hatoo

Stars and mentions

Last 30 days, Oct 5 – Nov 3

GitHub stars68
mentions8
02468Oct 5Oct 19Nov 3
UTC days · repositories hatoo owns1 repositories

Package downloads

Cumulative recorded downloads

crates.io—
01234Oct 5Oct 19Nov 3No observations in this range
Oct 5crates.io: 0/3 packages observed

Across 3 known packages in repositories hatoo owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete.

Top repositories

hatoo’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside hatoo’s account where hatoo opened or reviewed pull requests in the past 365 days.

Who noticed hatoo

Everyone who starred or forked hatoo’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

8posts
Nov 40 posts
  1. DEV · · @2u841r · hatoo/oha

    axum vs actix-web vs Rocket on 1 CPU and 1 GB RAM > TL;DR: I wrote the same Todo API in axum, actix-web and Rocket, then load tested each one in Docker with 1 or 2 CPU cores and 1 GB of RAM. On one core, actix served about 67k requests per second, axum 47k and Rocket 34k. Each server idled at about 1 MB of RAM. I then re-ran it on two AWS spot instances in Mumbai, a c7i.xlarge for the server and a c7i.2xlarge for the load generator, and got the same ranking over a real network. Before any of that, review found a bug in my axum version that let one bad request take the whole server down, and two settings that would have made the benchmark unfair. Code and full results: 2u841r/actix-vs-axum-vs-rocket. Why Every "Rust web framework benchmark" I find runs on a 64-core machine and reports millions of requests per second. That tells me nothing. The servers I actually pay for have 1 or 2 vCPUs and 1 GB of RAM. I wanted to know how much each framework can handle on that. The API Five routes, identical in all three projects: | Method | Path | Does | | --- | --- | --- | | GET | /health | returns OK | | GET | /todos | lists all todos | | GET | /todos/{id} | one todo, or 404 | | POST | /todos | creates a todo | | DELETE | /todos/{id} | deletes, 204 | State is a Mutex<HashMap<u64, Todo>> plus an AtomicU64 for ids. Nothing clever, and the same in all three, so I compare the frameworks and not my data structures. The axum version is the shortest of the three: let app = Router::new() .route("/health", get(|| async { "OK" })) .route("/todos", get(list_todos).post(create_todo)) .route("/todos/{id}", get(get_todo).delete(delete_todo)) .with_state(state); The bug that killed the server My first axum get_todo looked like this: let todo = state.todos.lock().unwrap().get(&id).cloned().unwrap(); It compiles and passes clippy pedantic, and it works for every id that exists. Ask for one that doesn't and the last unwrap() panics. The panic alone wouldn't be fatal, since axum only drops that connection. The problem is when it panics. The MutexGuard from lock() is a temporary, and temporaries live until the end of the statement. So the panic happens while the lock is still held, which poisons the mutex. From then on, every lock().unwrap() in every handler panics too. One GET /todos/999 and the server is effectively dead. The fix is to return a 404 instead of panicking: async fn get_todo( State(state): State<Arc<AppState>>, Path(id): Path<u64>, ) -> Result<Json<Todo>, StatusCode> { state.todos.lock().unwrap().get(&id).cloned().map(Json).ok_or(StatusCode::NOT_FOUND) } I first tried returning Option<Json<Todo>>, which Rocket handles as a 404. axum 0.8 no longer implements IntoResponse for Option, so it doesn't compile there. Result with a status code works. Making the comparison fair Two settings would have skewed the results before I ran anything: 1. Rocket logged every request. I had built its config from Config::debug_default(), which logs at the normal level. Printing a line per request at 30k req/s costs a lot, and the other two log nothing. I switched to release_default() with log_level: LogLevel::Off. 2. actix had a hardcoded .workers(8). Tokio and Rocket size their thread pools from the CPU count. With 1 CPU, actix would have run 8 workers against everyone else's 1. I removed it. All three frameworks call std::thread::available_parallelism(), which respects both the container's cgroup limit and its CPU pinning. Inside a container pinned to one core, nproc prints 1 and each framework starts one worker. That is what makes the comparison equal. The setup One shared multi-stage Dockerfile builds all three: FROM rust:1-bookworm AS build ARG APP WORKDIR /src COPY ${APP}/ ./ RUN cargo build --release && cp target/release/${APP} /app FROM debian:bookworm-slim COPY --from=build /app /app ENTRYPOINT ["/app"] Each server runs like this: docker run --rm --network host \ --cpuset-cpus=0 --memory=1g --memory-swap=1g \ axum-api - --cpuset-cpus=0 pins it to one physical core (0,1 for the two-core test). - --memory-swap equal to --memory turns swap off, so going over 1 GB gets the server killed instead of slowly swapping. - --network host skips docker-proxy, which would otherwise add its own overhead to every request. My laptop has a Ryzen 5 8645HS with 6 cores and 12 threads. lscpu -e=CPU,CORE shows that CPUs 6 and 7 are the hyperthread siblings of 0 and 1. I left them idle and pinned the load generator, oha, to the remaining cores: taskset -c 2-5,8-11 oha -z 10s -c 1000 --no-tui http://localhost:3001/todos If the load generator shares cores with the server, you end up measuring the load generator. For each framework, bench.sh adds 100 todos, warms up for 3 seconds, then runs GET /todos at 50, 100, 500 and 1000 connections and finally POST /todos, 10 seconds each. After every run it reads memory.peak from the container's cgroup. Results 1 CPU, 1 GB RAM | | actix-web | axum | Rocket | | --- | --- | --- | --- | | GET req/s, 100 connections | 67,205 | 47,328 | 33,792 | | GET req/s, 1000 connections | 58,279 | 44,788 | 31,459 | | GET p99, 1000 connections | 19 ms | 156 ms | 172 ms | | POST req/s, 100 connections | 123,745 | 113,489 | 70,511 | | Idle RAM | 1.4 MB | 0.9 MB | 1.0 MB | | Peak RAM, 1000 connections | 28 MB | 37 MB | 38 MB | 2 CPUs, 1 GB RAM | | actix-web | axum | Rocket | | --- | --- | --- | --- | | GET req/s, 100 connections | 128,872 | 80,511 | 63,736 | | GET req/s, 1000 connections | 109,103 | 65,114 | 57,171 | | GET p99, 1000 connections | 11 ms | 56 ms | 77 ms | | POST req/s, 100 connections | 236,629 | 217,888 | 133,975 | No errors and no out-of-memory kills in any run. The full table, including p50 latency for every run, is in the repo README. What the numbers say actix wins on throughput. It did about 1.4x what axum did and about 2x Rocket. It also scaled best from one core to two. The latency story is more interesting. At 1000 connections on one core, axum's median was 5 ms against actix's 17 ms, but axum's p99 was 156 ms against actix's 19 ms. axum and Rocket serve most requests quickly and make a few wait a long time. actix serves everyone at about the same speed. If you care about the slowest 1% of your users, that matters more than the req/s number. RAM doesn't matter at this scale. All three idle at about 1 MB and stay under 50 MB holding 1000 open connections. A 1 GB server runs out of CPU long before it runs out of memory. The POST runs did reach 180 to 360 MB, but that was the HashMap holding over a million todos after 10 seconds, not framework overhead. Rocket is "slow" only next to the other two. 31k requests per second on a single core is about 2.7 billion requests a day. No app I run gets anywhere near that. Round two: AWS, over a real network The laptop run had one obvious hole: the load generator and the server shared a machine and talked over localhost. So I ran it again on AWS in ap-south-1 (Mumbai), with two spot instances: | Role | Instance | vCPU | RAM | | --- | --- | --- | --- | | Server | c7i.xlarge | 4 (2 physical cores) | 8 GB | | Load generator | c7i.2xlarge | 8 | 16 GB | Both ran Amazon Linux 2023, in the same AZ and a cluster placement group, talking over private IPs. I didn't pick c7i.large for the server, because its 2 vCPUs are two hyperthreads of one core, and the 2 CPU test would have meant something different from the laptop. On the c7i.xlarge, vCPUs 0/2 and 1/3 are hyperthread pairs, so the server got 0 or 0,1, with 2 and 3 left idle. The container still had the same 1 GB cap. There was no SSH. Both boxes were driven with SSM Run Command, and the security group only let the load generator reach ports 3001 to 3003. The whole thing, Docker builds included, took about 20 minutes and cost well under a dollar at spot prices. 1 CPU, 1 GB RAM, on AWS | | actix-web | axum | Rocket | | --- | --- | --- | --- | | GET req/s, 100 connections | 66,252 | 47,784 | 40,390 | | GET req/s, 1000 connections | 63,885 | 42,090 | 36,304 | | GET p99, 1000 connections | 16 ms | 142 ms | 165 ms | | POST req/s, 100 connections | 171,394 | 150,572 | 73,327 | 2 CPUs, 1 GB RAM, on AWS | | actix-web | axum | Rocket | | --- | --- | --- | --- | | GET req/s, 100 connections | 111,959 | 79,327 | 61,285 | | GET req/s, 1000 connections | 107,731 | 43,867 | 58,774 | | GET p99, 1000 connections | 10 ms | 65 ms | 75 ms | | POST req/s, 100 connections | 286,742 | 228,708 | 113,680 | On one core, the cloud matched the laptop almost exactly: actix 66k vs 67k, axum 48k vs 47k. Rocket did a bit better on AWS, 40k vs 34k. POST was faster across the board, likely because the load generator had a whole machine to itself. The surprise was axum on 2 CPUs at high connection counts. In the main run it fell to about 44k req/s at 1000 connections, below Rocket. I didn't trust that, so I ran it twice more while the instances were still up: | axum, 2 CPUs | c=100 | c=500 | c=1000 | | --- | --- | --- | --- | | Run 1 | 79,327 | 44,231 | 43,867 | | Run 2 | 80,642 | 76,913 | 43,217 | | Run 3 | 80,250 | 81,166 | 76,492 | It lands at either about 44k or about 78k, never in between. actix and Rocket stayed within a few percent in every run. I haven't found the cause yet, but it's a good reminder that one run can lie, and that a stable framework is worth something on its own. Caveats - The laptop numbers are a single run. CPU boost and heat move numbers by 5 to 10%, so don't read anything into small gaps. - The laptop run is over localhost. The AWS run below fixes that. - GET /todos returns 100 todos, about 8 KB of JSON. That measures cloning and serde as much as routing. - The AWS run is one region and one instance family. Graviton (Arm) or AMD instances may rank differently. - A real app talks to a database. As I found in [latency is geography](/blog/latency-is-geography), the database round trip will cost far more than any difference between these three frameworks. So which one? On raw numbers, actix-web, both on my laptop and on AWS. In practice, any of them will handle far more than a 1 CPU server will ever be asked to do. I would pick axum for its ecosystem (tower middleware, tokio everywhere) and how little code it takes, and reach for actix when tail latency under heavy load really matters. Whichever you pick, don't unwrap() while holding a lock. The code, the Dockerfile and the benchmark script are on GitHub: 2u841r/actix-vs-axum-vs-rocket. Run ./bench.sh on your own machine and see whether your numbers match mine.

  2. これが俺のAI slopや! hatoo/shb

    1 like · 47 views
  3. TanStack Start vs Next.js in 2026: Same App, Real Benchmarks I built the same small store in TanStack Start 1.0 and Next.js 16.4 and benchmarked both on one machine. The original, with any updates, lives on fabwaseem.com. TanStack Start vs Next.js got a lot more interesting on October 13, 2026, when TanStack Start 1.0 went stable. I built the same small store in both frameworks, with the same routes, data, components and Tailwind styles, and measured them on one machine. TanStack Start served 2.9× more server-rendered list pages, 4.6× more product pages and 8.6× more JSON API calls per second than Next.js 16.4. It also shipped 20% less JavaScript and built 3.9× faster. Next.js still won where it was designed to win: a prerendered page, and a far bigger set of built-in tools. Here are the numbers, how I got them, and how I'd choose between the two in 2026. TL;DR: is TanStack Start faster than Next.js? On the server, yes, by a wide margin in my tests. Every route that rendered per request was 2.9× to 8.6× faster on TanStack Start, with much lower tail latency. On the client the gap is smaller: 109 KB of gzipped JavaScript against 135 KB, and an interactive button 35 ms sooner on a throttled CPU. Next.js led only on its prerendered home page, because it serves static HTML while Start rendered that page on every request. | Same app, Node 24.22, 2 cores | Next.js 16.4.2 | TanStack Start 1.169.3 | Difference | | --- | --- | --- | --- | | Home page, req/s | 3,220 (static) | 2,920 (SSR) | Next +10% | | Product list, 100 items, SSR, req/s | 220 | 637 | Start 2.9× | | Product page, SSR, req/s | 512 | 2,341 | Start 4.6× | | JSON API route, req/s | 2,165 | 18,515 | Start 8.6× | | p99 latency, product list | 754 ms | 194 ms | Start 3.9× lower | | Server memory at idle | 94 MB | 60 MB | Start −36% | | Client JS on /products, gzip | 135 KB, 7 files | 109 KB, 3 files | Start −20% | | Interactive button, 4× CPU throttle | 324 ms | 289 ms | Start −35 ms | | Production build | 4.86 s | 1.26 s | Start 3.9× | | Dev server, first page | 2.96 s | 1.52 s | Start 1.9× | | Deploy output | 38 MB | 1.4 MB | Start 27× smaller | If you mostly ship content that can be cached, these server numbers matter less. If you run a dashboard, an API-heavy app or anything that renders per user, they matter a lot. What is TanStack Start? TanStack Start is a full-stack React framework built on TanStack Router. It adds server-side rendering, streaming, typed server functions, server routes for raw HTTP and middleware, and it builds with Vite (or Rsbuild). The 1.0 announcement calls it ready for production after a long release-candidate phase, and the first stable package was @tanstack/react-start 1.169.0. The big design difference from Next.js is the component model. In Next.js App Router, pages and layouts are React Server Components by default and you opt into client code with "use client". In Start, components are ordinary React components that render on the server and hydrate on the client. You put work on the server explicitly with createServerFn() or a route loader. Server Components in Start exist, but they are experimental and off by default, so treat them as a preview, not a reason to pick it. How I benchmarked TanStack Start and Next.js I wanted a fair app, not a hello world. Both apps have: - Home page: a heading and a link. Next.js prerenders it as static HTML; Start has no static prerender by default, so it renders it per request. - Product list: 100 products rendered on the server on every request, with a timestamp so neither framework can cache it. In Next.js that's an async Server Component with await connection(). In Start it's a route loader calling a GET server function. - Product page: one product plus a client-side "Add to cart" counter, so both frameworks must hydrate interactive code. - JSON API: a route returning 20 products. A Next.js route handler with dynamic = "force-dynamic", and a Start server route. Versions: Next.js 16.4.2 with Turbopack and React 19.3.0, TanStack Start 1.169.3 with Vite 8.3.4, Nitro and React 19.3.1, Tailwind 4 in both. Both ran on Node 24.22 in production mode: Next.js as its standalone server.js, Start as its Nitro Node output. A quick check with next start gave the same results (2,377 req/s on the API, 534 on the product page). The server was pinned to 2 CPU cores with taskset, and the load generator oha ran on 6 other cores of an 8 vCPU Xeon VM. Each run used 64 connections for 10 seconds after a 4 second warm-up, and every number is the median of 3 runs on a fresh server process. All runs returned 100% HTTP 200. Client metrics came from Playwright and Chromium: script bytes on each page (gzip level 6), and the time from navigation to a working button click with a 4× CPU slowdown, median of 6 runs. This is a small synthetic store, not your app. Your database, auth and caching will usually dominate. Treat these as the cost of the framework layer itself. Server performance: how many requests can each handle? !TanStack Start vs Next.js server throughput on the same four routes, requests per second and p99 latency Server-rendered pages. The product list is where per-request rendering cost shows. Start served 637 pages per second with a p99 of 194 ms; Next.js served 220 with a p99 of 754 ms. On the lighter product page, Start served 2,341 per second versus 512. My reading is that Next.js does more work per request: it renders the Server Component tree to the RSC payload and then renders HTML from it, and it embeds that payload in the page. You can see that in the HTML: the 100-item list was 92 KB raw in Next.js and 60 KB in Start (8.5 KB versus 6.4 KB gzipped). API routes. This was the biggest gap. A Start server route answered 18,515 requests per second; a Next.js route handler answered 2,165. That's 8.6×. Start's server routes are close to a plain handler on Nitro, while every Next.js request goes through the full Next server and router. For context, Hono on raw Node served 73,000 JSON requests per second on the same 2 cores in my Hono vs Express benchmark, so neither framework is the right place for a hot, high-volume API. Static pages. Next.js led here: 3,220 versus 2,920 requests per second. Next serves the prerendered HTML file, while Start rendered the home page with React each time and still came within 10%. This is the important caveat for Next.js: anything you can make static or cache, with "use cache" or prerendering, skips most of the per-request cost. I covered how to do that in Next.js "use cache". Memory. Next.js idled at 94 MB and peaked at about 504 MB under the SSR list load. Start idled at 60 MB and peaked at 363 MB. Both are fine for a small VPS, but on a 1 GB box running several apps, Start leaves more room. Bundle size, hydration and client navigation !TanStack Start vs Next.js client JavaScript, HTML size, time to interactive, build time, dev server start and deploy size On /products, Next.js loaded 7 script files totalling 135 KB gzipped (453 KB raw). Start loaded 3 files totalling 109 KB gzipped (337 KB raw). Most of both is React and React DOM, so the difference is framework runtime: about 26 KB gzipped. With Chromium's CPU throttled 4×, the "Add to cart" button on a fresh product page became interactive in 289 ms on Start and 324 ms on Next.js. Client-side navigation from the list to a product took 160 ms on Start versus 182 ms on Next.js. Start made 2 requests per navigation (the route chunk and the server function), while Next.js made about 10. So on the client, Start is faster, but not dramatically. On a real app with a large component library, your own code will outweigh this 26 KB. Build time, dev server and deployment Production build: Next.js took 4.86 s (5 clean runs, including its TypeScript check) and Start took 1.26 s with Vite. Running tsc --noEmit separately on the Start app took another 1.54 s, so even with a type check added, Start's build was about 1.7× faster. Dev server: from launching the dev command to the first fully rendered /products page, Next.js took 2.96 s cold and 2.91 s warm. Start with Vite took 1.52 s cold and 1.45 s warm. Deploy output: Next.js standalone output was 38 MB because it traces and copies the parts of node_modules it needs, including Next itself. Start's Nitro output was 1.4 MB, fully bundled. In a Docker image that difference is real, but small next to a Node base image. My Next.js Dockerfile guide shows how to keep the Next.js side lean. Installed node_modules were 354 MB for the Next.js app and 152 MB for Start. Developer experience: what's different day to day? Numbers aside, the daily work feels different: - Data loading. Next.js fetches data inside async Server Components. Start uses route loaders and server functions, usually with TanStack Query for client caching. If you already use TanStack Query, Start will feel natural. - Server code. Next.js has Server Actions and route handlers; I compared them in Server Actions vs Route Handlers. Start has createServerFn() with validators, GET or POST, and middleware that runs on both client and server. - Type safety. Start's router generates types for every path, param and search param, so a broken link is a type error. Next.js has opt-in typedRoutes, which covers links but not validated search params. - Caching. Next.js has a framework cache (Cache Components, "use cache", cacheLife). Start has no server data cache: you use HTTP headers, a CDN, or your own store. That's simpler to reason about and more work for content sites. - Built-ins. Next.js ships next/image, next/font, metadata APIs and a huge ecosystem of examples. In Start you bring your own image and font handling. - Hosting. Next.js runs best on Vercel and works anywhere with Node or Docker, as I do with Coolify. Start deploys through Nitro or plugins to Node, Bun, Cloudflare Workers, Netlify, Vercel and Railway. One gotcha I hit in Next.js: my generated project wired Tailwind 4 through a turbopack.rules entry for *.css in next.config.ts (the @tailwindcss/turbopack loader). When I overwrote the config to add output: "standalone", the CSS came out empty and the Tailwind compiler ended up in the client bundle: 280 KB of gzipped JavaScript instead of 135 KB. If you edit that file, keep the rules block, and check your bundle after config changes. Should I switch from Next.js to TanStack Start? Pick TanStack Start if: - your app renders per user or per request (dashboards, SaaS, internal tools), so server cost matters - you want typed routes and search params, explicit server functions and no framework-level cache - you like Vite, or want to deploy to Cloudflare Workers or a small VPS without Vercel - you already use TanStack Query, Router or Table Stay with or pick Next.js if: - your site is mostly content that can be prerendered or cached, where Next served static pages fastest - you rely on React Server Components today, or on next/image, next/font and the metadata API - hiring, templates and third-party SDK examples matter more than raw speed - you host on Vercel and want its integration For an existing, healthy Next.js app, I wouldn't rewrite just for these numbers. Cache what you can first. For a new interactive app, Start 1.0 is now a serious default. The official TanStack Start vs Next.js page has a fair feature-by-feature comparison too. How do I migrate from Next.js to TanStack Start? The rough steps I'd follow, based on building the same app in both: 1. Move app/ routes to src/routes/ files using createFileRoute. Dynamic segments change from [id] to $id. 2. Replace data fetching in async Server Components with a route loader that calls a createServerFn(). 3. Remove "use client" directives. Every component in Start is a normal component. 4. Turn route handlers into server routes with server: { handlers: { GET } }. 5. Replace Server Actions with POST server functions, and add an input validator. 6. Replace next/link with TanStack Router's Link (to plus typed params), and next/image and next/font with your own components or plain tags. 7. Add Nitro (or a hosting plugin) to vite.config.ts for your deploy target. Migrate one representative route end to end first, including auth and a mutation, before committing the whole app. Common mistakes when comparing Next.js and TanStack Start - Comparing a static Next.js page to an SSR Start page and calling Next faster. Make the rendering mode the same on both sides, or report it, as I did for the home page. - Forgetting to copy .next/static into the standalone folder. Next's standalone server doesn't serve client assets without it, so hydration silently never happens. My first client test showed a 30 second timeout for exactly this reason. - Benchmarking dev mode. Always build and run with NODE_ENV=production. - Running the load generator on the same cores as the server. Pin them apart or your numbers mostly measure contention. - Leaving devtools in production. Check that router and query devtools aren't in your client bundle. Key takeaways - TanStack Start 1.0 went stable on October 13, 2026, and its Server Components support is still experimental. - On the same app and 2 cores, Start served 2.9× more SSR list pages, 4.6× more product pages and 8.6× more API calls than Next.js 16.4. - Next.js won on its prerendered static page, 3,220 versus 2,920 req/s, so caching closes the gap for content you can cache. - Start's p99 on the 100-item SSR page was 194 ms versus 754 ms, and it idled at 60 MB versus 94 MB. - Start shipped 20% less client JavaScript (109 KB vs 135 KB gzipped) and became interactive 35 ms sooner on a throttled CPU. - Start built in 1.26 s versus 4.86 s and its dev server answered in 1.5 s versus 3.0 s. - Choose Start for per-request, interactive apps and typed routing; choose Next.js for cacheable content, RSC and its built-ins. Related: if you're weighing other parts of your toolchain too, see Oxlint vs Biome vs ESLint and React Compiler in Next.js. FAQ Is TanStack Start faster than Next.js? On the server, yes in my tests. With the same app on 2 CPU cores, TanStack Start 1.169.3 served 637 server-rendered list pages per second versus 220 for Next.js 16.4.2, 2,341 product pages versus 512, and 18,515 API requests versus 2,165. Next.js was faster only on a prerendered static page, 3,220 versus 2,920 requests per second. Is TanStack Start stable and production ready? Yes. TanStack Start 1.0 was announced as stable on October 13, 2026, with @tanstack/react-start 1.169.0 as the first stable release. Its React Server Components support is still experimental and off by default. Does TanStack Start ship less JavaScript than Next.js? Somewhat. On the same product list page, TanStack Start loaded 109 KB of gzipped JavaScript in 3 files and Next.js loaded 135 KB in 7 files. Most of both is React itself, so the framework difference was about 26 KB gzipped. Does TanStack Start support React Server Components? Yes, but experimentally. You opt in with @vitejs/plugin-rsc and rsc: { enabled: true } in the tanstackStart plugin, and the docs say the feature will stay experimental into early v1. Start's normal SSR, loaders and server functions don't need Server Components. Should I migrate my Next.js app to TanStack Start? Not just for speed if the app is healthy. Cache or prerender what you can in Next.js first, since static pages were Next's fastest case. Consider Start for new interactive apps, apps that render per user, or teams that want typed routes and search params, Vite and simple hosting. How much faster does TanStack Start build than Next.js? In my test app, vite build for TanStack Start took 1.26 s and next build took 4.86 s, averaged over 5 clean runs. next build includes a TypeScript check; adding tsc --noEmit (1.54 s) to the Start build still left it about 1.7× faster. Can TanStack Start be self-hosted? Yes. It builds through Nitro to a self-contained Node server, which was 1.4 MB in my test versus 38 MB for the Next.js standalone output. It also deploys to Bun, Cloudflare Workers, Netlify, Vercel and Railway. What is the difference between Next.js Server Actions and TanStack Start server functions? Next.js Server Actions are tied to forms and React's pending and error states. TanStack Start server functions are typed RPC calls created with createServerFn, can use GET or POST, accept an input validator and compose middleware that runs on both client and server. Both need runtime validation and server-side authorization. --- Originally published on fabwaseem.com.

  4. Hono vs Express vs Fastify (and NestJS) in 2026: Real Benchmarks on Node 24, Node 26 and Bun I ran these benchmarks myself, and every number below comes from those runs. The original, with any updates, lives on fabwaseem.com. Hono vs Express in 2026 is a closer race than the benchmark charts you've seen suggest. On Node.js 24, Hono served 1.44× as many JSON requests per second as Express 5 in my tests, and Fastify was right next to it. But Fastify beat Hono on route parameters and POST bodies, and NestJS added 21 to 23% overhead on top of whichever engine it ran on. The biggest jump didn't come from the framework at all: moving Hono from Node to Bun gave another 1.6×. I benchmarked seven setups (raw node:http, Hono, Express, Fastify with and without response schemas, and NestJS 12 on both its Express and Fastify adapters) across three workloads, two Node versions and Bun. Here's every number, how I got it, and which framework I'd pick for which job. TL;DR: Hono vs Express vs Fastify, which is fastest? On Node, Hono and Fastify are tied for first, and both are about 1.4× faster than Express. Hono won the plain JSON test, Fastify won route parameters and POST bodies. Express 5 is the slowest of the three but still served 50,000 requests per second on two CPU cores, which is more than most APIs will ever see. On Bun, Hono pulls clearly ahead at 118,000 requests per second. | Node 24.22, 2 cores, requests/s (median) | JSON | Route param | POST JSON body | Startup to first response | Install size | | --- | --- | --- | --- | --- | --- | | node:http (no framework) | 78,870 | 73,049 | 41,917 | 76 ms | none | | Hono 4.13.13 | 73,067 | 70,128 | 36,553 | 94 ms | 3.9 MB, 2 packages | | Fastify 5.12.7 | 71,786 | 76,746 | 38,936 | 153 ms | 14.4 MB, 48 packages | | Express 5.3.0 | 50,744 | 48,335 | 28,569 | 116 ms | 4.3 MB, 65 packages | | NestJS 12.1.3 + Fastify | 56,434 | 59,499 | 33,418 | 425 ms | n/a | | NestJS 12.1.3 + Express | 38,893 | 35,829 | 23,011 | 320 ms | 22.4 MB, 98 packages | My pick: Hono for new APIs, especially anything that might run on Bun, Cloudflare Workers or another edge runtime. Fastify for Node-only services where you want schemas, plugins and the best throughput on real routes. Express when the team and middleware already exist, because it's fast enough. NestJS when the codebase is big enough that structure matters more than 20% of throughput, and then put it on the Fastify adapter. What are Hono, Express and Fastify? All three are HTTP frameworks for JavaScript and TypeScript, and they come from different eras. - Express is the 2010 original and still the default. Express 5 finally shipped native promise support in route handlers and dropped a lot of legacy API. It has the largest middleware ecosystem by far: 145 million npm downloads in the week of October 6 to 12, 2026. - Fastify was built for speed on Node. It compiles JSON schemas into fast serializers and validators, has a strict plugin system with encapsulation, and logs with Pino by default. 15.4 million downloads that week. - Hono is built on web standards: handlers take a Request-like context and return a Response. The same app runs on Node, Bun, Deno, Cloudflare Workers, AWS Lambda and Vercel. It's tiny and has zero dependencies. 74 million downloads that week, partly because other tools bundle it. - NestJS isn't a fourth HTTP engine. It's an application framework with modules, dependency injection and decorators that runs on top of Express (the default) or Fastify. I covered the latest release in my NestJS 12 upgrade guide. The code looks similar for a simple route. Here are the three handlers I benchmarked: // Hono app.get('/users/:id', c => c.json({ id: c.req.param('id'), fields: c.req.query('fields') ?? null })) // Express 5 app.get('/users/:id', (req, res) => res.json({ id: req.params.id, fields: req.query.fields ?? null })) // Fastify 5 app.get('/users/:id', async req => ({ id: req.params.id, fields: req.query.fields ?? null })) How I benchmarked them Benchmarks of web frameworks are easy to get wrong, so here's exactly what I ran. 1. Machine. An 8 vCPU Intel Xeon VM with 15 GB of RAM. Each server was pinned to 2 cores with taskset. The load generator, oha 1.16.0, ran on the other 6 cores with 64 connections. 2. Runtimes. Node.js 24.22.0, Node.js 26.12.0 and Bun 1.4.3. 3. Versions. Hono 4.13.13 with @hono/node-server 2.1.5, Express 5.3.0, Fastify 5.12.7, and NestJS 12.1.3 with @nestjs/platform-express and @nestjs/platform-fastify. These were the latest npm releases on October 17, 2026. 4. Workloads. GET /json returns {"message":"Hello, World!"}. GET /users/42?fields=name reads a route parameter and a query string. POST /echo parses a 907-byte JSON body and returns a count. 5. Fair settings. No logging. ETags off in Express and in NestJS on Express, and x-powered-by off in Express. Fastify ran twice, once without schemas and once with response schemas. Every app returns the same JSON. 6. Method. Each run started a fresh server, warmed it up for 4 seconds, then measured for 10 seconds. I ran 3 rounds per setup and report the median. Four setups had one noisy round, so I re-ran those with 5 rounds. That's 32 setups and more than 65 million measured requests, with a 100% success rate. Absolute numbers depend on hardware. The ratios between frameworks are what transfer to your servers. Is Hono faster than Express? Yes. On Node 24, Hono handled 1.44× Express's throughput on plain JSON (73,067 vs 50,744 requests per second), 1.45× on route parameters and 1.28× on POST bodies. Latency followed: p99 on the JSON test was 1.50 ms for Hono against 2.12 ms for Express. !Hono vs Express vs Fastify vs NestJS throughput on Node 24, Node 26 and Bun, requests per second Two details matter more than the headline: - Hono came within 8% of raw node:http on the JSON test. There's very little left to optimize in the framework itself. - Hono's lead shrinks on POST. On Node, Hono goes through @hono/node-server, which turns Node's request into a web-standard Request before your handler sees it. Parsing a body through that layer costs more than Fastify's native parser. On Bun, where Request is native, the same Hono app did 80,749 POST requests per second, 2.2× its Node result. Express 5 pays for its flexible middleware pipeline and the extra properties it adds to every request and response. It's still not slow. Fifty thousand requests per second on two cores is about 4 billion requests a day. Your database will give out long before Express does. Hono vs Fastify: which is faster? It depends on the route. On Node 24: | Requests/s, Node 24 | Hono | Fastify | Fastify + response schema | Winner | | --- | --- | --- | --- | --- | | JSON | 73,067 | 71,786 | 74,567 | tie (within 4%) | | Route param + query | 70,128 | 76,746 | 75,526 | Fastify, +9% | | POST JSON body | 36,553 | 38,936 | 39,045 | Fastify, +7% | Fastify's router is a radix tree (find-my-way), and it beat even my hand-written node:http router on the route parameter test (76,746 vs 73,049), because my raw version builds a URL object per request. Adding response schemas, which Fastify compiles into a serializer with fast-json-stringify, was worth only about 4% on these small responses. The bigger value of schemas is validation and documentation, not speed. So on Node, call it a draw. Pick between them on design: web standards and portability (Hono), or schemas, plugins and Node depth (Fastify). Fastify vs Express: is it worth switching in 2026? On raw speed, Fastify was 1.41× faster on JSON, 1.59× on route parameters and 1.36× on POST. Its p99 latency was 25 to 40% lower too. Whether that justifies a rewrite depends on where your time goes. If a typical request spends 20 ms in Postgres and 0.3 ms in the framework, cutting the framework's share in half changes nothing a user can feel. Switch when profiling shows the framework near the top, when you want schema validation built in, or when you're starting fresh anyway. Don't switch because of a chart, including this one. How much overhead does NestJS add? NestJS adds a layer of decorators, guards, pipes and interceptors on top of the engine. In my tests that cost 23% of Express's throughput (38,893 vs 50,744 on JSON) and 21% of Fastify's (56,434 vs 71,786). It also used more memory: about 100 MB idle versus 65 MB for plain Express. The fix is easy and well documented in the NestJS performance guide: NestJS on Fastify was 1.45× faster than NestJS on Express on JSON and POST, and 1.66× faster on route parameters. It was also faster than plain Express on every test. If you use NestJS and none of your middleware is Express-specific, the Fastify adapter is the cheapest performance win available. Do Node 26 and Bun change the ranking? Node 26 made every framework faster without code changes. On the JSON test, Express and Fastify gained about 12%, NestJS 10%, Hono 6% and raw node:http 7%. | JSON requests/s | Node 24.22 | Node 26.12 | Bun 1.4.3 | | --- | --- | --- | --- | | Hono | 73,067 | 77,454 | 118,432 | | Fastify | 71,786 | 80,220 | 86,269 | | Express | 50,744 | 56,627 | 72,479 | | NestJS + Express | 38,893 | 42,923 | not tested | On Bun, the ranking changes. Hono uses Bun's native server directly, so it ran 1.62× faster than on Node 24 and opened a 37% lead over Fastify. Express and Fastify also got faster on Bun (1.43× and 1.20×) but they run through Bun's node:http compatibility layer instead of calling Bun.serve directly. If you plan to run on Bun, Hono is the obvious choice. I compared the runtimes themselves in Bun vs Node.js in 2026. Memory, startup time and install size Throughput isn't the only cost. Startup matters for serverless and autoscaling, and install size matters for container images and cold deploys. !Startup time, memory and install size for Hono, Express, Fastify and NestJS on Node and Bun | Node 24 | Startup to first 200 | Peak RSS at startup | RSS idle | Peak RSS under JSON load | | --- | --- | --- | --- | --- | | node:http | 76 ms | 62 MB | 58 MB | 97 MB | | Hono | 94 ms | 67 MB | 63 MB | 104 MB | | Express | 116 ms | 75 MB | 65 MB | 97 MB | | Fastify | 153 ms | 78 MB | 72 MB | 105 MB | | NestJS + Express | 320 ms | 100 MB | 98 MB | 143 MB | | NestJS + Fastify | 425 ms | 109 MB | 106 MB | 138 MB | | Hono on Bun | 14 ms | 24 MB | 20 MB | 43 MB | Startup is the time from launching the process to the first successful response, measured with hyperfine over 20 runs. Hono on Bun was ready in 14 ms, which is why it's popular for serverless functions. NestJS needed about 2.8 times as long as the plain framework underneath it, because it scans modules and builds its dependency graph at boot. Install size, measured in a fresh folder with npm: Hono plus its Node adapter is 2 packages and 3.9 MB. Express 5 is 65 packages but only 4.3 MB. Fastify is 48 packages and 14.4 MB. A minimal NestJS app on Express (core, common, platform-express, reflect-metadata, rxjs) is 98 packages and 22.4 MB. If you ship Docker images, my Next.js Dockerfile guide has the same multi-stage tricks that keep a Node API image small. Which Node.js framework should I use in 2026? | If you need... | Pick | Why | | --- | --- | --- | | A new API with the fewest moving parts | Hono | Within 8% of raw Node, zero dependencies, web-standard code | | To run on Bun, Workers, Deno or Lambda | Hono | Same app everywhere; 118k req/s on Bun | | The best Node throughput on real routes | Fastify | Won route params and POST; schemas and plugins built in | | An existing team and Express middleware | Express 5 | 50k req/s is plenty; huge ecosystem; easy hiring | | Structure for a large team (modules, DI) | NestJS on Fastify | 1.45 to 1.66× faster than NestJS on Express | | End-to-end typed clients | Hono (RPC) or Fastify with TypeBox | Types flow from routes to clients | Two more points rarely show up in benchmark posts: - Ecosystem. Express still has the most middleware, tutorials and Stack Overflow answers. Fastify's plugin ecosystem covers most production needs. Hono's middleware set is smaller but growing, and anything built on web standards tends to just work. - Typed clients. Hono's RPC mode lets a frontend import the API's types directly. If your frontend is Next.js, also check whether you need a separate API at all; I covered that in Server Actions vs Route Handlers. How do I migrate from Express to Hono or Fastify? You don't need a big-bang rewrite. Both frameworks can sit next to Express while you move routes. // Fastify: run existing Express middleware during a migration import Fastify from 'fastify' import expressPlugin from '@fastify/express' const app = Fastify() await app.register(expressPlugin) app.use(legacyExpressMiddleware) // Hono: same handler shape on every runtime import { Hono } from 'hono' const app = new Hono() app.get('/health', c => c.json({ ok: true })) export default app // Bun, Workers, Deno; use @hono/node-server on Node A safe order: move health checks and read-only routes first, measure them in production, then move the routes that write data. Keep the request and response shapes identical so clients never notice. Watch for Express habits that don't carry over: mutating req from middleware, res.locals, and error handlers with four arguments. Common mistakes when benchmarking web frameworks - Running the load generator on the server's cores. Pin them apart, or you measure contention. - Benchmarking only /hello. Hono won plain JSON, Fastify won routes with parameters and bodies. One endpoint gives you one answer. - Leaving logging on. Fastify with a logger and Express with morgan are both much slower. Compare like with like. - Trusting a single run. Four of my 32 setups had one round 10 to 20% below the others. Take the median of several runs. - Comparing frameworks on different runtimes. "Hono is 2× faster than Express" is often Hono on Bun versus Express on Node. - Ignoring where time actually goes. Profile one real request. The framework is rarely the bottleneck. Related: if your API is meant for AI agents, read MCP vs API before choosing a framework, because the protocol choice changes more than the framework does. Key takeaways - On Node 24, Hono (73,067 req/s) and Fastify (71,786) are tied on JSON, and both are about 1.4× faster than Express 5 (50,744). - Fastify won route parameters (+9% over Hono) and POST bodies (+7%). Hono won plain JSON and came within 8% of raw node:http. - NestJS costs about 21 to 23% throughput and about 2.8× the startup time. On the Fastify adapter it's 1.45 to 1.66× faster than on Express. - Node 26 sped every framework up by 6 to 12% with no code changes. - On Bun, Hono jumped to 118,432 req/s, 1.62× its Node result, with 14 ms startup and 43 MB under load. - Hono installs as 2 packages (3.9 MB). Express is 65 packages (4.3 MB), Fastify 48 (14.4 MB), and NestJS 98 (22.4 MB). - Even Express handled 50,000 requests per second on 2 cores. Pick on design and ecosystem first; the framework is rarely your bottleneck. FAQ Is Hono faster than Express? Yes. In my October 2026 benchmark on Node 24, Hono 4.13.13 served 73,067 JSON requests per second against 50,744 for Express 5.3.0, which is 1.44× faster. It was 1.45× faster on route parameters and 1.28× faster on POST bodies, with lower p99 latency. Is Hono faster than Fastify? On Node they're tied. Hono won plain JSON by 2%, but Fastify won route parameters by 9% and POST bodies by 7%. On Bun, Hono pulls ahead: 118,432 requests per second versus 86,269 for Fastify, because Hono uses Bun's native server directly. Is Fastify faster than Express in 2026? Yes. Fastify 5.12.7 was 1.41× faster than Express 5.3.0 on JSON, 1.59× on route parameters and 1.36× on POST bodies, with 25 to 40% lower p99 latency. Express still handled about 50,000 requests per second on two cores, which is enough for most APIs. How much slower is NestJS than Express or Fastify? NestJS 12.1.3 cost about 23% of Express's throughput and 21% of Fastify's on the JSON test, used about 100 MB of memory at idle, and took about 2.8× as long to start. Using the Fastify adapter made NestJS 1.45 to 1.66× faster than on Express, and faster than plain Express on every test. Should I switch from Express to Hono or Fastify? Only if you have a reason beyond a benchmark. Switch when profiling shows the framework is a real cost, when you want built-in schema validation (Fastify), or when you need to run on Bun, Cloudflare Workers or other runtimes (Hono). If most request time is spent in the database, a faster framework won't be noticeable. Which Node.js framework should I use in 2026? Hono for new APIs and anything that may run on Bun, Workers, Deno or Lambda. Fastify for Node-only services that want schemas, plugins and the best throughput on real routes. Express 5 for teams with existing middleware and experience. NestJS on the Fastify adapter for large codebases that need modules and dependency injection. Does Node 26 make Express, Fastify and Hono faster? Yes. With no code changes, Node 26.12 improved JSON throughput over Node 24.22 by about 12% for Express and Fastify, 10% for NestJS, 7% for raw node:http and 6% for Hono. How did you benchmark Hono, Express and Fastify? Each server ran on 2 pinned CPU cores of an 8 vCPU Xeon VM, with oha 1.16.0 on the other cores at 64 connections. Every run started a fresh server, warmed up for 4 seconds and measured for 10 seconds. I report the median of 3 rounds, or 5 rounds for setups with a noisy round, across 32 setups on Node 24.22, Node 26.12 and Bun 1.4.3. --- Originally published on fabwaseem.com.

  5. Bun vs Node.js in 2026: Bun 1.4 vs Node 24 and 26, Benchmarked I ran these benchmarks myself on one machine, and every number below comes from those runs. The original, with any updates, lives on fabwaseem.com. Bun vs Node in 2026 comes down to this: Bun is a JavaScript runtime, package manager, bundler and test runner in one binary, built on JavaScriptCore and now written in Rust. Node.js is the V8-based runtime almost every server, library and hosting platform targets. Bun 1.4 reports Node.js 26 compatibility, so for many apps switching is now a runtime swap rather than a rewrite. I benchmarked Bun 1.4.3 against Node.js 24.22 (the current LTS) and Node.js 26.12 (LTS from October 28) on one machine. I measured HTTP throughput with Hono, Express and plain node:http, a real Postgres-backed API, a large in-memory heap, startup, TypeScript execution, npm install vs bun install, next build, and native addons like sharp and bcrypt. Every number below comes from those runs. TL;DR: should I switch from Node to Bun? Use Bun as your package manager and script runner today: bun install was 13 to 29 times faster than npm in my tests and changes nothing at runtime. Consider Bun as your production runtime for new or dependency-light APIs, CLIs and serverless functions, where it was 1.4 to 1.8 times faster and used 25-70% less memory under load. Stay on Node.js for large existing services that depend on Node-specific APM, long-running stability or exotic native addons, and move to Node 26, which was 8-16% faster than Node 24 on most of my HTTP tests. | | Node.js 24.22 | Node.js 26.12 | Bun 1.4.3 | | --- | --- | --- | --- | | Engine | V8 | V8 | JavaScriptCore | | Status (Oct 2026) | LTS, maintenance from Oct 20 | Current, LTS from Oct 28 | Stable, 1.x | | Hono JSON API, req/s | 53,408 | 60,431 | 98,145 | | Express 5 JSON, req/s | 35,764 | 38,530 | 55,382 | | Hono + Postgres, req/s | 21,749 | 21,008 | 32,254 (pg), 33,694 (Bun.sql) | | RSS under load, Hono JSON | 105 MB | 105 MB | 36 MB | | Startup (-e 0) | 28.5 ms | 26.3 ms | 3.3 ms | | Run a .ts file | 62.6 ms | 59.1 ms | 3.8 ms | | Install a Next.js app (cold) | 15.4 s (npm) | | 1.15 s (bun) | | Native addons tested | All work | All work | All work (sharp, better-sqlite3, bcrypt, argon2) | What is Bun, and how is it different from Node.js? Bun is an all-in-one toolkit: a JavaScript and TypeScript runtime, an npm-compatible package manager, a bundler and a Jest-style test runner in one executable. Node.js is just the runtime and leans on npm, tsc or a loader, a bundler and a test framework from the ecosystem. Bun runs on Apple's JavaScriptCore engine; Node runs on Google's V8. Bun aims to be a drop-in replacement. It implements Node's built-in modules (node:http, node:fs, node:crypto and the rest), reads package.json and node_modules the same way, and runs N-API native addons. It also adds its own faster APIs such as Bun.serve, Bun.sql and bun:sqlite. What's new in Bun 1.4? Bun 1.4 shipped on August 20, 2026, and it is the first Bun written in Rust instead of Zig. Per the Bun 1.4 release post, it adds "+1,517 tests from the Node.js test suite", fixes "over 2,900 issues", cuts idle CPU by 5x and memory by up to 35%, and "starts 50% faster on Linux." Bun now reports itself as Node.js 26 (process.versions.modules is 147). It also absorbs common dependencies into the runtime: Bun.Image (image processing), Bun.WebView (headless browser), Bun.markdown, Bun.cron(), Bun.Terminal, plus bun run --parallel and bun test --parallel. Upgrading from 1.3 isn't free: the breaking changes list includes stricter TLS verification, YAML 1.2 parsing and no .env auto-loading when Bun is invoked as node. Vercel made 1.4 an explicit opt-in on its platform for the same reason. How I benchmarked Bun vs Node.js 1. Machine. An 8 vCPU Intel Xeon VM with 15 GB RAM. Each server was pinned to 2 cores with taskset. The load generator, oha 1.16.0, ran on the other 6 cores with 64 connections. 2. Runtimes. Node.js 24.22.0, Node.js 26.12.0 and Bun 1.4.3, all official Linux x64 builds. 3. Apps. The same files ran on every runtime: a node:http hello server, a Bun.serve hello server (Bun only), a Hono 4.13 app, an Express 5.3 app, and a Hono route that reads one row from PostgreSQL 18 through pg 8.23 (or Bun.sql on Bun) with a 10-connection pool, across 10,000 users at random IDs. 4. Method. For every configuration: start the server, warm up for 4 seconds, measure for 10 seconds, read RSS from /proc. Each configuration ran 3 times and I report the median. Every request returned 200. 5. CLI timings used hyperfine 2.0.0 (40 runs for startup, 3 to 5 for installs and builds). Postgres ran on the same machine without pinning, so the database test also measures a shared CPU. That's closer to a small VPS than to a tuned cluster. Is Bun faster than Node.js? For HTTP servers, yes, clearly. On the Hono JSON route Bun served 98,145 requests per second against 53,408 on Node 24 and 60,431 on Node 26: 1.84 times Node 24 and 1.62 times Node 26. Bun's advantage held on Express (1.55x Node 24) and on the plain node:http module (1.42x), and Bun.serve reached 128,461 requests per second. !Bun vs Node HTTP benchmark: requests per second for node:http, Hono JSON, Express and Hono with Postgres on Node 24.22, Node 26.12 and Bun 1.4.3; Bun leads every workload, 98,145 vs 53,408 req/s on Hono JSON | Server (median of 3 x 10 s, 64 connections) | Node 24.22 | Node 26.12 | Bun 1.4.3 | Bun vs Node 24 | | --- | --- | --- | --- | --- | | node:http hello | 74,200 req/s | 83,301 req/s | 105,434 req/s | 1.42x | | Bun.serve hello | | | 128,461 req/s | 1.73x | | Hono, 10-item JSON | 53,408 req/s | 60,431 req/s | 98,145 req/s | 1.84x | | Express 5, same JSON | 35,764 req/s | 38,530 req/s | 55,382 req/s | 1.55x | | Hono + Postgres (pg) | 21,749 req/s | 21,008 req/s | 32,254 req/s | 1.48x | | Hono + Postgres (Bun.sql) | | | 33,694 req/s | 1.55x | | 600k-entry in-memory cache | 53,314 req/s | 61,908 req/s | 68,134 req/s | 1.28x | Latency followed throughput. On the Hono JSON route p99 was 2.10 ms on Node 24, 1.95 ms on Node 26 and 1.17 ms on Bun. On the Postgres route p99 was 4.75 ms, 6.95 ms and 3.98 ms, and 3.50 ms with Bun.sql. Two results surprised me. First, Bun stayed about 1.5 times faster even with a real database query in every request, which is where many "it's all the database anyway" arguments end. My database was local and fast, though. Over a real network, round trips will shrink that gap. Second, Node 26 alone was 8-16% faster than Node 24 on four of the five HTTP tests (the Postgres route was a tie), so upgrading Node is the cheapest speedup available. Does Bun use less memory than Node.js? Yes. Idle, a node:http server used 58 MB RSS on Node 24 and 23 MB on Bun, while Bun.serve used 16 MB. Under load the Hono app held 105 MB on both Node versions and 36 MB on Bun. On the Postgres route Node 24 grew to 206 MB against 61 MB for Bun with pg and 56 MB with Bun.sql. | RSS (MB): idle / after 10 s load / peak | Node 24.22 | Node 26.12 | Bun 1.4.3 | | --- | --- | --- | --- | | node:http hello | 58 / 95 / 95 | 60 / 97 / 97 | 23 / 55 / 74 | | Hono JSON | 70 / 105 / 105 | 66 / 105 / 105 | 28 / 36 / 45 | | Express JSON | 65 / 97 / 97 | 66 / 96 / 96 | 40 / 72 / 81 | | Hono + Postgres | 70 / 206 / 206 | 66 / 151 / 151 | 28 / 61 / 69 | | 600k-entry cache | 411 / 455 / 455 | 370 / 410 / 410 | 261 / 300 / 491 | The cache test is the exception worth reading. Bun started with less memory but briefly peaked higher (491 MB) than Node (455 MB). Bun's garbage collector is a known weak spot under large, long-lived heaps. A Bun pull request from this year described a GC "storm" that made allocation-heavy handlers run "at roughly half of Node.js" with a 150 MB live set. That PR #35431 was closed without merging. In my 1.4.3 run with a bigger heap Bun was still 28% faster than Node 24, but test your own workload, not a hello world. How fast does Bun start compared to Node.js? Bun starts about 8 times faster. An empty script took a median 3.3 ms on Bun against 28.5 ms on Node 24 and 26.3 ms on Node 26. Running a TypeScript file took 3.8 ms on Bun against 62.6 ms on Node 24. Node's built-in type stripping uses a WebAssembly-based parser, and here it added about 34 ms over an empty script. bun run launched a package.json script in 3.1 ms against 95.1 ms for npm run. | Command (hyperfine median) | Node 24.22 | Node 26.12 | Bun 1.4.3 | | --- | --- | --- | --- | | Empty script (-e 0) | 28.5 ms | 26.3 ms | 3.3 ms | | hello.ts (type annotations) | 62.6 ms | 59.1 ms | 3.8 ms | | import('express') | 94.1 ms | | 65.3 ms | | Run a no-op package.json script | 95.1 ms (npm run) | | 3.1 ms (bun run) | Startup matters for CLIs, cron jobs, serverless cold starts and test watchers. It barely matters for a long-running API server. Both runtimes run TypeScript directly now: Node's type stripping has been stable since v24.12.0 but only removes erasable syntax and ignores tsconfig.json, while Bun transpiles full TypeScript, including enums. Is bun install faster than npm? Much faster. On a Next.js 16.4.2 app with Tailwind, ESLint and TypeScript (458 packages), a cold install with empty caches and no lockfile took 15.4 seconds with npm and 1.15 seconds with Bun, 13 times faster. A CI-style install from a lockfile with a warm cache took 4.6 seconds with npm ci and 0.16 seconds with bun install --frozen-lockfile, 29 times faster. | Install, Next.js 16.4.2 app (458 packages) | npm 11.19 | bun 1.4.3 | Speedup | | --- | --- | --- | --- | | Cold: no cache, no lockfile (median of 3) | 15.4 s | 1.15 s | 13x | | Warm cache + lockfile (median of 5) | 4.6 s | 0.16 s | 29x | | Peak memory, warm install | 758 MB | 13.5 MB | | This is the safest win in the whole comparison. bun install writes a normal node_modules, so you can keep running the app on Node. The cold number includes downloads over my server's network, so yours will vary. # use Bun only as the package manager and script runner bun install # writes bun.lock and a normal node_modules bun run build # runs your package.json script with Node, as before node server.js # production stays on Node.js Does Next.js work with Bun? Yes. A Next.js 16.4.2 production build ran fine with bun --bun next build, in a median 3.03 seconds against 3.22 seconds on Node 24, about 6% faster. Turbopack does the heavy lifting in Rust either way, so the runtime matters less for builds than for serving requests. Without --bun, bun run build launches the Next.js CLI with Node because of its shebang. bun install bun --bun next build # build with the Bun runtime bun --bun next start # serve with the Bun runtime If you deploy with Docker, the base image changes from node:24-slim to oven/bun, and the rest of a production Next.js Dockerfile stays the same. Do native modules work in Bun? The common ones do. On Bun 1.4.3, sharp (image resize), better-sqlite3, bcrypt, argon2 and pg all installed from npm and passed the same smoke test as on Node 24. Bun runs N-API addons, which covers most popular native packages. Packages that pick a prebuilt binary by NODE_MODULE_VERSION need a build for 147, the ABI Bun 1.4 reports. What still bites people is less about compatibility tables and more about operations: APM agents that patch Node internals, rare Node APIs, and memory behavior under months of traffic. The Bun Node.js compatibility page lists module-by-module status. Is Bun faster at raw JavaScript? Sometimes. CPU-bound micro-benchmarks were mixed, so don't expect a blanket speedup. Bun was about 3 times faster at parsing small JSON and 1.4 times faster than Node 26 on a 67 KB document, but JSON.stringify tied Node 26. Node 26 made a big jump over Node 24 on JSON, 1.8 times faster on stringify. | Single core, ops/s (mean of 2 runs) | Node 24.22 | Node 26.12 | Bun 1.4.3 | | --- | --- | --- | --- | | JSON.parse, 110 B | 1,711,027 | 1,881,418 | 5,226,338 | | JSON.parse, 67 KB | 3,854 | 5,224 | 7,118 | | JSON.stringify, 67 KB | 6,539 | 11,634 | 11,644 | | SHA-256 of 1 KB (node:crypto) | 751,142 | 751,912 | 853,054 | | Sort 100,000 numbers | 55 | 60 | 90 | | Map set + get, 100,000 keys | 102 | 134 | 168 | I dropped one test: a regex replace on a constant string ran at 196 million operations per second on Bun, which means JavaScriptCore optimized the work away. That's the trouble with micro-benchmarks. Trust the HTTP and real-app numbers more than these. Should I use Bun in production in 2026? For new services, it's a reasonable default now. Bun 1.4 is fast, frugal and broadly compatible, and platforms such as Vercel Functions run it. For existing Node services, migrate only when you can measure the benefit and you have tested memory over days, not minutes. Trigger.dev reported a 5x throughput gain moving a service to Bun and also hit a Bun-only memory leak on the way. | Situation | My pick | | --- | --- | | New API, CLI or worker with mainstream dependencies | Bun (runtime + package manager) | | Serverless or cron jobs where cold start dominates | Bun | | Existing large Node service with APM and on-call | Node 26 + bun install in CI | | Heavy use of exotic native addons or Node internals | Node.js | | NestJS or Next.js app | Node in production for now, Bun for installs and scripts; test Bun in staging | !Bun or Node decision guide: use bun install everywhere, Bun runtime for new APIs, CLIs and serverless, Node 26 for large existing services with APM and native addons How do I migrate a Node.js app to Bun? Move in three steps and keep a way back at each one. First swap the package manager, then run your tests on Bun, then switch the production runtime behind a canary. # 1. package manager only (zero runtime risk) bun install # creates bun.lock next to package-lock.json # 2. run tests and scripts on Bun bun run test # your existing test script bun --bun run test # force the Bun runtime even for "node" shebangs # 3. run the server on Bun, keep the code portable bun src/server.ts // portable entry point: Bun.serve on Bun, @hono/node-server on Node import { Hono } from 'hono' const app = new Hono() app.get('/health', (c) => c.json({ ok: true })) if (typeof Bun !== 'undefined') { Bun.serve({ port: 3000, fetch: app.fetch }) } else { const { serve } = await import('@hono/node-server') serve({ fetch: app.fetch, port: 3000 }) } Frameworks built on Web standards, like Hono, make this painless because the same fetch handler runs on both. For database access, pg worked unchanged on Bun in my test, and Bun.sql is the built-in Postgres client that was 4% faster than pg on Bun in my test. If you're choosing an ORM, see Drizzle vs Prisma. If you self-host, Coolify runs a Bun Dockerfile like any other. Common mistakes when comparing Bun and Node.js - Benchmarking hello world only. Bun.serve vs node:http showed a 1.73x gap; Express showed 1.55x and a large-heap handler 1.28x. - Comparing against an old Node. Node 26 was 8-16% faster than Node 24 on four of five HTTP tests. Compare against the Node you would actually run. - Ignoring memory over time. A 10-second run says nothing about a slow leak. Watch RSS for days in staging. - Running the load generator on the same cores. Pin the server and the load generator to separate CPUs, or the numbers mostly measure contention. - Forgetting --bun. bun run executes scripts whose CLI has a #!/usr/bin/env node shebang with Node unless you pass --bun. - Switching runtime and dependencies at once. Swap the package manager first; it gives most of the day-to-day win with none of the runtime risk. Related: I also ran a NestJS 12 app on Bun 1.4.3: it served 1.49 times Node 24's requests per second on a hello route and started in 264 ms vs 361 ms. See the NestJS 12 migration guide. Related: framework choice matters on Bun too. In Hono vs Express vs Fastify, Hono served 118,432 JSON requests per second on Bun 1.4.3, 1.62× its Node 24 result, while Express and Fastify gained less. Key takeaways - Bun 1.4.3 served 1.84 times Node 24's requests per second on a Hono JSON API, and 1.48 times with a Postgres query in every request. - Bun used 25-70% less memory under load, for example 36 MB vs 105 MB RSS for the Hono app. - Bun started in 3.3 ms versus 26-29 ms for Node and ran a TypeScript file in 3.8 ms versus about 60 ms. - bun install was 13 times faster than npm cold and 29 times faster with a warm cache and lockfile. - Node 26 alone was 8-16% faster than Node 24 on four of five HTTP tests, a free upgrade when it becomes LTS on October 28. - sharp, better-sqlite3, bcrypt, argon2, pg and a Next.js 16.4 build all worked on Bun 1.4.3. - Adopt Bun as package manager first, then as runtime for new services; keep large existing Node services on Node 26 until you've tested memory over days. FAQ Is Bun faster than Node.js? For HTTP servers, yes. In my tests Bun 1.4.3 served 98,145 requests per second on a Hono JSON API against 53,408 on Node.js 24 and 60,431 on Node.js 26. With a Postgres query in every request Bun was 1.48 times faster than Node 24. CPU-bound micro-benchmarks were mixed, so the gap depends on the workload. Does Bun use less memory than Node.js? Usually. Under load my Hono app used 36 MB RSS on Bun versus 105 MB on Node 24 and 26, and the Postgres route used 61 MB versus 206 MB on Node 24. With a large in-memory cache Bun idled lower but briefly peaked higher, at 491 MB against 455 MB, so test memory with your own data. Is Bun production ready in 2026? For many services, yes. Bun 1.4 passes 1,517 more Node.js test-suite tests than 1.3, runs common native addons, and is offered on platforms such as Vercel Functions. Teams still report Bun-specific memory issues under long-running load, so canary it and watch memory for days before moving a large existing service. Is bun install faster than npm? Yes. On a Next.js 16.4.2 app with 458 packages, a cold install took 15.4 seconds with npm and 1.15 seconds with Bun. A lockfile install with a warm cache took 4.6 seconds with npm ci and 0.16 seconds with bun install --frozen-lockfile. It writes a normal node_modules, so the app can still run on Node. Does Next.js work with Bun? Yes. A Next.js 16.4.2 production build succeeded with bun --bun next build in 3.03 seconds against 3.22 seconds on Node 24. Use the --bun flag, because bun run otherwise launches the Next.js CLI with Node due to its node shebang. Turbopack compiles in Rust either way, so builds gain little. Do native modules like sharp and bcrypt work in Bun? The popular ones do. On Bun 1.4.3, sharp, better-sqlite3, bcrypt, argon2 and pg installed from npm and passed the same smoke test as on Node 24. Bun runs N-API addons and reports NODE_MODULE_VERSION 147, so packages that select a prebuilt binary by ABI need a build for 147. Should I upgrade to Node 26 or switch to Bun? If you have a large existing service, upgrade to Node 26 first: it was 8 to 16 percent faster than Node 24 on most of my HTTP tests and becomes LTS on October 28, 2026. Switch the runtime to Bun when you start a new service or can measure a clear gain in staging. What changed in Bun 1.4? Bun 1.4, released August 20, 2026, is the first Bun written in Rust instead of Zig. It reports Node.js 26 compatibility, adds 1,517 Node.js test-suite tests, fixes over 2,900 issues, starts 50 percent faster on Linux, and adds built-ins such as Bun.Image, Bun.WebView, Bun.markdown and Bun.cron. It also has breaking changes worth reviewing. --- Originally published on fabwaseem.com.

  6. たしかに。0BSDってやつにしてみたにょ competitive-rust-snippets#5

    4 likes · 218 views
  7. もうあんまし使ってる人居ないと思うけど hatoo/competitive-rust-snippets を適当にMITにしてしまったの良くなかったと思った。厳密にはコピペしたときにライセンス表記が必要になる気がするため

    1 like · 171 views
  8. oha is a command-line HTTP load generator, written in Rust. Load-test your web app with configurable concurrency and request rates, while watching results live in your terminal. 10k+ stars hatoo/oha

    10 views

Achievements

Awards earned by the repositories hatoo owns. Select an award to embed its badge.

No awards yet

Repositories earn awards by reaching the top three in a completed trending day or week.

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.