All Posts
react · migration

Porting a Next.js Portfolio to TanStack Start

A field guide from the migration — what mapped one-to-one, what changed shape, and what disappeared entirely.

Moving from Next.js App Router to TanStack Start turned out to be mostly mechanical. Here's the mapping table I wish I had before starting.

Concept mapping

Next.jsTanStack Start
app/layout.tsx__root.tsx shellComponent
app/page.tsxroutes/index.tsx
Server Components fetching DBroute loaders + createServerFn
NEXT_PUBLIC_* env varsimport.meta.env.VITE_*
next/font/google@fontsource/* packages
next/imageplain <img> + CSS

Things that got simpler

Routing. File-based routing exists in both, but TanStack Router generates a fully typed tree. Links like <Link to="/blog/$slug" params={{ slug }}> are compile-checked.

Hash scrolling. The old site hand-rolled smooth scrolling between sections. TanStack Router has it built in:

createTanStackRouter({
  hashScrollIntoView: true,
})

Things that needed care

  • "use client" directives vanish — components render on both server and client by default
  • Canvas/rAF code must live inside effects (it already did)
  • useId() output contains colons — sanitize before using in url(#id) references for SVG clipPaths

Verdict

Same visual site, fewer abstractions, faster dev server under Bun. The main win isn't performance though — it's that the framework stays out of the way.

End of post