DEV Community

Alex Spinov
Alex Spinov

Posted on

Hono Has the Fastest Web Framework — Here's Why It's Replacing Express Everywhere

Express is 14 years old. Hono is ultrafast, runs everywhere (Cloudflare Workers, Deno, Bun, Node, AWS Lambda), and has zero dependencies.

Why Hono?

  • Ultrafast: Based on RegExpRouter, faster than Express/Fastify
  • Multi-runtime: Same code runs on Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda
  • Zero dependencies: Tiny bundle size
  • Type-safe: Full TypeScript with RPC-like client

Quick Start

bun create hono my-app
cd my-app && bun install && bun run dev
Enter fullscreen mode Exit fullscreen mode
import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => c.text("Hello Hono!"));

app.get("/users/:id", (c) => {
  const id = c.req.param("id");
  return c.json({ id, name: "Alice" });
});

app.post("/users", async (c) => {
  const body = await c.req.json();
  return c.json({ created: true, user: body }, 201);
});

export default app;
Enter fullscreen mode Exit fullscreen mode

Middleware

import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
import { jwt } from "hono/jwt";
import { compress } from "hono/compress";
import { cache } from "hono/cache";

const app = new Hono();

app.use("*", logger());
app.use("*", cors());
app.use("*", compress());

// Protected routes
app.use("/api/*", jwt({ secret: "my-secret" }));

// Cache static responses
app.use("/static/*", cache({ cacheName: "static", cacheControl: "max-age=3600" }));
Enter fullscreen mode Exit fullscreen mode

Zod Validation

import { zValidator } from "@hono/zod-validator";
import { z } from "zod";

const createUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().min(18),
});

app.post("/users", zValidator("json", createUserSchema), (c) => {
  const user = c.req.valid("json"); // Fully typed!
  return c.json({ created: true, user });
});
Enter fullscreen mode Exit fullscreen mode

RPC Client (Type-Safe API Calls)

// Server
const routes = app
  .get("/users", (c) => c.json([{ id: 1, name: "Alice" }]))
  .post("/users", zValidator("json", createUserSchema), (c) => {
    return c.json({ id: 2, ...c.req.valid("json") });
  });

type AppType = typeof routes;

// Client (auto-generated types!)
import { hc } from "hono/client";

const client = hc<AppType>("http://localhost:3000");
const res = await client.users.$get();
const users = await res.json(); // Fully typed: { id: number, name: string }[]
Enter fullscreen mode Exit fullscreen mode

Deploy Anywhere

// Cloudflare Workers
export default app;

// Node.js
import { serve } from "@hono/node-server";
serve(app);

// Bun
export default app; // Bun auto-detects

// Deno
Deno.serve(app.fetch);

// AWS Lambda
import { handle } from "hono/aws-lambda";
export const handler = handle(app);
Enter fullscreen mode Exit fullscreen mode

Hono vs Express vs Fastify

Feature Hono Express Fastify
Speed Fastest Slow Fast
Runtime Multi Node only Node only
TypeScript Native Types pkg Good
Dependencies Zero ~30 ~10
Bundle Size ~14KB ~200KB ~100KB
Validation Built-in Manual Ajv

Building APIs for data extraction? Check out my web scraping actors on Apify Store — fast, reliable data from any website. For custom solutions, email spinov001@gmail.com.

Top comments (0)