Skip to Content

Last Updated: 3/9/2026


Routers

Routers are the most important feature of Hono. They determine how fast your application responds to requests.

Hono includes five routers, each optimized for different scenarios. Understanding them helps you choose the right tool for your use case.

TL;DR

  • RegExpRouter — Fastest router in JavaScript (default for most cases)
  • TrieRouter — Handles all route patterns (fallback for RegExpRouter)
  • SmartRouter — Automatically selects the best router (default)
  • LinearRouter — Optimized for “one-shot” environments
  • PatternRouter — Smallest router (under 15KB)

SmartRouter (Default)

SmartRouter is Hono’s default router. It combines multiple routers and automatically selects the fastest one.

import { Hono } from 'hono' const app = new Hono() // SmartRouter is used by default

Internally, SmartRouter uses:

const defaultRouter = new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()], })

When your application starts, SmartRouter analyzes your routes and selects:

  • RegExpRouter if it supports all your route patterns
  • TrieRouter if some patterns require it

You get the best performance automatically.

RegExpRouter: The Fastest

RegExpRouter is the fastest router in the JavaScript world.

How It Works

Unlike traditional routers that use linear loops (checking each route one by one), RegExpRouter compiles all routes into one large regular expression.

// Traditional router (linear) for (const route of routes) { if (route.pattern.test(path)) { return route.handler } } // RegExpRouter (single regex) const result = COMPILED_REGEX.exec(path) return handlers[result.index]

This means:

  • O(1) complexity — Constant time regardless of route count
  • Single match operation — No loops
  • No performance degradation — Add 100 routes or 1000 routes, same speed

Performance

RegExpRouter is 2-3x faster than other fast routers:

RegExpRouter x 1,000,000 ops/sec find-my-way x 400,000 ops/sec koa-tree-router x 350,000 ops/sec

Limitations

RegExpRouter doesn’t support all route patterns. When it encounters an unsupported pattern, SmartRouter falls back to TrieRouter.

Unsupported patterns are rare and include some complex regex patterns.

TrieRouter: Handles Everything

TrieRouter uses a Trie tree algorithm. It’s slower than RegExpRouter but still much faster than Express-style routers.

When It’s Used

SmartRouter uses TrieRouter when:

  • RegExpRouter doesn’t support a pattern
  • You explicitly configure it
import { Hono } from 'hono' import { TrieRouter } from 'hono/router/trie-router' const app = new Hono({ router: new TrieRouter() })

Performance

TrieRouter is:

  • Slower than RegExpRouter — But still very fast
  • Faster than Express — Much faster than linear routers
  • Supports all patterns — No limitations

LinearRouter: One-Shot Optimization

LinearRouter is optimized for environments that initialize on every request.

The Problem

RegExpRouter is fast at matching routes, but compiling the regex takes time. In environments like:

  • Serverless functions with cold starts
  • Edge functions that initialize per request

Route registration speed matters more than matching speed.

The Solution

LinearRouter uses a linear approach:

  • Instant registration — No compilation step
  • Fast enough matching — Linear search is fine for small route sets
  • Optimized for one-shot — Perfect for per-request initialization

Benchmark

Including the registration phase:

LinearRouter 1.82 µs/iter (fastest) KoaTreeRouter 3.81 µs/iter MedleyRouter 4.44 µs/iter TrekRouter 5.84 µs/iter FindMyWay 60.36 µs/iter

LinearRouter is 2x faster than the next competitor when registration is included.

When to Use It

Use LinearRouter when:

  • Your runtime initializes on every request
  • You have a small number of routes (< 50)
  • Cold start time is critical
import { Hono } from 'hono' import { LinearRouter } from 'hono/router/linear-router' const app = new Hono({ router: new LinearRouter() })

PatternRouter: The Smallest

PatternRouter is the smallest router. Use it when bundle size is critical.

Size Comparison

Hono with SmartRouter: ~20KB minified Hono with PatternRouter: <15KB minified

An application using only PatternRouter:

$ npx wrangler deploy --minify ./src/index.ts Total Upload: 14.68 KiB / gzip: 5.38 KiB

When to Use It

Use PatternRouter when:

  • Bundle size is extremely constrained
  • You’re deploying to size-limited environments
  • You have simple routing needs
import { Hono } from 'hono' import { PatternRouter } from 'hono/router/pattern-router' const app = new Hono({ router: new PatternRouter() })

Choosing a Router

Use this decision tree:

Do you need the smallest possible bundle? └─ Yes → PatternRouter └─ No ↓ Does your runtime initialize on every request? └─ Yes → LinearRouter └─ No ↓ Do you have specific router requirements? └─ Yes → Choose manually (RegExpRouter or TrieRouter) └─ No → SmartRouter (default, recommended)

For most applications: Use the default SmartRouter. It automatically optimizes for your routes.

Router Configuration

Default (SmartRouter)

const app = new Hono() // SmartRouter is used automatically

Specific Router

import { RegExpRouter } from 'hono/router/reg-exp-router' import { TrieRouter } from 'hono/router/trie-router' import { LinearRouter } from 'hono/router/linear-router' import { PatternRouter } from 'hono/router/pattern-router' const app = new Hono({ router: new RegExpRouter() })

Custom SmartRouter

import { SmartRouter } from 'hono/router/smart-router' import { RegExpRouter } from 'hono/router/reg-exp-router' import { TrieRouter } from 'hono/router/trie-router' const app = new Hono({ router: new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()], }), })

Performance Tips

Route Order Matters

Routes are matched in registration order:

// Good: Specific routes first app.get('/posts/new', handler1) app.get('/posts/:id', handler2) // Bad: Wildcard matches everything app.get('/posts/*', handler1) app.get('/posts/new', handler2) // Never reached!

Use Path Prefixes

Group routes with common prefixes:

const api = new Hono() api.get('/users', handler) api.get('/posts', handler) app.route('/api', api) // All routes under /api/*

This helps routers optimize matching.

Avoid Unnecessary Wildcards

// Good: Specific path app.get('/api/users', handler) // Bad: Unnecessary wildcard app.get('/api/*', handler)

Specific paths are faster to match.

Benchmarks

See detailed benchmarks in Performance.

What’s Next

Understand middleware: Learn about Middleware and the request/response flow.

See routing patterns: Check out the Routing Guide for all supported patterns.

Compare performance: Read Performance for detailed benchmarks.

Learn Web Standards: Understand Web Standards that power Hono.