Skip to content
All posts

Rebuilding my portfolio with Astro, Keystatic and Bun

Why I rebuilt my hand-crafted 2021 portfolio as a statically generated Astro site with a local Keystatic CMS, view transitions, and an AI-style streaming hero.

Astro Keystatic meta

My first portfolio was hand-written HTML, CSS and JavaScript — every animation keyframe typed out by hand, Materialize CSS holding the layout together, and a service worker bolted on at the end. It served me well for five years. But it was time.

What the new stack looks like

The new site is a bun monorepo with two apps:

  • apps/web — an Astro site, statically generated, deployed on Cloudflare Pages
  • apps/cms — a local Keystatic studio that writes MDX straight into the web app’s content folder

Content lives in MDX files with frontmatter, so the whole site builds to plain HTML — every route gets its own index.html at build time:

const blog = defineCollection({
  loader: glob({
    pattern: '**/index.mdx',
    base: './src/content/blog',
  }),
  schema: (ctx) => z.object(articleFields(ctx)),
});

The fun parts

  1. The JS-box-to-name morph from the old site survived — rebuilt with modern CSS
  2. The typewriter intro became an AI-style streaming tagline, pulsing cursor included
  3. Native view transitions make every navigation feel like one continuous surface

More on each of those soon. This post itself was written in the new CMS — and published with a single button that commits and pushes the markdown to git.