Skip to main content
← All projects

ayomideodewale.com

This site, and the resume generator that keeps it honest.

Visit ayomideodewale.com View source

ayomideodewale.com screenshot
5
Resume variants
1 dataset
Generated from
0
Build dependencies added
2023
Since
01

The problem

A portfolio site, a set of resume PDFs and a LinkedIn profile are three copies of the same facts, and copies drift. Mine had: the site was missing the current employer, one resume said five years of experience while another said six, job titles disagreed across surfaces, and the PDF the site linked to was a stale export nobody had regenerated in a year.

Every one of those is the same failure. The facts were stored in the documents rather than anywhere a document could be generated from.

02

What I built

One typed dataset of roles, projects, education and certifications, and a `buildResume(variant)` function that composes a document from it. Five variants (fullstack, backend, frontend, mobile and cloud) select and reorder from the same records, and a variant may override the bullets for a role, but it can never introduce a second spelling of a fact.

That dataset renders into a print-styled Svelte route, and a script drives headless Chrome over it to produce five PDFs. The site’s own experience section is a projection over the same records, filtered by a per-role `site` flag, so the timeline on the homepage and the timeline in the PDF cannot disagree.

The site itself is SvelteKit 2 on Svelte 5 runes, Tailwind 4 in its CSS-first configuration, deployed to Vercel.

03

Decisions I'd defend

Dates are `YYYY-MM` strings, not `Date` objects. Lexicographic order equals chronological order, so sorting is free, and there is no timezone to get wrong. This is not hypothetical: `new Date('2026-01')` parses as UTC midnight and renders as December 2025 in any negative-offset locale, which would have shipped a wrong start date on every resume.

The resume route sets `prerender = true` and `csr = false`. Without client-side rendering the theme watcher never mounts, so a stale dark class cannot leak into a print, the particle background never paints, and SvelteKit omits a hydration payload that would otherwise serialise the whole document into the page a second time.

The print stylesheet specifies Arial rather than the system font stack. macOS San Francisco is not embeddable, so Chrome rasterises it into Type 3 fonts that some applicant tracking systems extract badly; Arial embeds as TrueType. The document is single-column for the same reason, since a CSS grid can make Chrome interleave columns in the PDF text stream and scramble extraction order.

No dependency was added for any of this. Screenshots and PDFs go through the Chrome DevTools Protocol over Node’s built-in WebSocket, and the four non-canonical resume variants render from a dev-only route guarded by `if (!dev) error(404)`, so they exist as PDFs without ever being publicly reachable as pages.

04

What went wrong

Two things, both instructive. Chrome’s `--print-to-pdf` has no error channel: a broken page prints blank and reports success, so the script verifies every output starts with the `%PDF` magic bytes and exceeds a size floor, and I still open each one. And launching the installed Chrome while a normal Chrome is running silently hands the URL to the existing instance and ignores the flag entirely, which is why the script uses `chrome-headless-shell` with a fresh profile directory every run.

Separately, writing the case studies on this site meant reading the source of the products they describe, and three claims did not survive that. A Terraform module I had described as provisioning production infrastructure had, by its own README, never been applied. Traction numbers quoted on a marketing site were not substantiated anywhere in the repository. A project I had called solo had two collaborators in the git history. All three were corrected rather than softened.

05

Where it is now

Live, open source, and the single source of truth for every surface it feeds. Adding a role means editing one record; the homepage timeline, five PDFs and the sitemap follow from it.