← wardtechsystems.com
Ward Tech Systems — Writing

My resume is a repo: a single HTML file that also builds its own PDF

Why one self-contained HTML file with print CSS beats a static site generator for a resume, and how a Puppeteer script generates a byte-matching PDF from the same source.

My resume is one HTML file. Not a static site generator project with a resume template bolted on — one .html file with inline CSS, no build step required to view it, and a small Puppeteer script that turns that exact file into a PDF. The repo is public: github.com/ward-tech-systems/resume-v2. Steal it.

Why not a static site generator

A resume doesn't need routing, templating, content collections, or a plugin ecosystem. It needs to render correctly in a browser and print correctly on paper, and it needs to not break. Every layer you add between "the content" and "the rendered page" is a place for the web version and the PDF version to drift apart — a font that resolves differently, a build step that only one output path goes through, a template change that updates the site but not the export. A single self-contained file collapses that entire class of bug: there's exactly one source of truth, and both outputs read from it.

Fitting exactly one page with print CSS

The trick is a @media print block paired with an explicit @page rule:

@page {
  size: letter;
  margin: /* tight, tuned by hand */;
}

@media print {
  /* tighten line-height, font-size, and margins here
     until the content lands on exactly one page */
}

There's no formula that gets you to exactly one page — it's iterative. You set @page { size: letter } so the browser's print target matches a real sheet of paper, then you tune font size and line-height down in small increments, checking the print preview each time, until the last line of content sits just above the page break instead of spilling a lone paragraph onto a second page. The @media print block only applies when printing or exporting to PDF, so you can keep the on-screen version slightly more spacious without affecting the printed layout at all.

The PDF is generated from the same source

The Puppeteer script loads the same HTML file in headless Chromium and calls page.pdf() on it — the exact same DOM, the exact same CSS, the exact same @media print rules the browser would apply if you hit Ctrl+P yourself. That's the whole trick: the PDF isn't a separate artifact someone remembered to update, it's a deterministic export of the one file that exists. Change the HTML, regenerate the PDF, and the two can never quietly diverge — there's no second copy to forget about.

Deploy

The HTML is a static asset on Cloudflare Pages, served at wardtechsystems.com/resume. No server, no build pipeline beyond running the Puppeteer export when the content changes, no CMS. It's a file on a CDN.

Steal it

The repo is public and linked from my LinkedIn: github.com/ward-tech-systems/resume-v2. If you're tuning your own one-page print CSS, the @page + @media print approach above is the whole technique — there's no framework to install.