Tools that show their working, built to be read as much as used.
I am a development economist and a lawyer. This is where the experiments live: econometrics that runs in the page, poverty and inequality from grouped data, survey audits, women's and climate data pulled live, and legal calculators that cite the paragraph beside every rupee.
Hover over any card for what it does in plain words; open "how it's built" for the method and what it was checked against. One HTML file per tool, no dependencies, and nothing you type in leaves your browser.
Difference-in-differences, event studies, synthetic control and regression discontinuity: simulate a panel with a known effect, upload a CSV, or pull a live World Bank country panel and name the treated country.
World Bank API · cluster-robust SEs · Sun–Abraham · placebo inference · IK bandwidth
Open the tool →
In plain words. When a policy reaches some places and not others, the question is what would have happened without it. These four methods each build a counterfactual from the untreated units and measure the gap. The simulator plants a known effect so you can watch each estimator recover it, or fail when its assumption is violated.
DiD. Two-way fixed effects removed by alternating demeaning, OLS on the residualised variables by Cholesky, cluster-robust sandwich with the fixest small-sample convention, t on G−1 degrees of freedom.
Event study. Binned relative-time indicators with k = −1 omitted and a pre-period Wald test; the Sun–Abraham (2021) option averages cohort × relative-time coefficients with cohort-share weights and delta-method standard errors.
Synthetic control. Simplex weights by accelerated projected gradient with the exact projection of Duchi et al. (2008); placebo-in-space RMSPE ratios; an over-fitting warning when donors outnumber pre-periods.
Regression discontinuity. Local linear fits with a triangular kernel and HC1 errors, the Imbens–Kalyanaraman (2012) plug-in bandwidth, a bandwidth-sensitivity band, placebo cutoffs and a McCrary density test.
Verified: TWFE coefficient and SE match an explicit-dummies regression written separately in Python to six and four decimals; the RD simulator's interval covers the planted jump.
What POVCAL did with grouped data: Lorenz curves fitted to decile shares pulled live from the World Bank's Poverty and Inequality Platform, then Gini, Theil, Atkinson, Palma and FGT poverty at any line, the Datt–Ravallion decomposition and a growth incidence curve.
PIP API · GQ and Beta Lorenz curves · Shapley decomposition
Open the tool →
In plain words. Published inequality data usually comes as ten numbers, the share of income going to each tenth of the population. From those ten numbers and the average, this page reconstructs the whole distribution and reads off how many people fall below any poverty line, how unequal the country is, and whether growth between two surveys reached the poor. One click compares its answers with the World Bank's own.
Lorenz curves after Datt (1998): General Quadratic and Beta forms fitted by OLS to the cumulative decile points, validity checked on a 2,000-point grid and against the theoretical conditions; the valid curve with the smaller squared error wins.
Measures from the fitted quantile function y(p) = μ·L′(p) on a 4,000-point grid: Gini, Theil T, mean log deviation, Atkinson at three aversions, Palma, P90/P10, median; headcount by bisection, FGT1 and FGT2 by integration, Watts.
Change over time: Datt–Ravallion growth and redistribution with its residual, the Shapley version without one, and the Ravallion–Chen growth incidence curve.
Verified: on India 2022 the page gives Gini 0.256 and a $3.00 headcount of 5.1% against PIP's microdata 0.255 and 5.3%; the GQ results match Datt's closed forms to four decimals.
Oaxaca–Blinder decomposition of a wage gap on your own microdata: how much is education, experience, sector and location, and how much is the same characteristics being paid differently. Four reference-coefficient choices, three-fold form, bootstrap standard errors.
HC1 regressions · Jann (2008) pooled reference · bootstrap
Open the tool →
In plain words. Women earn less than men in every labour force survey India has run. This page splits the gap into the part that comes from differences in what women and men bring to the market and the part that comes from how the market pays them for it, and shows how much the answer depends on choices that are usually hidden.
Two-fold: (X̄A − X̄B)′β* + [X̄A′(βA − β*) + X̄B′(β* − βB)], with β* from the pooled regression with a group dummy (Jann 2008), the pooled regression without it (Neumark 1988), or either group.
Three-fold: endowments, coefficients and interaction. Detailed contributions per variable, with the Oaxaca–Ransom warning that dummy-variable rows depend on the base category.
Bootstrap standard errors resample workers and rerun both regressions and the decomposition each time; text columns are expanded to dummies against their most common category.
Verified: totals reproduced exactly by an independent plain-Python implementation on the same simulated sample.
02
Women & climate
The evidence that decides women's working lives, pulled live
Two things I work on most, wired to public data that updates on its own.
Women's health, work, assets, agency and safety across India's states and the five NFHS rounds, pulled live from the DHS Program API: state rankings with change since the previous round, and who is behind by wealth, residence, education and age.
In plain words. Pick anaemia, bank accounts, spousal violence, child marriage or any of twenty indicators and see every state's number, how far it moved since the last survey, and whether the poorest or least educated women are the ones still behind. Nothing is typed in by hand: every figure comes from the survey's own API with its sample size.
Pulls api.dhsprogram.com/rest/dhs/data for India, all rounds, all breakdowns, and resolves NFHS-5's nested regions and renamed states before matching across rounds.
The API carries sample sizes but not NFHS's published confidence intervals, so the page draws Wilson intervals on the unweighted n inflated by a design effect the reader sets, and labels them approximate.
Says when a module has no all-India total in the API (domestic violence) rather than inventing one.
Verified: anaemia among women renders 57.0% for NFHS-5 and 53.1% for NFHS-4, matching the published fact sheets.
Hour-by-hour heat stress for outdoor workers from live weather: WBGT for any place in India this week, the occupational work–rest limits by workload, safe working hours per day, wages lost, and how the count of dangerous-heat days has changed since 1991.
In plain words. Heat takes hours and wages from outdoor workers long before it puts anyone in a clinic. The people who work through an Indian summer, on farms, at kilns, on construction sites and on public-works schemes where women are most of the workforce, lose hours and wages as the air gets hotter and wetter. This page says which hours are safe to work this week, what the lost hours cost, and whether the summers are getting worse where you are.
WBGT in the sun from the Australian Bureau of Meteorology approximation (0.567·T + 0.393·e + 3.94); in shade and at night from Stull's natural wet-bulb, 0.7·Tw + 0.3·T.
Each hour gets the largest work allocation the ACGIH threshold limit values (acclimatised) or action limits (unacclimatised) permit for the chosen workload; hours lost are summed over the workday and priced at the wage you enter.
Thirty-five years of daily maxima and mean humidity from the ERA5-based archive give March–June counts of days over the continuous-work and almost-no-work limits, with a least-squares trend and its 95% interval.
Verified: 35 °C at 50% humidity gives WBGT 34.8 °C, matching the Bureau of Meteorology's tables; the allocation function returns the ACGIH table's values.
03
Field & appraisal
What a monitoring and evaluation team needs before, during and after
Planning a trial, checking the data that comes back, and putting a number on whether it was worth it.
Power and minimum detectable effect for individual and cluster designs, with intra-cluster correlation, covariate adjustment, attrition, take-up and multiple outcomes; then a seeded, stratified randomiser for a baseline CSV with a balance table and a randomisation record.
Bloom / Duflo–Glennerster–Kremer formulas · permuted blocks · Welch and joint F balance tests
Open the tool →
In plain words. Before a trial starts, two questions: how small an effect this sample could detect once villages cluster, some people drop out and not everyone takes the programme up; and who gets treatment. The page answers the first with curves you can move, and does the second with a draw that is stratified, reproducible from a seed, and documented for the pre-analysis plan.
MDE = (t1−α/2 + t1−β)·√[1/(P(1−P))]·√[σ²(1−R²)·(1+(m−1)ρ)/N], t quantiles from the regularised incomplete beta function; required sample by bisection.
Randomisation within strata by permuted blocks with a seeded generator, allocation remainders carried across strata so small strata still add up to the target split, cluster-level draws supported.
Balance table with Welch p-values and a joint F-test; a randomisation record with the seed, algorithm and a SHA-256 digest of the input file.
Verified: MDE 0.177 for N = 1,000 matches the closed form; 18/18 cluster splits and 40/30/30 three-arm splits come out exact.
The checks a monitoring team runs before anyone estimates anything: duplicate and near-duplicate interviews, Benford's law, age heaping, straightlining, interview length and timing, missingness, and an enumerator profile that says who to call back.
Nigrini MAD · Whipple and Myers · Welch z-scores · Markdown and CSV export
Open the tool →
In plain words. Field surveys go wrong in predictable ways: an interviewer copies yesterday's form under a new number, invents incomes, rounds every age to a five, answers a whole block with the same tick, or finishes a forty-minute interview in eight. Drop in the CSV and the page finds each pattern, names the enumerator, and writes the call-back list.
Exact duplicates by hashing every column except ID and timestamps; near-duplicates by pairwise comparison within an enumerator at 90% identical fields.
Benford judged by Nigrini's mean-absolute-deviation cut-offs, per-enumerator by χ² p-value because MAD is unreliable at small n; Whipple's index on the UN scale and Myers' blended index; straightlining against a chance benchmark.
Every metric z-scored across enumerators; two flags puts a name on the list. Nothing is uploaded anywhere.
Verified: the seeded demo plants six problems across five enumerators and the audit recovers all six, attributed to the right people.
Net present value, benefit–cost ratio, IRR, payback and cost per outcome for a programme's cost, benefit and outcome streams, with Monte Carlo on every input and a tornado chart of which assumptions drive the answer.
Triangular draws · bisection IRR · one-at-a-time tornado
Open the tool →
In plain words. Every donor asks whether a programme was worth it; almost nobody shows how sure they are. Enter what it costs, what it returns and how confident you are of each, and the page gives the usual numbers plus the probability the programme pays off and the two or three assumptions on which that hangs.
PV by year with year 0 undiscounted; IRR by bisection with a warning when net flows change sign more than once; cost per outcome shown with outcomes undiscounted and discounted.
Monte Carlo draws each stream from a triangular distribution on its range and the discount rate uniformly; the tornado sets each input to its low and high with everything else fixed.
Streams are independent by design, and the page says what that leaves out.
Verified: PV, NPV, BCR, IRR and cost per outcome on the illustrative example reproduced to the cent in an independent Python calculation.
04
Law & economics
Where a court or a statute has turned a valuation into a schedule
A schedule can be coded, and the code can cite the paragraph. Where the law is unsettled, the page says so and offers both readings.
Fatal-accident awards under the Motor Vehicles Act, step by step with the authority for each line: the Sarla Verma multiplier, Pranay Sethi future prospects and conventional heads with their 10% triennial enhancement, consortium per dependant, and interest.
In plain words. When someone dies in a road accident, tribunals value the income the family has lost using rules the Supreme Court has fixed. Enter the age, income and family, and the page produces the award the way a tribunal would write it, with the case and paragraph next to every figure.
Sarla Verma paras 30–32 and 42 (deductions, multiplier table); Pranay Sethi para 61 (future prospects by employment and age, conventional heads, 10% every three years from 31 October 2017); consortium to each dependant per Magma (2018), Somwati (2020) and Sameem Begum (2026), with the contrary 2023 line offered too.
Enhancement computed as 1.1⌊months/36⌋, which reproduces the ₹16,500 / ₹44,000 and ₹18,150 / ₹48,400 figures the courts have applied since.
Verified: reproduces a published worked example (₹8,64,864 loss of dependency) and the ₹48,400 consortium applied by the Supreme Court in August 2026.
The RFCTLARR Act 2013 formula line by line: section 26 market value, the First Schedule multiplication factor, section 29 assets, 100% solatium, the 12% additional amount, and every Second Schedule rehabilitation entitlement, with a comparison to the 1894 Act.
sections 26, 29, 30 · First and Second Schedules · annuity present value
Open the tool →
In plain words. When the state takes land, the 2013 Act says exactly how the price is built: the best of three market benchmarks, doubled or less depending on how rural the land is, plus what stands on it, plus the same again as solatium, plus 12% a year for the wait, and then a separate list of what each displaced family is owed. Enter the land and the family; the page does the sum and names the section beside every line.
Market value as the higher of the circle rate, the average of the top 50% of sale deeds and any consented amount (section 26); the state's factor for rural land; assets under section 29; solatium and the 12% addition under section 30.
Second Schedule items 1 to 10 with the Act's minimums; the annuity option valued as a present value on a discount rate and CPI indexation the reader sets, next to its nominal total.
The unsettled base for the 12% addition (bare market value or multiplied value) is left to a selector, so the reader chooses rather than the page.
Verified: every First Schedule line reproduced by hand on the default inputs; Second Schedule amounts checked against the schedule text.
Translates Hindi Supreme Court and High Court petitions into formal legal English, so yaachikaakarta becomes "Petitioner" and anuchhed becomes "Article", and the output reads like it was drafted in English.
Sarvam AI · Llama 3.3 70B via Groq · Netlify Functions
Open the tool →
In plain words. Paste the Hindi text of a petition and get back English that a lawyer would recognise as a petition, with the right terms of art, rather than a literal translation.
Text is chunked and sent to sarvam-translate:v1 in formal mode, then revised by Llama 3.3 70B on Groq with a prompt that fixes legal terminology.
Keys stay server-side in a Netlify Function; the browser only talks to that function. Stage: prototype, awaiting a blind comparison against a human legal translator.
Headless-browser command line for view-only Google Drive PDFs: scrolls the viewer, captures each rendered page, and reassembles them into a fresh PDF. No Drive authentication needed.
Node · Playwright · jsPDF
Source on GitHub →
In plain words. Some documents shared on Google Drive can be read but not downloaded. This script reads them the way you would, page by page, and saves what it sees as a normal PDF you can keep and search.
Playwright drives Chromium through the Drive viewer until every page canvas has rendered, exports each as an image and stitches them with jsPDF at the original dimensions. Runs locally; nothing is uploaded.
A candidate's running account under section 77 of the Representation of the People Act: entries by head against the Rule 90 ceiling, burn rate and a projection to counting day, the section 78 lodging deadline, and flags for cash above the threshold, spending outside the period and expenditure by others.
In plain words. Every candidate must keep a day-by-day account of what the campaign spends, and the total has a legal cap. Type in each bill as it comes; the page keeps the total, shows how fast the money is going, says where the campaign will land on counting day at that pace, and tells you the last day to file the account. Nothing leaves your browser.
Ceiling pre-filled by house and state from the Rule 90 amendment of 6 January 2022 (₹95 / ₹75 lakh; ₹40 / ₹28 lakh), editable because the state banding is reproduced from the notification pattern rather than read from each notification.
Accounting period from nomination to declaration, both inclusive; burn rate over elapsed accounting days; the projection is linear; the step chart marks the poll day. A hand-written CSV parser handles quoted commas so descriptions round-trip.
Verified: the example ledger's fourteen entries sum to ₹21,01,000 by hand; a ₹12,000 cash entry raises the flag.
Beneficiaries × uptake × unit cost for each promise, with low and high ranges, against a state's revenue receipts, expenditure, GSDP and fiscal deficit: a multi-year path against the 3% norm, a Monte Carlo band and a tornado of which assumption matters.
triangular Monte Carlo · one-at-a-time tornado · RBI State Finances inputs
Open the tool →
In plain words. A party promises free electricity, or a monthly transfer to women, or a loan waiver. Each promise has a cost: the number of people covered, times the share who will claim, times the amount each gets. This page adds those costs up and sets the sum beside the state's own budget, so you can see whether the promises cost a tenth of the revenue or half of it, and what the deficit would be if they were simply borrowed.
Each promise carries low, likely and high for beneficiaries, uptake and unit cost; recurring promises grow at a unit-cost rate, one-off promises are spread over their years. Aggregates are entered by hand from the state budget or the RBI study; the default is an illustrative state, labelled as such.
4,000 draws from independent triangular distributions give the 5th to 95th percentile of the first-year bill and the share of draws that breach the deficit norm; the tornado moves one input at a time from low to high and ranks by swing.
Verified: the six example promises reproduce by hand (₹31,500 crore, 15.7% of revenue receipts, deficit 3.0% to 5.0% of GSDP).
Interest the way Indian statutes prescribe it, with the section quoted: MSMED Act s.16 (three times the bank rate, monthly rests), CPC s.34 on decrees, Arbitration Act s.31(7) on awards, the Negotiable Instruments Act limits on a bounced cheque, and plain simple or compound with the schedule.
In plain words. When a buyer pays a small supplier late, or a court decrees a sum, or an arbitrator awards one, the law fixes the interest, and the rules differ. Pick the situation, enter the amount and the dates, and the page computes the interest month by month with the section it is applying printed beside the working.
MSMED: the 45-day cap on the agreed period, interest from the day after, compound with monthly rests at 3 × the RBI bank rate the reader enters. CPC: three simple-interest periods with the 6% post-decree ceiling and the commercial-transaction proviso. Arbitration: post-award at current rate + 2 on the sum plus pre-award interest (Hyder Consulting, 2015), with the principal-only alternative shown.
Every compounding schedule prints each period's opening balance, interest and closing balance; stub periods are simple; day count actual over 365.
Verified: all five default cases reproduce in Python to the rupee (MSMED ₹86,430; decree ₹2,65,315; award ₹8,74,473).
A year of hourly PM2.5, PM10 and NO₂ for any Indian city or coordinate, live from Open-Meteo's CAMS archive, reduced to what the standards ask: annual means against WHO 2021 and NAAQS 2009, days over each 24-hour limit, month by month, and the cigarette equivalent.
Open-Meteo air quality API (CAMS) · WHO 2021 · NAAQS 2009 · Berkeley Earth rule
Open the tool →
In plain words. Pick a city. The page fetches every hour of the past year's fine-particle pollution, works out the daily averages, counts how many days broke the Indian limit and the WHO guideline, and says how many cigarettes a year of that air is comparable to. The figures are model estimates rather than readings from a roadside monitor, and the page says so.
8,760 hourly rows fetched in one request with an IST timezone; daily means of 24 hourly values; a day breaches a 24-hour limit when its mean exceeds it; the cigarette equivalent is the sum of daily PM2.5 divided by 22.
Hand-rolled SVG for the daily line and the monthly bars with hover; tolerant of a series the API does not return.
Verified: a recorded Delhi year reproduces in Python (365 days, 86.2 µg/m³ annual mean, 260 days over India's 24-hour limit, 1,431 cigarette equivalents).
A representation, memorandum or petition drafted in the accepted form: addressee, subject, facts, grounds, prayer, annexures and a signatory sheet, in four variants from a municipal office to the Lok Sabha, with print, Word and Markdown export and a link that carries the draft to co-signatories.
Article 350 · House petition rules · .doc export without a library · draft encoded in the URL
Open the tool →
In plain words. Officials read the shape of a petition before they read its words. Fill in who it goes to, what it is about, what happened, why they should act and what you want, add the names, and the page lays it out the way a clerk expects to see it, ready to print or send as a Word file.
Four templates share one form model; facts and grounds number continuously, the prayer restarts, annexures are lettered. The Word export is an HTML document served with Word's MIME type, which Word and LibreOffice open with the layout intact, so no library is needed.
The shareable link packs the draft into the URL fragment as base64url JSON, so a co-signatory sees the same draft with no server. The draft is also kept in local storage and can be exported as JSON.
Verified: the example renders every section and the signatory table headless; the House form switches opening, closing and countersignature line.
Drop a PDF and get a page-turning book with a hard cover and facing spreads that flip under the mouse or a finger, then download it as one HTML file with the pages and the page-turn engine inside. The file works offline, on a phone, and on any web host. The PDF never leaves the browser.
PDF.js rendering in a Web Worker · StPageFlip · self-contained export with JPEG pages inlined
Open the tool →
In plain words. The flipbook services charge a subscription, watermark the result and keep your file on their servers. This does the same thing in the browser: an annual report, a magazine or a child's picture book becomes a book you can leaf through, and the file you download needs nothing else to open.
Each PDF page is drawn to a canvas at the width you choose (1000 to 2400px) and stored as a JPEG at the quality you set; title and author are read from the PDF's own metadata. The book is a StPageFlip instance with hard cover, facing spreads, single pages on narrow screens, keyboard and thumbnail navigation.
Export fetches the page-flip library text and writes it into the file together with the page images as data URLs, so the result is one HTML document with no external requests; a 20-page A4 report at 1400px is about 2 MB.
Verified: a seven-page PDF generated headless renders in full, the title is read from its metadata, buttons, keys and thumbnails turn pages, and the exported file opens from disk with no network request and turns pages.
06
Personal
Built for the two children in the house, and the shelves they read from
A Class 1 CBSE worksheet generator with a structured course beside it: English phonics and reading, Hindi, Maths and EVS. Fresh questions every time, on-screen marking with confetti, printable sheets with answer keys, and eight decodable readers with read-along audio.
In plain words. A six-year-old's practice app. It never shows the same worksheet twice, it checks answers on screen, and its course introduces sounds before letters in the order that makes readable words fastest. Every lesson has a note for the grown-up on how to teach the rule.
36 activity types generated from rules, seeded per sheet so a printed answer key matches its worksheet; 161 lessons across four paths, each opening the next at 80%.
Decodable readers use only the sounds taught so far, with word-timed audio; installable PWA with a small service worker, progress stored on the device.
A CBSE Class 8 revision app: notes for every chapter of science, maths, social science, English, Hindi, Sanskrit and computing, hundreds of questions with instant marking and explanations, printable worksheets, mock papers in the CBSE pattern, and a mistakes book.
In plain words. A thirteen-year-old's exam companion. Pick a chapter, read the notes, answer questions and see why an answer is right or wrong, then let the mistakes book bring back what you got wrong until the answers stick.
All content in one HTML file as structured data, a doodle per chapter as inline SVG; one marking engine across question types; spaced repetition on the mistakes book; content checked against the NCERT texts.
Catalogue the books in a house: add by ISBN or title with authors, year, subjects and covers from Open Library, or by hand, list or CSV; shelve them, track who is reading what and who borrowed which book, and see the shelves as a subject map. Kept in the browser only.
Open Library books and search APIs · Goodreads CSV import · force-directed subject map in plain SVG
Open the tool →
In plain words. A house with a few hundred books has a library and no catalogue. Type an ISBN and the book appears with its cover; tell it which room it lives in and who has borrowed it; and look at the whole collection as a map of subjects rather than a list. The replacement for the family library that used to live on this page, without the family's data.
Records come from openlibrary.org's books and search endpoints (both send CORS headers); covers from covers.openlibrary.org. Duplicates are refused by ISBN or by title and first author. A hand-written CSV parser handles Goodreads' quoted ISBN cells.
The map is a seeded force layout (repulsion, spring on shared subjects, centring) run for 220 iterations in the page and drawn as static SVG with hover; subjects shared by more than forty books are ignored as uninformative.
Verified headless against recorded Open Library responses: ISBN lookup, title search, every view, filters and persistence.
07
Graduated
Everything that grew up and moved out
When something outgrows this page it gets a repository and a home of its own, and it stops being listed here. The index of those projects, with status labels, is openstacks.dev.
How these are made, and why this way
The argument this page makes is about method. Every tool can be read in full, and every result is checked against something outside the page.
One file, no buildEach tool is a single HTML file with its CSS and JavaScript inline, deployed as-is on push. There is no build step and nothing to install, so a tool from this page still opens in ten years and can be forked by copying one file. The two AI tools keep their keys in Netlify Functions so the browser never holds a secret.
Compute in the browserCholesky solves, alternating-projection demeaning, cluster-robust sandwiches, simplex projection, Lorenz-curve fitting, incomplete beta functions, numerical integration and bisection are written in plain JavaScript in the page. Survey data, panels and microdata never leave the machine.
Live where it should beFour public APIs, and only four: the World Bank indicators and Poverty and Inequality Platform, the DHS Program, and Open-Meteo. The site's Content-Security-Policy allows nothing else, so a page cannot start calling a new host without a change to that policy.
Checked against something outsideTWFE against an explicit-dummies regression in Python; GQ poverty measures against Datt's closed forms and PIP's microdata; the wage-gap decomposition and the cost-benefit sums against independent implementations; Whipple, Myers and Benford against limiting cases; the legal calculators against published worked examples and the schedule text.
Tested in a real browserEvery page is driven in headless Chromium before it is pushed: estimators run on simulated and recorded data, the console must be empty, and screenshots are checked at desktop and phone widths. Charts are hand-drawn SVG with hover tooltips and one axis.
Written to be readEvery tool carries a method note beside its output, its README states what was verified and how, and where a method or a judgment is unsettled the page says so. Source: github.com/Varnasr/Experiments, MIT.