← all posts

Why this site ships zero-JS-ish: SvelteKit + mdsvex

20 September 2025 · 4 min read

  • Sveltekit
  • Mdsvex
  • Performance

The stack

  • SvelteKit 2 with the static adapter (adapter-static) — every route prerenders to plain files at build time
  • mdsvex — Markdown pages become real Svelte components at build time, so blog posts can include interactive islands when needed, and none otherwise
  • Tailwind v4, CSS-first config, no runtime cost
  • Zero analytics, zero client state, one component tree

Why this matters

A personal site’s job is: load fast, be readable, get out of the way. The typical React-portfolio-of-the-week ships ~600 KB of JS for a hero paragraph. This entire site’s client bundle is a rounding error by comparison, which matters more on hotel wifi than in a benchmark lab.

mdsvex is the secret sauce

Posts are plain .md files with frontmatter:

---
title: 'Hello world'
date: '2025-09-20'
---

Hello.

import.meta.glob + mdsvex turns them into typed, metadata-carrying, preview-able modules at build time. Listings, RSS, sitemap, and JSON-LD structured data all read from the same module. No CMS, no backend, no build race-condition department.

Limitations

  • Multi-language routing and content-sets get verbose at scale — if your site is 5k posts, this stops being the best tool
  • Authenticated routes need a server; this site has none

Ship it anyway. Static works.