jasonmatthew.dev
This site. A personal portfolio and blog built with Astro 5, Tailwind CSS v4, and MDX in a Turborepo monorepo. Deployed on Cloudflare Pages.
Why Build Your Own
I’ve had portfolio sites on WordPress, Jekyll, Gatsby, and Next.js over the years. Each one taught me something about the tools of its era. This version is Astro — and it’s the first time the framework has felt like it gets out of the way entirely.
There’s also a meta reason. I wrote a blog post about side projects as a management tool — and this site is the proof. Every tool decision I made here (Tailwind v4, Turborepo, Cloudflare Pages) is something my teams use at work. Staying hands-on keeps me honest.
Technical Decisions
Monorepo with Turborepo — content lives in packages/content/ as MDX with Zod-validated frontmatter schemas. The Astro site in apps/web/ consumes it. This separation means content can be edited without touching the app, and the schemas catch broken frontmatter at build time.
Tailwind CSS v4 — the new CSS-first configuration with @theme inline and @layer base. Design tokens are CSS custom properties that swap between light and dark mode via a .dark class, which means Tailwind utilities can override base styles cleanly.
Accessibility from the start — ESLint with eslint-plugin-astro and jsx-a11y-recommended rules, focus-visible outlines on all interactive elements, skip-to-content link, ARIA attributes on the mobile menu, and prefers-color-scheme support in the SVG favicon.
Asset generation with Playwright — the OG image, favicon, and apple-touch-icon are generated programmatically from a script that renders HTML templates and screenshots them. No design tools required, fully reproducible.
Pre-commit Quality
Husky + lint-staged runs Prettier and ESLint a11y checks on every commit. If it doesn’t pass accessibility linting, it doesn’t get committed.