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 Pagesapps/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
- The JS-box-to-name morph from the old site survived — rebuilt with modern CSS
- The typewriter intro became an AI-style streaming tagline, pulsing cursor included
- 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.