Engineering · · 7 min read · Giovanni Liber

JavaScript frameworks compared: what the same app costs

CPU, page weight and cold starts for seven frameworks, measured on real deployments

Seven towers sorted from heavy to light, showing CPU milliseconds per 400-row page: Next.js 103, TanStack Start 36, React Router 26, Nuxt 26, SvelteKit 13, Hono 9, Astro 7

The short answer

Start with the lightest framework that does the job. For an API, a site or server-rendered pages, that’s Hono or Astro. Choose Next.js when you need something on the short list below.

We built one shop twice, in Next.js and in Hono, with the same pages and the same output. The catalog page used 129 ms of CPU in Next.js and 9 ms in Hono: 93% less. The browser downloaded 145 KB of JavaScript for the Next.js shop and none for the Hono shop.

We have a stake in this: Eurobase runs all seven frameworks, and every plan includes a monthly CPU budget for Workers. That’s why we measured on real deployments, and the method is at the end.

Decide in 30 seconds

Your appPick
A JSON API or a webhookHono
Server-rendered pages with little or no interactivityHono
A marketing site, a blog or docsAstro
Content pages with a few interactive partsAstro
An interactive app with little JavaScript in the browserSvelteKit
An interactive app, and your team writes VueNuxt
A React app with routes and data loadersReact Router
A React app with typed routes and server functionsTanStack Start
A large React app built on server components and Server ActionsNext.js
An app that depends on a library built for Next.jsNext.js

If your app already works in Next.js and fits your CPU budget, keep it.

One shop, built twice

The shop has 400 products, a header, navigation and a footer, a stylesheet, a catalog, product pages, a static About page and a JSON report on 2,000 orders. Data lives in memory, so there’s no database in these numbers. Every page renders on each request, except About.

Both versions returned the same <main> markup and the same JSON, apart from a timestamp. The Next.js shop uses server components, and we wrote no client components for it. The Hono shop uses its own JSX.

CPU per requestNext.jsHonoLess with Hono
Home, 12 products28.0 ms3.8 ms86%
Catalog, 400 products128.7 ms9.0 ms93%
Product page30.1 ms3.2 ms89%
Static About page17.9 ms0.04 ms99%
JSON report on 2,000 orders16.7 ms7.5 ms55%
Size and speedNext.jsHonoLess with Hono
Worker size, compressed1,059 KB23 KB98%
JavaScript on a first visit145 KB0 KB100%
Catalog first visit, all downloads176 KB11 KB94%
Catalog HTML, uncompressed283 KB82 KB71%
Catalog time to first byte, median168 ms77 ms54%
First request on a cold start, median1,800 ms975 ms46%
Next.js sends each page twice
The catalog HTML holds the products once as markup and again as data for React in the browser. That’s why it weighs 283 KB against 82 KB, with the same visible page.
A static Next.js page still runs your Worker
The About page is prerendered in both shops. Hono’s is a file served without running your Worker. In Next.js, a request runs the Worker and returns the cached page, which used 18 ms of CPU.
The JavaScript buys something
With 145 KB in the browser, the Next.js shop can move between pages without a full reload, and it’s ready for interactive components. The Hono shop loads a new page on each click.
Your own code shrinks the gap
The JSON report does the same sums in both shops and renders nothing. That’s where the gap is smallest: 55%. The more of a request is your own work, the less the framework matters.

How far your CPU budget goes

Workers plans include a monthly CPU budget for the whole workspace. Dividing each budget by the measured CPU of the catalog page gives the views it covers, if the catalog were your only page:

PlanCPU per monthNext.js viewsHono views
Free3,000 s23,000332,000
Starter30,000 s233,0003,329,000
Pro100,000 s776,00011,098,000

Calculated from unrounded CPU, then rounded down. Startup CPU doesn’t count, and neither do files served without running a Worker.

The Free plan also limits each request to 50 ms of CPU. A 129 ms page is over that limit, so each view draws on a 2 s reserve that refills at 50 ms per second. Once the reserve is empty, the request gets a 503. The same page in Hono stays inside the limit. Paid plans allow 30 s per request.

All seven frameworks

For this comparison we built a smaller app in each framework: a small dynamic page, a page listing 400 rows, a static page and a JSON report. It has no header or stylesheet, so its numbers are lower than the shop’s. Compare frameworks within this table, not with the shop.

FrameworkSmall page400 rowsJSONStatic pageJavaScript400-row HTML
Next.js26.0102.615.718.6141 KB237 KB
TanStack Start8.536.310.70115 KB146 KB
React Router8.526.311.50119 KB144 KB
Nuxt10.225.98.0075 KB138 KB
SvelteKit4.913.18.3037 KB144 KB
Hono2.99.27.300 KB71 KB
Astro5.57.07.300 KB71 KB

The first four number columns are CPU in ms per request. Static pages under 0.1 ms show as 0. JavaScript is the compressed download for the small page on a first visit, and 400-row HTML is uncompressed.

  • Hono and Astro send no JavaScript. Their 400-row HTML is about half the size of most others, and under a third of Next.js.
  • SvelteKit sends the least JavaScript of the five frameworks that send any.
  • Static pages use almost no CPU in every framework here except Next.js.
  • On JSON, six frameworks sit between 7 and 12 ms, because most of that time is the report itself.
  • A cold start took a median of 1.0 to 1.5 s in six frameworks, and 1.9 s in Next.js.

What you gain by switching

FromToSmall page CPU400-row CPUJavaScript
Next.jsHono89% less91% less100% less
Next.jsAstro79% less93% less100% less
Next.jsSvelteKit81% less87% less74% less
Next.jsNuxt61% less75% less47% less
Next.jsReact Router67% less74% less16% less
Next.jsTanStack Start67% less65% less18% less
React RouterAstro36% less73% less100% less
NuxtSvelteKit52% less50% less51% less
SvelteKitHono41% less30% less100% less

Calculated from unrounded CPU.

The size of a rewrite matters as much as the saving. React Router and TanStack Start keep your React components, so they’re the shortest move from Next.js, and CPU still drops by 65% to 74%. Hono, Astro and SvelteKit save more, and you rewrite your components.

When Next.js is worth its cost

Server and client components in one tree
Server components fetch data on the server, and client components add interactivity inside the same page. For a large React app, that model is the reason to pay.
Forms that call server code directly
Server Actions let a form run a server function with no API route to write.
Cached pages refreshed on demand
Incremental static regeneration, use cache and revalidateTag refresh a page when its data changes. On Eurobase, a small cached page still used 18 ms of CPU.
Libraries built for it
Some tools expect Next.js. Payload CMS, for one, installs inside a Next.js app.
A team and an app already on it
What your team already knows is worth something, and a rewrite has its own cost.

If none of these describes your app, you’re paying for features you don’t use. Image resizing isn’t a reason on Eurobase: on Workers, next/image serves each image at its original size.

What you give up with Hono

  • Routes and layouts by folder. You write routes in code and compose layouts yourself.
  • React. Hono’s JSX isn’t React, so React component libraries aren’t built for it.
  • Page changes without a reload. Each click loads a full page.
  • Interactivity out of the box. You add client components and their build yourself.
  • An image component and a data cache. You choose your own.
  • On Eurobase, setup with no config. Hono needs a Wrangler config.

When each framework fits

Hono
APIs, webhooks and server-rendered pages. The smallest Worker and no JavaScript in the browser unless you add it.
Astro
Sites made of content, with islands of interactivity where you need them. On Eurobase, images on server-rendered pages keep their original size, and Astro sessions don’t work.
SvelteKit
Interactive apps with routing built in, for 37 KB of JavaScript where the React frameworks here send 115 KB or more.
Nuxt
The full framework for Vue teams, with routing and server routes in one project.
React Router
React apps that want routes and loaders without server components.
TanStack Start
React apps that want typed routes and server functions. It used the most CPU on the 400-row page after Next.js, so check your longest lists.
Next.js
Large React apps that use what’s listed above. On Eurobase, Next.js responses are cached only when your app sends CDN-Cache-Control, and a Cache Components page renders on each request.

If a coding agent picks for you

This part is our experience, not a measurement: coding agents often reach for Next.js, even for a small site that would do the same job in a lighter framework. So name the framework in your prompt, and ask for Next.js only when your app needs what’s listed above.

How we measured

  • Each app ran as a Worker on Eurobase, deployed on 6 November 2026. Eurobase added the adapter during the build, except for Hono, which has its own Wrangler config.
  • CPU: 300 requests per page, one at a time from one client in Europe, after 20 warm-up requests. We read the project’s metered Workers CPU before and after, and subtracted what a warm instance adds while idle.
  • Time to first byte: taken on the same 300 requests, over a reused connection.
  • Downloads: a headless Chromium browser with an empty cache, counting compressed bytes.
  • Worker size: the compressed upload size of the shop, built locally with the same adapters.
  • Cold start: we waited 16.5 minutes, past the 15-minute idle stop, then opened a new connection, followed by three more. Medians use the first request of each run. That’s 5 samples per shop, 6 for the small Hono and Next.js apps, and 3 for the others.
FrameworkVersionSetup
Next.js16.4.3, React 19.3.0Server components, OpenNext adapter 1.20.9
TanStack Start1.169.4, React 19.3.1Server functions
React Router8.5.1, React 19.3.1Loaders
Nuxt4.6.3, Vue 3.5.44useFetch and a server route
SvelteKit3.1.1, Svelte 5.57.3Server load functions
Hono4.13.14hono/jsx
Astro7.4.4Server output

What these numbers don’t tell you:

  • They describe these frameworks on V8 isolates. Next.js runs here through its adapter, so it will behave differently on a Node.js server.
  • These are small apps with data in memory, and one client at a time. We didn’t test concurrent traffic.
  • These apps have no interactive parts, so Hono and Astro send no JavaScript. Yours may need some.
  • Two of 148 requests in the cold-start runs returned a 503, one on Nuxt and one on React Router. We left them out, so Nuxt has 2 cold-start samples.

Deploy your app in Europe

Sign up