Earlier this month I shipped PayBrackets, a free calculator that tells Americans what they actually keep from their paycheck after federal tax, state tax, and Social Security take their cut. It covers all 50 states plus D.C., it has no database, no backend, no APIs, and my total running cost is the domain.
I want to walk through how it's built, because the interesting part isn't the code. It's how much you can get out of very little code if the data underneath is right.
Why a tax calculator, of all things
Every month, millions of people type things like "75000 after taxes texas" or "25 an hour is how much a year" into Google. I looked at what they find. Mostly it's ten-year-old calculators buried under popups, or freshly generated AI pages where the numbers are confidently wrong.
That gap felt workable for one person. Salaries and taxes are pure math. The rules are public. Nothing about it needs a server, an account system, or content writers. It needs someone to sit down, get the rules right once, and present them clearly.
So the whole plan was: encode the 2026 tax rules properly, build one calculation engine, and let that engine generate every page.
The unglamorous part was the whole ballgame
There's no tax API behind the site. The source of truth is a set of TypeScript files I wrote by hand, encoding the 2026 federal brackets from the IRS, the Social Security wage base from the SSA, and every state's brackets, deductions, exemptions, and phaseouts from Tax Foundation data. It looks like this:
{
name: "California",
slug: "california",
kind: "graduated",
topRate: 0.133,
brackets: {
single: [
{ rate: 0.01, threshold: 0 },
{ rate: 0.02, threshold: 11_079 },
// ...8 more brackets up to 13.3% at $1M
],
},
standardDeduction: { single: 5_540, married: 11_080 },
payrollTaxes: [{ name: "CA SDI", rate: 0.013 }], // uncapped since 2024
}
Doing this for 51 jurisdictions took me a full day, and it was the most valuable day of the project. States are genuinely weird. Maryland's counties add their own income tax on top of the state's. California's disability insurance tax lost its wage cap in 2024, so it applies to every dollar. Connecticut quietly claws back the benefit of its lower brackets once you earn enough. Nine states don't tax wages at all.
If I had modeled states as "one tax rate" like most quick calculators do, every single page would be wrong in a different way. And where I chose not to model something, like those Maryland county rates, the page says so in a visible note instead of pretending.
One engine, checked against reality
The heart of the site is embarrassingly small. Progressive taxes are just a walk over brackets:
export function marginalTax(taxable: number, brackets: Bracket[]): number {
let tax = 0;
for (let i = 0; i < brackets.length; i++) {
const { rate, threshold } = brackets[i];
if (taxable <= threshold) break;
const ceiling = i + 1 < brackets.length ? brackets[i + 1].threshold : Infinity;
tax += rate * (Math.min(taxable, ceiling) - threshold);
}
return tax;
}
Around that sits the composition: federal income tax after the standard deduction, Social Security up to the wage cap, Medicare plus the surtax on high earners, optional 401(k) deferrals, then the state layer with all its exceptions.
Before launch I wrote a small check script with hand-verified salaries. It runs the engine against numbers I worked out independently and fails loudly if anything drifts. A typo in a bracket threshold is invisible in a code review. In a paycheck for a specific salary, it screams.
163 pages from one route
The site is Next.js, fully static. All the calculator pages hang off a single dynamic route, and the slugs are literally the questions people search:
export function allProgrammaticSlugs(): string[] {
return [
...STATES.map((s) => `${s.slug}-paycheck-calculator`), // 51 pages
...HOURLY_RATES.map((r) => `${r}-an-hour-is-how-much-a-year`), // 61 pages
...SALARY_AMOUNTS.map((a) => `${a}-after-taxes`), // 35 pages
];
}
At build time, each page computes its own numbers. The "$50,000 after taxes" page shows the exact take-home in all 51 jurisdictions. The Texas page shows what no state income tax is actually worth against California at the same salary. No two pages share their content, which is the difference between programmatic pages that help people and the thin templated stuff Google buries.
The build produces 163 static pages in about half a minute, and the interactive calculator runs the same engine in the browser. Your salary never leaves the page, which was important to me. Nobody should upload their income to a stranger's server to learn what they already earn.
The readers that aren't people
A growing share of these questions never reach Google. People ask ChatGPT or Perplexity instead. So the site treats AI crawlers as an audience of their own.
Every page opens with the question stated plainly and a two-sentence answer with real numbers, before any explanation. There's FAQ markup throughout, a methodology page naming every data source, and a robots.txt that explicitly welcomes the OpenAI, Anthropic, and Perplexity crawlers rather than blocking them.
The bet is simple. Assistants quote pages that are structured like clean answers with checkable numbers. If an assistant answers "what's $70k after taxes in Florida" by citing my site, that citation is the new referral traffic.
The launch video is also code
One more thing that amused me. I wanted a proper product video for the launch, the smooth animated kind startups pay studios for. I don't own After Effects, so I built the video in Remotion instead. Every scene is a React component, the dollar figures in the animation come from the same tax engine as the site, and the final MP4 renders from the command line.
There's something satisfying about a project where even the marketing assets compile.
Where it stands
The site has been live for a few weeks. It's indexing, impressions are climbing, and the first ad review is in progress. I deliberately have no revenue story to tell yet, and I'd rather say that than inflate it. Once there are real numbers, good or bad, I'll write the follow-up.
The site is paybrackets.com if you want to poke at it. Happy to go deeper on the tax data modeling, the static generation, or the video in the comments.
Top comments (0)