chornous.dev
All writing

From JAMstack to App Router

A practical migration lens for static sites that still need rich interaction and typed content.

VCVolodymyr Chornous··2 min read
Abstract web development workspace

The older JAMstack pitch was simple: prebuild the pages, ship them close to users, and avoid unnecessary servers.

That idea is still strong. What changed is the shape of modern static sites. A portfolio, docs hub, or product marketing site can now include typed content, local search, feed generation, animated interaction, and route-level metadata without turning into a backend project.

Static does not mean inert

The important distinction is between runtime data and runtime interaction. A blog post does not need a server request to render. A search dialog, springy project card, or physics token field can still hydrate only where needed.

That is the useful App Router pattern for this site:

  • Server components render content and metadata.
  • Local MDX keeps writing editable.
  • Zod validates frontmatter before publishing.
  • Pagefind indexes exported HTML.
  • Client components own only the interaction layer.

Migration pressure points

The risky parts are rarely the pages themselves. They are the contracts between systems:

  • Does draft filtering match across blog, tags, RSS, sitemap, and search?
  • Do dynamic routes have deterministic static params?
  • Are images served from public paths instead of framework-specific asset pipelines?
  • Do animations respect reduced motion and avoid layout shift?

Answer those questions early and the migration becomes much less dramatic.

What I optimize for

I want static sites that are easy to publish, easy to inspect, and hard to accidentally break. The stack matters, but the contract matters more: typed content in, predictable pages out, and interaction isolated enough that the site remains fast when the visual layer gets ambitious.

VC

Written by

Volodymyr Chornous

Get in touch