Relevant source files
The following files were used as context for generating this wiki page:
Overview
The application core of Hono centers around the Hono class and its foundational base HonoBase in [[Application Core]], serving as the central dispatcher and routing engine that handles request lifecycle execution, path matching, and middleware coordination across Web Standard runtimes. By separating core routing logic from distribution builds like [[Presets and Builds]], Hono provides an extensible architecture where applications can inject optimized routing strategies such as SmartRouter, TrieRouter, LinearRouter, or PatternRouter to resolve endpoints and parameters. Incoming requests are wrapped into an Execution Context via Context and HonoRequest objects, which manage response rendering, environment bindings, and scoped basePath transformations while supporting modular sub-application composition and centralized error handling.
Sources: src/hono-base.ts:98-126, src/hono.ts:16-33, src/context.ts:293-361, src/request.ts:36-80
Hono and HonoBase architecture
Class Hierarchy and Core Separation
The application architecture relies on a two-tier class hierarchy separating abstract routing mechanisms from concrete router initialization. HonoBase acts as an abstract-like engine implementing route registration, method assignment, middleware composition, request dispatching, and error handling without binding itself to a specific router implementation. The concrete Hono class extends HonoBase, supplying default router configurations and initializing application options.
class Hono<
E extends Env = Env,
S extends Schema = {},
BasePath extends string = '/',
CurrentPath extends string = BasePath,
> {
get!: HandlerInterface<E, 'get', S, BasePath, CurrentPath>
post!: HandlerInterface<E, 'post', S, BasePath, CurrentPath>
put!: HandlerInterface<E, 'put', S, BasePath, CurrentPath>
delete!: HandlerInterface<E, 'delete', S, BasePath, CurrentPath>
options!: HandlerInterface<E, 'options', S, BasePath, CurrentPath>
patch!: HandlerInterface<E, 'patch', S, BasePath, CurrentPath>
all!: HandlerInterface<E, 'all', S, BasePath, CurrentPath>
on: OnHandlerInterface<E, S, BasePath>
use: MiddlewareHandlerInterface<E, S, BasePath>
/*
This class is like an abstract class and does not have a router.
To use it, inherit the class and implement router in the constructor.
*/
router!: Router<[H, RouterRoute]>
readonly getPath: GetPath<E>
// Cannot use `#` because it requires visibility at JavaScript runtime.
private _basePath: string = '/'
#path: string = '/'
routes: RouterRoute[] = []
constructor(options: HonoOptions<E> = {}) {Sources: src/hono-base.ts:98-126
export class Hono<
E extends Env = BlankEnv,
S extends Schema = BlankSchema,
BasePath extends string = '/',
> extends HonoBase<E, S, BasePath> {
/**
* Creates an instance of the Hono class.
*
* @param options - Optional configuration options for the Hono instance.
*/
constructor(options: HonoOptions<E> = {}) {
super(options)
this.router =
options.router ??
new SmartRouter({
routers: [new RegExpRouter(), new TrieRouter()],
})
}Sources: src/hono.ts:16-33
Note
HonoBase declares router without instantiating it directly in its own constructor. Subclasses or custom builds must inject a valid Router implementation before routing requests, or errors will occur during matching.
Constructor Options and Router Injection
The constructor accepts configuration options via HonoOptions, allowing developers to override default path resolution strategies or inject custom routing engines that conform to the Router Contracts specification.
| Option Key | Type | Default Value | Purpose |
|---|---|---|---|
router | Router<[H, RouterRoute]> | new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()] }) | Custom router instance injected into the application. |
strict | boolean | true | Controls whether trailing slashes are strictly matched during path resolution. |
getPath | GetPath<E> | getPath (strict) or getPathNoStrict | Custom function to extract the pathname from incoming request objects. |
const { strict, ...optionsWithoutStrict } = options
Object.assign(this, optionsWithoutStrict)
this.getPath = (strict ?? true) ? (options.getPath ?? getPath) : getPathNoStrict
}Sources: src/hono-base.ts:170-173
constructor(options: HonoOptions<E> = {}) {
super(options)
this.router =
options.router ??
new SmartRouter({
routers: [new RegExpRouter(), new TrieRouter()],
})
}Sources: src/hono.ts:26-33
Tip
Setting strict: false in HonoOptions automatically swaps the default path parser from getPath to getPathNoStrict, allowing requests with and without trailing slashes to resolve to the same handler.
Default Router Configuration
When instantiated without parameters, the concrete Hono constructor defaults to SmartRouter, configured with an internal fallback array containing RegExpRouter and TrieRouter instances. This composition allows Hono to dynamically evaluate route patterns and delegate matching to the most efficient underlying router strategy.
constructor(options: HonoOptions<E> = {}) {
super(options)
this.router =
options.router ??
new SmartRouter({
routers: [new RegExpRouter(), new TrieRouter()],
})
}Sources: src/hono.ts:26-33
HTTP method handler registration
Method and Route Registration APIs
The HonoBase class exposes standard HTTP method registration properties including get, post, put, delete, options, patch, and all. Each method is initialized dynamically in the constructor by iterating over METHODS and METHOD_NAME_ALL_LOWERCASE. When invoked, these method properties accept either a path string followed by one or more request handlers, or simply a sequence of handlers when a path has been set previously.
const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]
allMethods.forEach((method) => {
this[method] = (args1: string | H, ...args: H[]) => {
if (typeof args1 === 'string') {
this.#path = args1
} else {
this.#addRoute(method, this.#path, args1)
}
args.forEach((handler) => {
this.#addRoute(method, this.#path, handler)
})
return this as any
}
})Sources: src/hono-base.ts:128-141
Note
If the first argument passed to a method handler like app.get() is a string, it updates the internal #path property for that registration context. Subsequent arguments and subsequent calls without a string path attach the provided handlers to that stored path.
Custom Method Registration via app.on
In addition to standard method shortcuts, HonoBase provides the .on() method to register routes for arbitrary HTTP methods or collections of methods and paths simultaneously. The .on() implementation flattens input arrays for both paths and methods, converting method strings to uppercase via .toUpperCase() before adding them to the underlying router.
// Implementation of app.on(method, path, ...handlers[])
this.on = (method: string | string[], path: string | string[], ...handlers: H[]) => {
for (const p of [path].flat()) {
this.#path = p
for (const m of [method].flat()) {
handlers.map((handler) => {
this.#addRoute(m.toUpperCase(), this.#path, handler)
})
}
}
return this as any
}Sources: src/hono-base.ts:143-154
Warning
Passing lowercase method strings to app.on() is automatically normalized via toUpperCase(), but callers must ensure custom method identifiers comply with valid HTTP specification requirements if used outside standard fetch client constraints.
Type Signatures and Handler Overloads
Type safety across route registration is governed by HandlerInterface and OnHandlerInterface, which support multiple overloaded signatures ranging from single handlers to multi-handler middleware chains up to ten handlers deep. These interfaces track environment variables (Env), path parameters, input schemas (Input), and typed response mappings (HandlerResponse), merging them into the application's aggregate Schema.
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>,
MiddlewareHandler<E10, P>,
]
): HonoBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
S,
BasePath,
MergedPath
>
//// app.use(path, ...handlers[])
<P extends string, E2 extends Env = E>(
path: P,
...handlers: MiddlewareHandler<E2, MergePath<BasePath, P>>[]
): HonoBase<E, S, BasePath, MergePath<BasePath, P>>
}Sources: src/types.ts:1431-1449
M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>,
M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>,
M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>,
M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>,
M9 extends H<E10, MergedPath, I9> = H<E10, MergedPath, I9>,
>(
method: M,
path: P,
...handlers: [
H<E2, MergedPath, I> & M1,
H<E3, MergedPath, I2> & M2,
H<E4, MergedPath, I3> & M3,
H<E5, MergedPath, I4> & M4,
H<E6, MergedPath, I5> & M5,
H<E7, MergedPath, I6> & M6,
H<E8, MergedPath, I7> & M7,
H<E9, MergedPath, I8> & M8,
H<E10, MergedPath, I9> & M9,
H<E11, MergedPath, I10, R>,
]
): HonoBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
S &
ToSchema<
M,
MergePath<BasePath, P>,
I10,
| MergeTypedResponse<R>
| MergeMiddlewareResponse<M1>
| MergeMiddlewareResponse<M2>
| MergeMiddlewareResponse<M3>
| MergeMiddlewareResponse<M4>
| MergeMiddlewareResponse<M5>
| MergeMiddlewareResponse<M6>
| MergeMiddlewareResponse<M7>
| MergeMiddlewareResponse<M8>
| MergeMiddlewareResponse<M9>
>,
BasePath,
MergePath<BasePath, P>
>Sources: src/types.ts:1901-1941
Route storage and path resolution
Internal Route Structure and Routing Tables
When handlers are registered through method shortcuts, app.use(), or app.on(), HonoBase invokes its private #addRoute method to normalize paths, uppercase method identifiers, and populate internal routing structures. Every registered route is encapsulated as a RouterRoute object containing the assigned basePath, the fully qualified path, the HTTP method, and the target handler.
#addRoute(method: string, path: string, handler: H, baseRoutePath?: string): void {
method = method.toUpperCase()
path = mergePath(this._basePath, path)
const r: RouterRoute = {
basePath:
baseRoutePath !== undefined ? mergePath(this._basePath, baseRoutePath) : this._basePath,
path,
method,
handler,
}
this.router.add(method, path, [handler, r])
this.routes.push(r)
}Sources: src/hono-base.ts:385-397
The RouterRoute entries are dual-stored: they are pushed sequentially into the instance's public routes array for introspection or sub-application composition, and they are registered directly into the active router instance by calling this.router.add(method, path, [handler, r]). This associates each route pattern with a tuple containing the handler and its metadata description.
src/hono-base.ts:124| routes: RouterRoute[] = []Sources: src/hono-base.ts:124
Note
The router implementation stores tuples of [handler, r] as values for each registered method and path combination, permitting downstream dispatch logic to access both the executable function and the complete RouterRoute descriptor during request matching.
Path Normalization and Prefix Merging
Path normalization and prefix combining are handled by utility functions imported from ./utils/url, specifically mergePath, getPath, and getPathNoStrict. Within #addRoute, incoming paths are passed through mergePath(this._basePath, path) to ensure that any configured application base path prefixes are correctly prepended without redundant slashes or missing separators.
method = method.toUpperCase()
path = mergePath(this._basePath, path)Sources: src/hono-base.ts:386-387
The active getPath function is selected during instantiation based on the strict option flag. If strict evaluates to true (the default), options.getPath ?? getPath is selected, enforcing exact path matching including trailing slashes. If strict is set to false, getPathNoStrict is assigned to normalize out trailing slashes during path resolution.
const { strict, ...optionsWithoutStrict } = options
Object.assign(this, optionsWithoutStrict)
this.getPath = (strict ?? true) ? (options.getPath ?? getPath) : getPathNoStrict
}Sources: src/hono-base.ts:170-173
Caution
Modifying the strict flag alters how getPath processes incoming URLs at runtime; mixing strict and non-strict sub-applications without accounting for trailing slash normalization can lead to unexpected 404 Not Found responses during lookup matching.
Sub-application routing and basePath
Scoped basePath Cloning and Instance Isolation
Modular composition in Hono relies on creating isolated sub-applications and scoping routing prefixes via .basePath(). The .basePath() method invokes a private #clone() helper that instantiates a new Hono instance sharing the parent's underlying router, getPath, errorHandler, #notFoundHandler, and routes references, while updating the private _basePath property through mergePath(this._basePath, path).
#clone(): Hono<E, S, BasePath, CurrentPath> {
const clone = new Hono<E, S, BasePath, CurrentPath>({
router: this.router,
getPath: this.getPath,
})
clone.errorHandler = this.errorHandler
clone.#notFoundHandler = this.#notFoundHandler
clone.routes = this.routes
return clone
}Sources: src/hono-base.ts:175-184
basePath<SubPath extends string>(
path: SubPath
): Hono<E, S, MergePath<BasePath, SubPath>, MergePath<BasePath, SubPath>> {
const subApp = this.#clone()
subApp._basePath = mergePath(this._basePath, path)
return subApp
}Sources: src/hono-base.ts:247-253
Tip
Calling .basePath() does not duplicate the underlying router or existing route collection; instead, it returns a lightweight shadow instance pre-configured with an extended _basePath value for subsequent route registrations.
Composing Sub-Applications with route()
Sub-applications and independent Hono router instances can be merged into a parent application using the .route() method. When .route(path, app) is invoked, it creates a scoped sub-application at the specified mount path and iterates over all app.routes definitions, re-registering each route into the parent's router and route collection.
route<
SubPath extends string,
SubEnv extends Env,
SubSchema extends Schema,
SubBasePath extends string,
SubCurrentPath extends string,
>(
path: SubPath,
app: Hono<SubEnv, SubSchema, SubBasePath, SubCurrentPath>
): Hono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> | S, BasePath, CurrentPath> {
const subApp = this.basePath(path)
app.routes.map((r) => {
let handler
if (app.errorHandler === errorHandler) {
handler = r.handler
} else {
handler = async (c: Context, next: Next) =>
(await compose([], app.errorHandler)(c, () => r.handler(c, next))).res
;(handler as any)[COMPOSED_HANDLER] = r.handler
}
subApp.#addRoute(r.method, r.path, handler, r.basePath)
})
return this
}Sources: src/hono-base.ts:208-232
If the mounted sub-application defines a custom error handler differing from the default errorHandler, .route() wraps each copied route handler in a composed execution block that routes errors through the sub-application's specific error boundary before falling back or continuing execution.
if (app.errorHandler === errorHandler) {
handler = r.handler
} else {
handler = async (c: Context, next: Next) =>
(await compose([], app.errorHandler)(c, () => r.handler(c, next))).res
;(handler as any)[COMPOSED_HANDLER] = r.handler
}Sources: src/hono-base.ts:221-227
External Framework Mounting with mount()
External request handlers and applications built with other frameworks can be integrated into a Hono application using the .mount() method. It processes optional MountOptions configurations, which accept either a custom MountOptionHandler function or an options object containing an optionHandler and a replaceRequest strategy.
mount(
path: string,
applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>,
options?: MountOptions
): Hono<E, S, BasePath, CurrentPath> {
// handle options
let replaceRequest: MountReplaceRequest | undefined
let optionHandler: MountOptionHandler | undefined
if (options) {
if (typeof options === 'function') {
optionHandler = options
} else {
optionHandler = options.optionHandler
if (options.replaceRequest === false) {
replaceRequest = (request) => request
} else {
replaceRequest = options.replaceRequest
}
}
}Sources: src/hono-base.ts:328-347
The request transformation and argument extraction behavior during execution depend on whether explicit options are provided:
| Option Property | Default Behavior | Custom Behavior |
|---|---|---|
replaceRequest | Strips the mounted path prefix from the incoming request URL pathname | Passes the request through a custom MountReplaceRequest function or preserves it unchanged if set to false |
optionHandler | Passes [c.env, executionContext] extracted from the active Context | Invokes the custom MountOptionHandler function and normalizes its return value into an array |
const getOptions: (c: Context) => unknown[] = optionHandler
? (c) => {
const options = optionHandler!(c)
return Array.isArray(options) ? options : [options]
}
: (c) => {
let executionContext: ExecutionContext | undefined = undefined
try {
executionContext = c.executionCtx
} catch {} // Do nothing
return [c.env, executionContext]
}
replaceRequest ||= (() => {
const mergedPath = mergePath(this._basePath, path)
const pathPrefixLength = mergedPath === '/' ? 0 : mergedPath.length
return (request) => {
const url = new URL(request.url)
url.pathname = this.getPath(request).slice(pathPrefixLength) || '/'
return new Request(url, request)
}
})()Sources: src/hono-base.ts:350-370
Once the request transformer and argument extractors are resolved, .mount() registers a wildcard route matching mergePath(path, '*') with METHOD_NAME_ALL, executing the external handler inside a middleware wrapper.
const handler: MiddlewareHandler = async (c, next) => {
const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c))
if (res) {
return res
}
await next()
}
this.#addRoute(METHOD_NAME_ALL, mergePath(path, '*'), handler)
return this
}Sources: src/hono-base.ts:372-383
Application-level error handling
Default Handlers and Customization
Hono provides built-in fallback handlers for unhandled routing misses and runtime exceptions. The default notFoundHandler returns a plain text response with status code 404 and the body 404 Not Found.
const notFoundHandler: NotFoundHandler = (c) => {
return c.text('404 Not Found', 404)
}Sources: src/hono-base.ts:31-33
The default errorHandler inspects caught exceptions to check if they implement a getResponse() method. If present, it directly returns the response provided by the error instance; otherwise, it formats a generic internal error response.
const errorHandler: ErrorHandler = (err, c) => {
if ('getResponse' in err) {
const res = err.getResponse()
return c.newResponse(res.body, res)
}
console.error(err)
return c.text('Internal Server Error', 500)Sources: src/hono-base.ts:35-41
Applications can override these default behaviors by registering custom handlers via the .notFound() and .onError() methods, which update the instance's #notFoundHandler and errorHandler properties and return the modified Hono instance.
onError = (handler: ErrorHandler<E>): Hono<E, S, BasePath, CurrentPath> => {
this.errorHandler = handler
return this
}
/**
* `.notFound()` allows you to customize a Not Found Response.
*
* @see {@link https://hono.dev/docs/api/hono#not-found}
*
* @param {NotFoundHandler} handler - request handler for not-found
* @returns {Hono} changed Hono instance
*
* @example
* ```ts
* app.notFound((c) => {
* return c.text('Custom 404 Message', 404)
* })
* ```
*/
notFound = (handler: NotFoundHandler<E>): Hono<E, S, BasePath, CurrentPath> => {
this.#notFoundHandler = handler
return this
}Sources: src/hono-base.ts:271-294
Exception Dispatching and Error Normalization
During request dispatching in #dispatch(), runtime exceptions thrown within route handlers or middleware are caught and passed to #handleError(). The #handleError() method checks if the thrown value is an instance of Error; if so, it delegates to the registered errorHandler. If the thrown value is not an Error instance, it rethrows the raw value.
#handleError(err: unknown, c: Context<E>): Response | Promise<Response> {
if (err instanceof Error) {
return this.errorHandler(err, c)
}
throw err
}Sources: src/hono-base.ts:399-404
Warning
Non-Error exceptions (such as thrown strings or primitives) bypass the custom errorHandler entirely and propagate out of #handleError(), potentially causing unhandled promise rejections if not caught at the top-level fetch boundary.
When dispatching requests with a single matching handler or via composed middleware chains, exceptions originating from synchronous code execution, asynchronous promise rejections, or unfinalized context states are intercepted and routed through the error handling pipeline.
if (matchResult[0].length === 1) {
let res: ReturnType<H>
try {
res = matchResult[0][0][0][0](c, async () => {
c.res = await this.#notFoundHandler(c)
})
} catch (err) {
return this.#handleError(err, c)
}
return res instanceof Promise
? res
.then(
(resolved: Response | undefined) =>
resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
)
.catch((err: Error) => this.#handleError(err, c))
: (res ?? this.#notFoundHandler(c))
}
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler)
return (async () => {
try {
const context = await composed(c)
if (!context.finalized) {
throw new Error(
'Context is not finalized. Did you forget to return a Response object or `await next()`?'
)
}
return context.res
} catch (err) {
return this.#handleError(err, c)
}
})()
}Sources: src/hono-base.ts:430-466
Fetch interface and runtime execution
Standard Fetch Handler and Request Dispatching
The .fetch() method serves as the primary entry point for Hono applications, adhering to the standard Web Fetch API signature by accepting a Request object, optional environment bindings, and an ExecutionContext. It delegates directly to the private #dispatch() method using request.method and the provided bindings.
fetch: (
request: Request,
Env?: E['Bindings'] | {},
executionCtx?: ExecutionContext
) => Response | Promise<Response> = (request, ...rest) => {
return this.#dispatch(request, rest[1], rest[0], request.method)
}Sources: src/hono-base.ts:479-485
Inside #dispatch(), HTTP HEAD requests are intercepted and handled specially by delegating to a GET dispatch and stripping the response body, returning a new Response with a null body.
if (method === 'HEAD') {
return (async () =>
new Response(null, await this.#dispatch(request, executionCtx, env, 'GET')))()
}Sources: src/hono-base.ts:413-416
For all other methods, path resolution is performed via the configured getPath helper, and the router matches the method against the path to produce a matchResult. A new Context instance is then instantiated with the request, matched route handlers, bindings, and execution context.
const path = this.getPath(request, { env })
const matchResult = this.router.match(method, path)
const c = new Context(request, {
path,
matchResult,
env,
executionCtx,
notFoundHandler: this.#notFoundHandler,
})Sources: src/hono-base.ts:418-427
Note
If a match yields exactly one handler, Hono bypasses the full [[Middleware Composition|compose]] pipeline overhead to execute the handler directly, falling back to the not-found handler if unfinalized.
// Do not `compose` if it has only one handler
if (matchResult[0].length === 1) {
let res: ReturnType<H>
try {
res = matchResult[0][0][0][0](c, async () => {
c.res = await this.#notFoundHandler(c)
})
} catch (err) {
return this.#handleError(err, c)
}
return res instanceof Promise
? res
.then(
(resolved: Response | undefined) =>
resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
)
.catch((err: Error) => this.#handleError(err, c))
: (res ?? this.#notFoundHandler(c))
}Sources: src/hono-base.ts:429-448
When multiple handlers match, #dispatch() invokes compose with the matched handlers, error handler, and not-found handler, ensuring that context finalization invariants are strictly enforced on the resulting execution pipeline.
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler)
return (async () => {
try {
const context = await composed(c)
if (!context.finalized) {
throw new Error(
'Context is not finalized. Did you forget to return a Response object or `await next()`?'
)
}
return context.res
} catch (err) {
return this.#handleError(err, c)
}
})()
}Sources: src/hono-base.ts:450-466
Testing Helpers and Service Worker Integration
Hono provides the .request() method as a utility primarily designed for testing. It accepts Request, string, or URL inputs along with optional request initialization options, environment bindings, and execution context, automatically resolving relative paths against a localhost base if necessary.
request = (
input: Request | string | URL,
requestInit?: RequestInit,
Env?: E['Bindings'] | {},
executionCtx?: ExecutionContext
): Response | Promise<Response> => {
if (input instanceof Request) {
return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx)
}
input = input.toString()
return this.fetch(
new Request(
/^https?:\/\//.test(input) ? input : `http://localhost${mergePath('/', input)}`,
requestInit
),
Env,
executionCtx
)
}Sources: src/hono-base.ts:499-517
For environments adhering to the Service Worker API (such as non-ES module Cloudflare Workers), the .fire() method registers a global fetch event listener via addEventListener, responding to incoming fetch events by invoking #dispatch().
fire = (): void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
addEventListener('fetch', (event: FetchEventLike): void => {
event.respondWith(this.#dispatch(event.request, event, undefined, event.request.method))
})
}Sources: src/hono-base.ts:536-542
Warning
The .fire() method is deprecated and should be avoided in modern ES module runtimes; use fire from hono/service-worker instead.
* @deprecated
* Use `fire` from `hono/service-worker` instead.Sources: src/hono-base.ts:522-523
Related
On This Page
OverviewHono and HonoBase architectureClass Hierarchy and Core SeparationConstructor Options and Router InjectionDefault Router ConfigurationHTTP method handler registrationMethod and Route Registration APIsCustom Method Registration via app.onType Signatures and Handler OverloadsRoute storage and path resolutionInternal Route Structure and Routing TablesPath Normalization and Prefix MergingSub-application routing and basePathScoped basePath Cloning and Instance IsolationComposing Sub-Applications with route()External Framework Mounting with mount()Application-level error handlingDefault Handlers and CustomizationException Dispatching and Error NormalizationFetch interface and runtime executionStandard Fetch Handler and Request DispatchingTesting Helpers and Service Worker IntegrationRelated