# TrieRouter

**Kind:** Class

**Source:** [`src/router/trie-router/router.ts`](https://github.com/honojs/hono/blob/main/src/router/trie-router/router.ts#L5)

**Part of:** [Router](subsystem-src-router)

`TrieRouter` stores route patterns and their handlers in a trie-based route tree. Use `add()` to register a method and path, then call `match()` to resolve an incoming method and path to a `Result<T>`.

**Implements:** `Router`

## Methods

| Method | Signature | Returns |
|---|---|---|
| `add` | `add(method: string, path: string, handler: T)` | `void` |
| `match` | `match(method: string, path: string)` | `Result<T>` |

## Properties

| Property | Type |
|---|---|
| `name` | `string` |
| `#node` | `Node<T>` |

## Diagram

```mermaid
graph LR
  Route[Route registration] --> Add[add()]
  Add --> Trie[Trie route tree]
  Request[Incoming method and path] --> Match[match()]
  Match --> Trie
  Trie --> Result[Result<T>]
```

## Usage

```ts
const router = new TrieRouter<string>()

router.add('GET', '/articles/:slug', 'getArticle')
router.add('POST', '/articles', 'createArticle')

const result = router.match('GET', '/articles/intro')

// Pass result to the request dispatcher.
console.log(result)
```

## AI Coding Instructions

- Keep the handler type consistent for every route registered in the same `TrieRouter` instance.
- Register routes through `add()` before matching requests through `match()`.
- Pass the HTTP method and request path to `match()` using the same format used during registration.
- Handle the returned `Result<T>` in the caller that dispatches matched handlers and processes route parameters.

## How it works

- `TrieRouter<T>` is an exported generic router class implementing `Router<T>`. Its public `name` field is `"TrieRouter"`, and each instance initializes one private `Node<T>` as its route storage and matcher. [`src/router/trie-router/router.ts:5-11`](src/router/trie-router/router.ts#L5-L11)

- `add(method, path, handler)` registers `handler` for the supplied method and path by inserting it into that private node structure. This mutates the router’s stored routes and has no returned value. [`src/router/trie-router/router.ts:13-23`](src/router/trie-router/router.ts#L13-L23) The underlying insertion splits routing paths into segments, creates child nodes as needed, and appends a method/handler entry at the terminal node. [`src/router/trie-router/node.ts:44-84`](src/router/trie-router/node.ts#L44-L84)

- Before insertion, `add` checks for an optional named parameter. When `path` ends in `?` and contains `:`, the helper returns expanded path variants; `TrieRouter` inserts the same handler for every variant. [`src/router/trie-router/router.ts:13-20`](src/router/trie-router/router.ts#L13-L20) For example, `/api/animals/:type?` expands to `/api/animals` and `/api/animals/:type`; a root optional parameter expands to `/` and its parameterized form. [`src/utils/url.ts:171-205`](src/utils/url.ts#L171-L205) [`src/utils/url.test.ts:235-255`](src/utils/url.test.ts#L235-L255)

- `match(method, path)` delegates directly to the node search and returns `Result<T>`, whose concrete form here is a one-element tuple containing an array of `[handler, params]` pairs. [`src/router/trie-router/router.ts:25-27`](src/router/trie-router/router.ts#L25-L27) [`src/router/trie-router/node.ts:114-115`](src/router/trie-router/node.ts#L114-L115) [`src/router/trie-router/node.ts:237-244`](src/router/trie-router/node.ts#L237-L244) A non-match returns that same shape with an empty handler array. [`src/router/trie-router/node.test.ts:14-20`](src/router/trie-router/node.test.ts#L14-L20)

- Paths support literal segments, named segments such as `:id`, wildcard segments (`*`), and named segments constrained by a regular expression such as `:id{[0-9]+}`. Pattern recognition is performed while adding routes. [`src/utils/url.ts:50-77`](src/utils/url.ts#L50-L77) Named and constrained captures are returned in the parameter record. [`src/router/trie-router/node.ts:165-229`](src/router/trie-router/node.ts#L165-L229) [`src/router/trie-router/node.test.ts:74-108`](src/router/trie-router/node.test.ts#L74-L108) [`src/router/trie-router/node.test.ts:216-234`](src/router/trie-router/node.test.ts#L216-L234)

- A registered method is matched exactly; if no exact method entry exists at a matched route node, an entry registered as `ALL` is selected. [`src/router/trie-router/node.ts:94-110`](src/router/trie-router/node.ts#L94-L110) [`src/router.ts:6-13`](src/router.ts#L6-L13) Wildcards can match the remainder of a path and also match when no further segment follows, such as `/hello/*` matching `/hello`. [`src/router/trie-router/node.ts:136-146`](src/router/trie-router/node.ts#L136-L146) [`src/router/trie-router/node.ts:153-163`](src/router/trie-router/node.ts#L153-L163)

- Matching can return more than one handler when multiple registered routes match. Returned matches are sorted by their route insertion score, which is incremented for each insertion. [`src/router/trie-router/node.ts:44-46`](src/router/trie-router/node.ts#L44-L46) [`src/router/trie-router/node.ts:237-244`](src/router/trie-router/node.ts#L237-L244) For example, a literal route and a wildcard route can both be returned. [`src/router/trie-router/node.test.ts:125-134`](src/router/trie-router/node.test.ts#L125-L134)

- `TrieRouter` itself contains no explicit argument validation or explicit error handling. [`src/router/trie-router/router.ts:9-27`](src/router/trie-router/router.ts#L9-L27) Route patterns with `{...}` are passed to `new RegExp(...)` during insertion, without a catch in the shown code. [`src/utils/url.ts:60-74`](src/utils/url.ts#L60-L74)

## Relationships

- IMPORTS → `checkOptionalParameter`
- IMPORTS → `Node`
