---
title: "Smart Router"
description: "The `SmartRouter` is a high-level orchestration component in the Hono framework designed to bridge the gap between multiple underlying routing strategies. Rather than forcing a singular routing alg..."
last_updated: "2026-07-02T09:13:46.833816+00:00"
canonical_url: "https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing-algorithms/smart-router"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [package.json](https://github.com/blade47/hono/blob/main/package.json)
- [jsr.json](https://github.com/blade47/hono/blob/main/jsr.json)
- [src/hono.ts](https://github.com/blade47/hono/blob/main/src/hono.ts)
- [src/validator/validator.ts](https://github.com/blade47/hono/blob/main/src/validator/validator.ts)
- [src/preset/quick.ts](https://github.com/blade47/hono/blob/main/src/preset/quick.ts)
- [src/types.ts](https://github.com/blade47/hono/blob/main/src/types.ts)
- [src/middleware/ip-restriction/index.ts](https://github.com/blade47/hono/blob/main/src/middleware/ip-restriction/index.ts)
- [src/router/smart-router/router.ts](https://github.com/blade47/hono/blob/main/src/router/smart-router/router.ts)
- [src/router/reg-exp-router/router.ts](https://github.com/blade47/hono/blob/main/src/router/reg-exp-router/router.ts)
- [src/utils/url.ts](https://github.com/blade47/hono/blob/main/src/utils/url.ts)
- [src/router/reg-exp-router/prepared-router.ts](https://github.com/blade47/hono/blob/main/src/router/reg-exp-router/prepared-router.ts)
</details>

The `SmartRouter` is a high-level orchestration component in the Hono framework designed to bridge the gap between multiple underlying routing strategies. Rather than forcing a singular routing algorithm (like a Trie or Regular Expression) onto all developers, it acts as a dynamic, "smart" proxy that enables Hono to optimize its routing performance based on the actual usage patterns of an application.

The core problem addressed by `SmartRouter` is the selection of the most efficient routing mechanism. Different routers perform optimally under different conditions (e.g., Trie-based routers often excel at static lookups, while RegExp-based routers offer flexibility for complex patterns). `SmartRouter` achieves this by maintaining an internal list of candidate routers and deferring the definitive choice until the first request is matched.

Upon the first request, the component iterates through its configured router implementations, attempting to register all previously queued routes sequentially into each candidate. The first router to successfully process the full routing table for the given request context is selected as the "active" router. Subsequent requests bypass the initialization logic entirely, essentially hot-swapping the `SmartRouter` instance with the performance-proven candidate.

## Design Philosophy and Router Selection

`SmartRouter` functions as a wrapper that implements the standard `Router` interface, yet hides a sophisticated "activation" phase. Its design follows a "fail-safe and promote" pattern: it maintains a list of candidate routers provided via configuration and, on the first call to `match`, attempts to populate them until one succeeds.

The mechanism uses a deferred routing strategy:
1. All `add` calls (for registering routes) are buffered in a local `private #routes` array.
2. The `match` method, when called for the first time, performs a "build" operation.
3. It iterates through the provided `routers` list, calling `add` for every buffered route on each candidate.
4. If a router successfully matches the request, that router is marked active.

> [!IMPORTANT]
> The `SmartRouter` guarantees that the router chosen is capable of handling the entire existing route set, not just the single request that triggered the selection. This ensures that the state consistency of the routing table is preserved across the transition from buffer to execution.

Sources: [src/router/smart-router/router.ts:4-32](https://github.com/blade47/hono/blob/main/src/router/smart-router/router.ts#L4-L32)

## Initialization and Lifecycle

`SmartRouter` is typically instantiated within the Hono constructor. By default, it is configured with a prioritized list (e.g., `RegExpRouter` followed by `TrieRouter`). This allows the system to attempt the most performant or generic router first.

```mermaid
classDiagram
  class Router {
    <<interface>>
    +add(method, path, handler)
    +match(method, path)
  }
  class SmartRouter {
    -routers: Router[]
    -routes: [method, path, handler][]
    +add()
    +match()
  }
  Router <|-- SmartRouter
```
Sources: [src/hono.ts:28-32](https://github.com/blade47/hono/blob/main/src/hono.ts#L28-L32)

## Call-Chain Execution: The First Match

The most complex logic within `SmartRouter` is the first-match orchestration. The control flow is explicitly designed to handle potential failures in individual router builders (like `UnsupportedPathError`).

1. **`add()`**: Buffers the route into `this.#routes`.
2. **`match()` (First invocation)**: 
   - Checks if `this.#routes` is non-null (indicating build phase).
   - Loops through `this.#routers`.
   - Calls `router.add(...)` for every entry in the buffered `routes` array.
   - Executes `router.match(method, path)`.
   - If an `UnsupportedPathError` occurs, the loop continues to the next router.
   - Upon success, it rebinds `this.match` to the active router's `match` function, effectively becoming a pass-through for subsequent requests.

Sources: [src/router/smart-router/router.ts:13-50](https://github.com/blade47/hono/blob/main/src/router/smart-router/router.ts#L13-L50)

## The Re-binding Mechanism

Once an active router is identified, `SmartRouter` modifies itself to minimize overhead for future requests. By re-binding the `match` function, it bypasses its own logic loop entirely.

```typescript
// The line that shifts responsibility from SmartRouter to the chosen implementation
this.match = router.match.bind(router);
```

This specific assignment prevents unnecessary conditional checks during the high-frequency path of route lookup, effectively turning the `SmartRouter` into a thin wrapper around the chosen router.

Sources: [src/router/smart-router/router.ts:46](https://github.com/blade47/hono/blob/main/src/router/smart-router/router.ts#L46)

## Guard Conditions and Invariants

`SmartRouter` relies on several critical invariants to maintain the integrity of the routing table:

> [!CAUTION]
> Once `match` is called, the state of the router is frozen. The check `if (!this.#routes) throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT)` inside the `add` method prevents any further modifications to the route set after the selection of an active router has occurred.

Sources: [src/router/smart-router/router.ts:14-16](https://github.com/blade47/hono/blob/main/src/router/smart-router/router.ts#L14-L16)

## Usage Example

The following code illustrates how `SmartRouter` is initialized within the standard Hono framework instantiation.

```typescript
import { Hono } from 'hono';
import { SmartRouter } from 'hono/router/smart-router';
import { RegExpRouter } from 'hono/router/reg-exp-router';
import { TrieRouter } from 'hono/router/trie-router';

// Manual instantiation (normally handled by the Hono class)
const myRouter = new SmartRouter({
  routers: [new RegExpRouter(), new TrieRouter()]
});

const app = new Hono({ router: myRouter });

app.get('/api/users', (c) => c.json({ status: 'ok' }));
```
Sources: [src/hono.ts:26-32](https://github.com/blade47/hono/blob/main/src/hono.ts#L26-L32)

## Related

- [RegExp Router](https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing-algorithms/regexp-router)
- [Alternative Routers](https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing-algorithms/alternative-routers)


## Sitemap

See the full [sitemap](https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
