Skip to main content
doc0blade47/honodocumentation home
Sign in

Application Core

Last updated Oct 12, 202691% grounded
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 KeyTypeDefault ValuePurpose
routerRouter<[H, RouterRoute]>new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()] })Custom router instance injected into the application.
strictbooleantrueControls whether trailing slashes are strictly matched during path resolution.
getPathGetPath<E>getPath (strict) or getPathNoStrictCustom 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 PropertyDefault BehaviorCustom Behavior
replaceRequestStrips the mounted path prefix from the incoming request URL pathnamePasses the request through a custom MountReplaceRequest function or preserves it unchanged if set to false
optionHandlerPasses [c.env, executionContext] extracted from the active ContextInvokes 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

Was this page helpful?