diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 1efe02f0c..3909f981b 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -2,5 +2,4 @@
 
 - [ ] Add tests
 - [ ] Run tests
-- [ ] `bun denoify` to generate files for Deno
 - [ ] `bun run format:fix && bun run lint:fix` to format the code
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4248e33e1..1165bf03d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,25 +23,15 @@ jobs:
       - run: bun run build
       - run: bun run test
 
-  denoify:
-    name: "Checking if you've done denoify"
+  jsr-dry-run:
+    name: "Checking if it's valid for JSR"
     runs-on: ubuntu-latest
-    env:
-      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     steps:
       - uses: actions/checkout@v4
-      - uses: actions/setup-node@v4
-        with:
-          node-version: '18.x'
-      - uses: oven-sh/setup-bun@v1
+      - uses: denoland/setup-deno@v1
         with:
-          bun-version: '1.0.25'
-      - run: bun install
-      - run: |
-          bun run denoify
-          if [[ `git status --porcelain` ]]; then
-            exit 1
-          fi
+          deno-version: v1.x
+      - run: deno publish --dry-run
 
   deno:
     name: 'Deno'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..dcff75ac9
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,23 @@
+name: ci
+
+on: [push]
+
+jobs:
+  deno:
+    name: publish-to-jsr
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+      id-token: write
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Install deno
+        uses: denoland/setup-deno@v1
+        with:
+          deno-version: v1.x
+
+      - name: Publish to JSR
+        run: deno run -A jsr:@david/publish-on-tag@0.1.3
diff --git a/bun.lockb b/bun.lockb
index 6e1ab1c8d..c1654be2c 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/deno_dist/LICENSE b/deno_dist/LICENSE
deleted file mode 100644
index bd174facc..000000000
--- a/deno_dist/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 - present, Yusuke Wada and Hono contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/deno_dist/README.md b/deno_dist/README.md
deleted file mode 100644
index 1cfe2bde4..000000000
--- a/deno_dist/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-<div align="center">
-  <a href="https://hono.dev">
-    <img src="https://raw.githubusercontent.com/honojs/hono/main/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
-  </a>
-</div>
-
-<hr />
-
-<p align="center">
-<a href="https://hono.dev"><b>Documentation :point_right: hono.dev</b></a><br />
-<i>v4 has been released!</i> <a href="docs/MIGRATION.md">Migration guide</b>
-</p>
-
-<hr />
-
-[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/honojs/hono/ci.yml?branch=main)](https://github.com/honojs/hono/actions)
-[![GitHub](https://img.shields.io/github/license/honojs/hono)](https://github.com/honojs/hono/blob/main/LICENSE)
-[![npm](https://img.shields.io/npm/v/hono)](https://www.npmjs.com/package/hono)
-[![npm](https://img.shields.io/npm/dm/hono)](https://www.npmjs.com/package/hono)
-[![Bundle Size](https://img.shields.io/bundlephobia/min/hono)](https://bundlephobia.com/result?p=hono)
-[![Bundle Size](https://img.shields.io/bundlephobia/minzip/hono)](https://bundlephobia.com/result?p=hono)
-[![npm type definitions](https://img.shields.io/npm/types/hono)](https://www.npmjs.com/package/hono)
-[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
-[![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/main)
-[![Deno badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Flatest-version%2Fx%2Fhono%2Fmod.ts)](https://doc.deno.land/https/deno.land/x/hono/mod.ts)
-[![Discord badge](https://img.shields.io/discord/1011308539819597844?label=Discord&logo=Discord)](https://discord.gg/KMh2eNSdxV)
-
-Hono - _**\[η‚Ž\] means flameπŸ”₯ in Japanese**_ - is a small, simple, and ultrafast web framework for the Edges.
-It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, AWS Lambda, Lambda@Edge, and Node.js.
-
-Fast, but not only fast.
-
-```ts
-import { Hono } from 'hono'
-const app = new Hono()
-
-app.get('/', (c) => c.text('Hono!'))
-
-export default app
-```
-
-## Quick Start
-
-```
-npm create hono@latest
-```
-
-## Features
-
-- **Ultrafast** πŸš€ - The router `RegExpRouter` is really fast. Not using linear loops. Fast.
-- **Lightweight** πŸͺΆ - The `hono/tiny` preset is under 13kB. Hono has zero dependencies and uses only the Web Standard API.
-- **Multi-runtime** 🌍 - Works on Cloudflare Workers, Fastly Compute, Deno, Bun, AWS Lambda, Lambda@Edge, or Node.js. The same code runs on all platforms.
-- **Batteries Included** πŸ”‹ - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
-- **Delightful DX** πŸ˜ƒ - Super clean APIs. First-class TypeScript support. Now, we've got "Types".
-
-## Documentation
-
-The documentation is available on [hono.dev](https://hono.dev).
-
-## Migration
-
-The migration guide is available on [docs/MIGRATION.md](docs/MIGRATION.md).
-
-## Communication
-
-[Twitter](https://twitter.com/honojs) and [Discord channel](https://discord.gg/KMh2eNSdxV) are available.
-
-## Contributing
-
-Contributions Welcome! You can contribute in the following ways.
-
-- Create an Issue - Propose a new feature. Report a bug.
-- Pull Request - Fix a bug and typo. Refactor the code.
-- Create third-party middleware - Instruct below.
-- Share - Share your thoughts on the Blog, Twitter, and others.
-- Make your application - Please try to use Hono.
-
-For more details, see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).
-
-## Contributors
-
-Thanks to [all contributors](https://github.com/honojs/hono/graphs/contributors)!
-
-## Authors
-
-Yusuke Wada <https://github.com/yusukebe>
-
-_RegExpRouter_, _SmartRouter_, _LinearRouter_, and _PatternRouter_ are created by Taku Amano <https://github.com/usualoma>
-
-## License
-
-Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
diff --git a/deno_dist/adapter/deno/conninfo.ts b/deno_dist/adapter/deno/conninfo.ts
deleted file mode 100644
index 7a6f8e7ff..000000000
--- a/deno_dist/adapter/deno/conninfo.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { GetConnInfo } from '../../helper/conninfo/index.ts'
-
-/**
- * Get conninfo with Deno
- * @param c Context
- * @returns ConnInfo
- */
-export const getConnInfo: GetConnInfo = (c) => {
-  const { remoteAddr } = c.env
-  return {
-    remote: {
-      address: remoteAddr.hostname,
-      port: remoteAddr.port,
-      transport: remoteAddr.transport,
-      addressType: 'unknown',
-    },
-  }
-}
diff --git a/deno_dist/adapter/deno/deno.d.ts b/deno_dist/adapter/deno/deno.d.ts
deleted file mode 100644
index d85d8eac6..000000000
--- a/deno_dist/adapter/deno/deno.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-declare namespace Deno {
-  /**
-   * Creates a new directory with the specified path.
-   *
-   * @param path The path to create a directory.
-   * @param options Options for creating a directory.
-   * @returns A promise that resolves when the directory is created.
-   */
-  export function mkdir(path: string, options?: { recursive?: boolean }): Promise<void>
-
-  /**
-   * Write a new file, with the specified path and data.
-   *
-   * @param path The path to the file to write.
-   * @param data The data to write to the file.
-   * @returns A promise that resolves when the file is written.
-   */
-  export function writeFile(path: string, data: Uint8Array): Promise<void>
-
-  export function upgradeWebSocket(req: Request): {
-    response: Response
-    socket: WebSocket
-  }
-}
diff --git a/deno_dist/adapter/deno/index.ts b/deno_dist/adapter/deno/index.ts
deleted file mode 100644
index 54bd109ef..000000000
--- a/deno_dist/adapter/deno/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { serveStatic } from './serve-static.ts'
-export { toSSG, denoFileSystemModule } from './ssg.ts'
-export { upgradeWebSocket } from './websocket.ts'
-export { getConnInfo } from './conninfo.ts'
diff --git a/deno_dist/adapter/deno/serve-static.ts b/deno_dist/adapter/deno/serve-static.ts
deleted file mode 100644
index 2661efb24..000000000
--- a/deno_dist/adapter/deno/serve-static.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { ServeStaticOptions } from '../../middleware/serve-static/index.ts'
-import { serveStatic as baseServeStatic } from '../../middleware/serve-static/index.ts'
-import type { Env, MiddlewareHandler } from '../../types.ts'
-
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-const { open } = Deno
-
-export const serveStatic = <E extends Env = Env>(
-  options: ServeStaticOptions<E>
-): MiddlewareHandler => {
-  return async function serveStatic(c, next) {
-    const getContent = async (path: string) => {
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      let file: any
-      try {
-        file = await open(path)
-      } catch (e) {
-        console.warn(`${e}`)
-      }
-      return file ? file.readable : null
-    }
-    const pathResolve = (path: string) => {
-      return `./${path}`
-    }
-    return baseServeStatic({
-      ...options,
-      getContent,
-      pathResolve,
-    })(c, next)
-  }
-}
diff --git a/deno_dist/adapter/deno/ssg.ts b/deno_dist/adapter/deno/ssg.ts
deleted file mode 100644
index 33924c24e..000000000
--- a/deno_dist/adapter/deno/ssg.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { toSSG as baseToSSG } from '../../helper/ssg/index.ts'
-import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg/index.ts'
-
-/**
- * @experimental
- * `denoFileSystemModule` is an experimental feature.
- * The API might be changed.
- */
-export const denoFileSystemModule: FileSystemModule = {
-  writeFile: async (path, data) => {
-    const uint8Data =
-      typeof data === 'string' ? new TextEncoder().encode(data) : new Uint8Array(data)
-    await Deno.writeFile(path, uint8Data)
-  },
-  mkdir: async (path, options) => {
-    return Deno.mkdir(path, { recursive: options?.recursive ?? false })
-  },
-}
-
-/**
- * @experimental
- * `toSSG` is an experimental feature.
- * The API might be changed.
- */
-export const toSSG: ToSSGAdaptorInterface = async (app, options) => {
-  return baseToSSG(app, denoFileSystemModule, options)
-}
diff --git a/deno_dist/adapter/deno/websocket.ts b/deno_dist/adapter/deno/websocket.ts
deleted file mode 100644
index 77cf62208..000000000
--- a/deno_dist/adapter/deno/websocket.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import type { UpgradeWebSocket, WSContext, WSReadyState } from '../../helper/websocket/index.ts'
-
-export const upgradeWebSocket: UpgradeWebSocket = (createEvents) => async (c, next) => {
-  if (c.req.header('upgrade') !== 'websocket') {
-    return await next()
-  }
-  const { response, socket } = Deno.upgradeWebSocket(c.req.raw)
-
-  const events = await createEvents(c)
-
-  const wsContext: WSContext = {
-    binaryType: 'arraybuffer',
-    close: (code, reason) => socket.close(code, reason),
-    get protocol() {
-      return socket.protocol
-    },
-    raw: socket,
-    get readyState() {
-      return socket.readyState as WSReadyState
-    },
-    url: socket.url ? new URL(socket.url) : null,
-    send: (source) => socket.send(source),
-  }
-  socket.onopen = (evt) => events.onOpen && events.onOpen(evt, wsContext)
-  socket.onmessage = (evt) => events.onMessage && events.onMessage(evt, wsContext)
-  socket.onclose = (evt) => events.onClose && events.onClose(evt, wsContext)
-  socket.onerror = (evt) => events.onError && events.onError(evt, wsContext)
-
-  return response
-}
diff --git a/deno_dist/adapter/netlify/handler.ts b/deno_dist/adapter/netlify/handler.ts
deleted file mode 100644
index 9711d0397..000000000
--- a/deno_dist/adapter/netlify/handler.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import type { Context } from 'https://edge.netlify.com/'
-import type { Hono } from '../../hono.ts'
-
-export type Env = {
-  Bindings: {
-    context: Context
-  }
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const handle = (app: Hono<any, any>) => {
-  return (req: Request, context: Context) => {
-    return app.fetch(req, { context })
-  }
-}
diff --git a/deno_dist/adapter/netlify/index.ts b/deno_dist/adapter/netlify/index.ts
deleted file mode 100644
index 8833f3bef..000000000
--- a/deno_dist/adapter/netlify/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './mod.ts'
diff --git a/deno_dist/adapter/netlify/mod.ts b/deno_dist/adapter/netlify/mod.ts
deleted file mode 100644
index dc56ad619..000000000
--- a/deno_dist/adapter/netlify/mod.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { handle } from './handler.ts'
-export type { Env } from './handler.ts'
diff --git a/deno_dist/client/client.ts b/deno_dist/client/client.ts
deleted file mode 100644
index 632b2c5d1..000000000
--- a/deno_dist/client/client.ts
+++ /dev/null
@@ -1,190 +0,0 @@
-import type { Hono } from '../hono.ts'
-import type { ValidationTargets } from '../types.ts'
-import { serialize } from '../utils/cookie.ts'
-import type { UnionToIntersection } from '../utils/types.ts'
-import type { Callback, Client, ClientRequestOptions } from './types.ts'
-import {
-  deepMerge,
-  mergePath,
-  removeIndexString,
-  replaceUrlParam,
-  replaceUrlProtocol,
-} from './utils.ts'
-
-const createProxy = (callback: Callback, path: string[]) => {
-  const proxy: unknown = new Proxy(() => {}, {
-    get(_obj, key) {
-      if (typeof key !== 'string' || key === 'then') {
-        return undefined
-      }
-      return createProxy(callback, [...path, key])
-    },
-    apply(_1, _2, args) {
-      return callback({
-        path,
-        args,
-      })
-    },
-  })
-  return proxy
-}
-
-class ClientRequestImpl {
-  private url: string
-  private method: string
-  private queryParams: URLSearchParams | undefined = undefined
-  private pathParams: Record<string, string> = {}
-  private rBody: BodyInit | undefined
-  private cType: string | undefined = undefined
-
-  constructor(url: string, method: string) {
-    this.url = url
-    this.method = method
-  }
-  fetch = async (
-    args?: ValidationTargets & {
-      param?: Record<string, string>
-    },
-    opt?: ClientRequestOptions
-  ) => {
-    if (args) {
-      if (args.query) {
-        for (const [k, v] of Object.entries(args.query)) {
-          if (v === undefined) {
-            continue
-          }
-
-          this.queryParams ||= new URLSearchParams()
-          if (Array.isArray(v)) {
-            for (const v2 of v) {
-              this.queryParams.append(k, v2)
-            }
-          } else {
-            this.queryParams.set(k, v)
-          }
-        }
-      }
-
-      if (args.form) {
-        const form = new FormData()
-        for (const [k, v] of Object.entries(args.form)) {
-          form.append(k, v)
-        }
-        this.rBody = form
-      }
-
-      if (args.json) {
-        this.rBody = JSON.stringify(args.json)
-        this.cType = 'application/json'
-      }
-
-      if (args.param) {
-        this.pathParams = args.param
-      }
-    }
-
-    let methodUpperCase = this.method.toUpperCase()
-
-    const headerValues: Record<string, string> = {
-      ...(args?.header ?? {}),
-      ...(typeof opt?.headers === 'function'
-        ? await opt.headers()
-        : opt?.headers
-        ? opt.headers
-        : {}),
-    }
-
-    if (args?.cookie) {
-      const cookies: string[] = []
-      for (const [key, value] of Object.entries(args.cookie)) {
-        cookies.push(serialize(key, value, { path: '/' }))
-      }
-      headerValues['Cookie'] = cookies.join(',')
-    }
-
-    if (this.cType) {
-      headerValues['Content-Type'] = this.cType
-    }
-
-    const headers = new Headers(headerValues ?? undefined)
-    let url = this.url
-
-    url = removeIndexString(url)
-    url = replaceUrlParam(url, this.pathParams)
-
-    if (this.queryParams) {
-      url = url + '?' + this.queryParams.toString()
-    }
-    methodUpperCase = this.method.toUpperCase()
-    const setBody = !(methodUpperCase === 'GET' || methodUpperCase === 'HEAD')
-
-    // Pass URL string to 1st arg for testing with MSW and node-fetch
-    return (opt?.fetch || fetch)(url, {
-      body: setBody ? this.rBody : undefined,
-      method: methodUpperCase,
-      headers: headers,
-      ...opt?.init,
-    })
-  }
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const hc = <T extends Hono<any, any, any>>(
-  baseUrl: string,
-  options?: ClientRequestOptions
-) =>
-  createProxy(function proxyCallback(opts) {
-    const parts = [...opts.path]
-
-    // allow calling .toString() and .valueOf() on the proxy
-    if (parts[parts.length - 1] === 'toString') {
-      if (parts[parts.length - 2] === 'name') {
-        // e.g. hc().somePath.name.toString() -> "somePath"
-        return parts[parts.length - 3] || ''
-      }
-      // e.g. hc().somePath.toString()
-      return proxyCallback.toString()
-    }
-
-    if (parts[parts.length - 1] === 'valueOf') {
-      if (parts[parts.length - 2] === 'name') {
-        // e.g. hc().somePath.name.valueOf() -> "somePath"
-        return parts[parts.length - 3] || ''
-      }
-      // e.g. hc().somePath.valueOf()
-      return proxyCallback
-    }
-
-    let method = ''
-    if (/^\$/.test(parts[parts.length - 1])) {
-      const last = parts.pop()
-      if (last) {
-        method = last.replace(/^\$/, '')
-      }
-    }
-
-    const path = parts.join('/')
-    const url = mergePath(baseUrl, path)
-    if (method === 'url') {
-      if (opts.args[0] && opts.args[0].param) {
-        return new URL(replaceUrlParam(url, opts.args[0].param))
-      }
-      return new URL(url)
-    }
-    if (method === 'ws') {
-      const targetUrl = replaceUrlProtocol(
-        opts.args[0] && opts.args[0].param ? replaceUrlParam(url, opts.args[0].param) : url,
-        'ws'
-      )
-
-      return new WebSocket(targetUrl)
-    }
-
-    const req = new ClientRequestImpl(url, method)
-    if (method) {
-      options ??= {}
-      const args = deepMerge<ClientRequestOptions>(options, { ...(opts.args[1] ?? {}) })
-      return req.fetch(opts.args[0], args)
-    }
-    return req
-  }, []) as UnionToIntersection<Client<T>>
diff --git a/deno_dist/client/index.ts b/deno_dist/client/index.ts
deleted file mode 100644
index 5be1ce977..000000000
--- a/deno_dist/client/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export { hc } from './client.ts'
-export type {
-  InferResponseType,
-  InferRequestType,
-  Fetch,
-  ClientRequestOptions,
-  ClientRequest,
-  ClientResponse,
-} from './types.ts'
diff --git a/deno_dist/client/types.ts b/deno_dist/client/types.ts
deleted file mode 100644
index 0b3c776d0..000000000
--- a/deno_dist/client/types.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import type { Hono } from '../hono.ts'
-import type { Endpoint, ResponseFormat, Schema } from '../types.ts'
-import type { StatusCode, SuccessStatusCode } from '../utils/http-status.ts'
-import type { HasRequiredKeys } from '../utils/types.ts'
-
-type HonoRequest = (typeof Hono.prototype)['request']
-
-export type ClientRequestOptions<T = unknown> = {
-  fetch?: typeof fetch | HonoRequest
-  /**
-   * Standard `RequestInit`, caution that this take highest priority
-   * and could be used to overwrite things that Hono sets for you, like `body | method | headers`.
-   *
-   * If you want to add some headers, use in `headers` instead of `init`
-   */
-  init?: RequestInit
-} & (keyof T extends never
-  ? {
-      headers?:
-        | Record<string, string>
-        | (() => Record<string, string> | Promise<Record<string, string>>)
-    }
-  : {
-      headers: T | (() => T | Promise<T>)
-    })
-
-export type ClientRequest<S extends Schema> = {
-  [M in keyof S]: S[M] extends Endpoint & { input: infer R }
-    ? R extends object
-      ? HasRequiredKeys<R> extends true
-        ? (args: R, options?: ClientRequestOptions) => Promise<ClientResponseOfEndpoint<S[M]>>
-        : (args?: R, options?: ClientRequestOptions) => Promise<ClientResponseOfEndpoint<S[M]>>
-      : never
-    : never
-} & {
-  $url: (
-    arg?: S[keyof S] extends { input: infer R }
-      ? R extends { param: infer P }
-        ? { param: P }
-        : {}
-      : {}
-  ) => URL
-} & (S['$get'] extends { outputFormat: 'ws' }
-    ? S['$get'] extends { input: infer I }
-      ? {
-          $ws: (args?: I) => WebSocket
-        }
-      : {}
-    : {})
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type BlankRecordToNever<T> = T extends any
-  ? T extends null
-    ? null
-    : keyof T extends never
-    ? never
-    : T
-  : never
-
-type ClientResponseOfEndpoint<T extends Endpoint = Endpoint> = T extends {
-  output: infer O
-  outputFormat: infer F
-  status: infer S
-}
-  ? ClientResponse<O, S extends number ? S : never, F extends ResponseFormat ? F : never>
-  : never
-
-export interface ClientResponse<
-  T,
-  U extends number = StatusCode,
-  F extends ResponseFormat = ResponseFormat
-> extends globalThis.Response {
-  readonly body: ReadableStream | null
-  readonly bodyUsed: boolean
-  ok: U extends SuccessStatusCode
-    ? true
-    : U extends Exclude<StatusCode, SuccessStatusCode>
-    ? false
-    : boolean
-  status: U
-  statusText: string
-  headers: Headers
-  url: string
-  redirect(url: string, status: number): Response
-  clone(): Response
-  json(): F extends 'text'
-    ? Promise<never>
-    : F extends 'json'
-    ? Promise<BlankRecordToNever<T>>
-    : Promise<unknown>
-  text(): F extends 'text' ? (T extends string ? Promise<T> : Promise<never>) : Promise<string>
-  blob(): Promise<Blob>
-  formData(): Promise<FormData>
-  arrayBuffer(): Promise<ArrayBuffer>
-}
-
-export interface Response extends ClientResponse<unknown> {}
-
-export type Fetch<T> = (
-  args?: InferRequestType<T>,
-  opt?: ClientRequestOptions
-) => Promise<ClientResponseOfEndpoint<InferEndpointType<T>>>
-
-type InferEndpointType<T> = T extends (
-  args: infer R,
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  options: any | undefined
-) => Promise<infer U>
-  ? U extends ClientResponse<infer O, infer S, infer F>
-    ? { input: NonNullable<R>; output: O; outputFormat: F; status: S } extends Endpoint
-      ? { input: NonNullable<R>; output: O; outputFormat: F; status: S }
-      : never
-    : never
-  : never
-
-export type InferResponseType<T, U extends StatusCode = StatusCode> = InferResponseTypeFromEndpoint<
-  InferEndpointType<T>,
-  U
->
-
-type InferResponseTypeFromEndpoint<T extends Endpoint, U extends StatusCode> = T extends {
-  output: infer O
-  status: infer S
-}
-  ? S extends U
-    ? O
-    : never
-  : never
-
-export type InferRequestType<T> = T extends (
-  args: infer R,
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  options: any | undefined
-) => Promise<ClientResponse<unknown>>
-  ? NonNullable<R>
-  : never
-
-export type InferRequestOptionsType<T> = T extends (
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  args: any,
-  options: infer R
-) => Promise<ClientResponse<unknown>>
-  ? NonNullable<R>
-  : never
-
-type PathToChain<
-  Path extends string,
-  E extends Schema,
-  Original extends string = ''
-> = Path extends `/${infer P}`
-  ? PathToChain<P, E, Path>
-  : Path extends `${infer P}/${infer R}`
-  ? { [K in P]: PathToChain<R, E, Original> }
-  : {
-      [K in Path extends '' ? 'index' : Path]: ClientRequest<
-        E extends Record<string, unknown> ? E[Original] : never
-      >
-    }
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type Client<T> = T extends Hono<any, infer S, any>
-  ? S extends Record<infer K, Schema>
-    ? K extends string
-      ? PathToChain<K, S>
-      : never
-    : never
-  : never
-
-export type Callback = (opts: CallbackOptions) => unknown
-
-interface CallbackOptions {
-  path: string[]
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  args: any[]
-}
-
-export type ObjectType<T = unknown> = {
-  [key: string]: T
-}
diff --git a/deno_dist/client/utils.ts b/deno_dist/client/utils.ts
deleted file mode 100644
index c9b43bcbb..000000000
--- a/deno_dist/client/utils.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { ObjectType } from './types.ts'
-
-export const mergePath = (base: string, path: string) => {
-  base = base.replace(/\/+$/, '')
-  base = base + '/'
-  path = path.replace(/^\/+/, '')
-  return base + path
-}
-
-export const replaceUrlParam = (urlString: string, params: Record<string, string>) => {
-  for (const [k, v] of Object.entries(params)) {
-    const reg = new RegExp('/:' + k + '(?:{[^/]+})?')
-    urlString = urlString.replace(reg, `/${v}`)
-  }
-  return urlString
-}
-
-export const replaceUrlProtocol = (urlString: string, protocol: 'ws' | 'http') => {
-  switch (protocol) {
-    case 'ws':
-      return urlString.replace(/^http/, 'ws')
-    case 'http':
-      return urlString.replace(/^ws/, 'http')
-  }
-}
-
-export const removeIndexString = (urlSting: string) => {
-  if (/^https?:\/\/[^\/]+?\/index$/.test(urlSting)) {
-    return urlSting.replace(/\/index$/, '/')
-  }
-  return urlSting.replace(/\/index$/, '')
-}
-
-function isObject(item: unknown): item is ObjectType {
-  return typeof item === 'object' && item !== null && !Array.isArray(item)
-}
-
-export function deepMerge<T>(target: T, source: Record<string, unknown>): T {
-  if (!isObject(target) && !isObject(source)) {
-    return source as T
-  }
-  const merged = { ...target } as ObjectType<T>
-
-  for (const key in source) {
-    const value = source[key]
-    if (isObject(merged[key]) && isObject(value)) {
-      merged[key] = deepMerge(merged[key], value)
-    } else {
-      merged[key] = value as T[keyof T] & T
-    }
-  }
-
-  return merged as T
-}
diff --git a/deno_dist/compose.ts b/deno_dist/compose.ts
deleted file mode 100644
index b03903a23..000000000
--- a/deno_dist/compose.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { Context } from './context.ts'
-import type { ParamIndexMap, Params } from './router.ts'
-import type { Env, NotFoundHandler, ErrorHandler } from './types.ts'
-
-interface ComposeContext {
-  finalized: boolean
-  res: unknown
-}
-
-// Based on the code in the MIT licensed `koa-compose` package.
-export const compose = <C extends ComposeContext, E extends Env = Env>(
-  middleware: [[Function, unknown], ParamIndexMap | Params][],
-  onError?: ErrorHandler<E>,
-  onNotFound?: NotFoundHandler<E>
-) => {
-  return (context: C, next?: Function) => {
-    let index = -1
-    return dispatch(0)
-
-    async function dispatch(i: number): Promise<C> {
-      if (i <= index) {
-        throw new Error('next() called multiple times')
-      }
-      index = i
-
-      let res
-      let isError = false
-      let handler
-
-      if (middleware[i]) {
-        handler = middleware[i][0][0]
-        if (context instanceof Context) {
-          context.req.routeIndex = i
-        }
-      } else {
-        handler = (i === middleware.length && next) || undefined
-      }
-
-      if (!handler) {
-        if (context instanceof Context && context.finalized === false && onNotFound) {
-          res = await onNotFound(context)
-        }
-      } else {
-        try {
-          res = await handler(context, () => {
-            return dispatch(i + 1)
-          })
-        } catch (err) {
-          if (err instanceof Error && context instanceof Context && onError) {
-            context.error = err
-            res = await onError(err, context)
-            isError = true
-          } else {
-            throw err
-          }
-        }
-      }
-
-      if (res && (context.finalized === false || isError)) {
-        context.res = res
-      }
-      return context
-    }
-  }
-}
diff --git a/deno_dist/context.ts b/deno_dist/context.ts
deleted file mode 100644
index ac86abada..000000000
--- a/deno_dist/context.ts
+++ /dev/null
@@ -1,576 +0,0 @@
-import type { HonoRequest } from './request.ts'
-import type { Env, FetchEventLike, Input, NotFoundHandler, TypedResponse } from './types.ts'
-import { HtmlEscapedCallbackPhase, resolveCallback } from './utils/html.ts'
-import type { RedirectStatusCode, StatusCode } from './utils/http-status.ts'
-import type { IsAny, JSONParsed, JSONValue, Simplify } from './utils/types.ts'
-
-type HeaderRecord = Record<string, string | string[]>
-export type Data = string | ArrayBuffer | ReadableStream
-
-export interface ExecutionContext {
-  waitUntil(promise: Promise<unknown>): void
-  passThroughOnException(): void
-}
-
-export interface ContextVariableMap {}
-
-export interface ContextRenderer {}
-interface DefaultRenderer {
-  (content: string | Promise<string>): Response | Promise<Response>
-}
-
-export type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer
-export type PropsForRenderer = [...Required<Parameters<Renderer>>] extends [unknown, infer Props]
-  ? Props
-  : unknown
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type Layout<T = Record<string, any>> = (props: T) => any
-
-interface Get<E extends Env> {
-  <Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key]
-  <Key extends keyof E['Variables']>(key: Key): E['Variables'][Key]
-}
-
-interface Set<E extends Env> {
-  <Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void
-  <Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void
-}
-
-interface NewResponse {
-  (data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
-  (data: Data | null, init?: ResponseInit): Response
-}
-
-interface BodyRespond extends NewResponse {}
-
-interface TextRespond {
-  <T extends string, U extends StatusCode>(text: T, status?: U, headers?: HeaderRecord): Response &
-    TypedResponse<T, U, 'text'>
-  <T extends string, U extends StatusCode>(text: T, init?: ResponseInit): Response &
-    TypedResponse<T, U, 'text'>
-}
-
-interface JSONRespond {
-  <T extends JSONValue | Simplify<unknown>, U extends StatusCode>(
-    object: T,
-    status?: U,
-    headers?: HeaderRecord
-  ): Response &
-    TypedResponse<
-      Simplify<T> extends JSONValue
-        ? JSONValue extends Simplify<T>
-          ? never
-          : JSONParsed<T>
-        : never,
-      U,
-      'json'
-    >
-  <T extends JSONValue | Simplify<unknown>, U extends StatusCode>(
-    object: Simplify<T> extends JSONValue ? T : Simplify<T>,
-    init?: ResponseInit
-  ): Response &
-    TypedResponse<
-      Simplify<T> extends JSONValue
-        ? JSONValue extends Simplify<T>
-          ? never
-          : JSONParsed<T>
-        : never,
-      U,
-      'json'
-    >
-}
-
-interface HTMLRespond {
-  (html: string | Promise<string>, status?: StatusCode, headers?: HeaderRecord):
-    | Response
-    | Promise<Response>
-  (html: string | Promise<string>, init?: ResponseInit): Response | Promise<Response>
-}
-
-type ContextOptions<E extends Env> = {
-  env: E['Bindings']
-  executionCtx?: FetchEventLike | ExecutionContext | undefined
-  notFoundHandler?: NotFoundHandler<E>
-}
-
-export const TEXT_PLAIN = 'text/plain; charset=UTF-8'
-
-const setHeaders = (headers: Headers, map: Record<string, string> = {}) => {
-  Object.entries(map).forEach(([key, value]) => headers.set(key, value))
-  return headers
-}
-
-export class Context<
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  E extends Env = any,
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  P extends string = any,
-  I extends Input = {}
-> {
-  /**
-   * `.req` is the instance of {@link HonoRequest}.
-   */
-  req: HonoRequest<P, I['out']>
-  /**
-   * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
-   * @example
-   * ```ts
-   * // Environment object for Cloudflare Workers
-   * app.get('*', async c => {
-   *   const counter = c.env.COUNTER
-   * })
-   * ```
-   * @see https://hono.dev/api/context#env
-   */
-  env: E['Bindings'] = {}
-  private _var: E['Variables'] = {}
-  finalized: boolean = false
-  /**
-   * `.error` can get the error object from the middleware if the Handler throws an error.
-   * @example
-   * ```ts
-   * app.use('*', async (c, next) => {
-   *   await next()
-   *   if (c.error) {
-   *     // do something...
-   *   }
-   * })
-   * ```
-   * @see https://hono.dev/api/context#error
-   */
-  error: Error | undefined = undefined
-
-  #status: StatusCode = 200
-  #executionCtx: FetchEventLike | ExecutionContext | undefined
-  #headers: Headers | undefined = undefined
-  #preparedHeaders: Record<string, string> | undefined = undefined
-  #res: Response | undefined
-  #isFresh = true
-  private layout: Layout<PropsForRenderer & { Layout: Layout }> | undefined = undefined
-  private renderer: Renderer = (content: string | Promise<string>) => this.html(content)
-  private notFoundHandler: NotFoundHandler<E> = () => new Response()
-
-  constructor(req: HonoRequest<P, I['out']>, options?: ContextOptions<E>) {
-    this.req = req
-    if (options) {
-      this.#executionCtx = options.executionCtx
-      this.env = options.env
-      if (options.notFoundHandler) {
-        this.notFoundHandler = options.notFoundHandler
-      }
-    }
-  }
-
-  /**
-   * @see https://hono.dev/api/context#event
-   */
-  get event(): FetchEventLike {
-    if (this.#executionCtx && 'respondWith' in this.#executionCtx) {
-      return this.#executionCtx
-    } else {
-      throw Error('This context has no FetchEvent')
-    }
-  }
-
-  /**
-   * @see https://hono.dev/api/context#executionctx
-   */
-  get executionCtx(): ExecutionContext {
-    if (this.#executionCtx) {
-      return this.#executionCtx as ExecutionContext
-    } else {
-      throw Error('This context has no ExecutionContext')
-    }
-  }
-
-  /**
-   * @see https://hono.dev/api/context#res
-   */
-  get res(): Response {
-    this.#isFresh = false
-    return (this.#res ||= new Response('404 Not Found', { status: 404 }))
-  }
-
-  set res(_res: Response | undefined) {
-    this.#isFresh = false
-    if (this.#res && _res) {
-      this.#res.headers.delete('content-type')
-      for (const [k, v] of this.#res.headers.entries()) {
-        if (k === 'set-cookie') {
-          const cookies = this.#res.headers.getSetCookie()
-          _res.headers.delete('set-cookie')
-          for (const cookie of cookies) {
-            _res.headers.append('set-cookie', cookie)
-          }
-        } else {
-          _res.headers.set(k, v)
-        }
-      }
-    }
-    this.#res = _res
-    this.finalized = true
-  }
-
-  /**
-   * `.render()` can create a response within a layout.
-   * @example
-   * ```ts
-   * app.get('/', (c) => {
-   *   return c.render('Hello!')
-   * })
-   * ```
-   * @see https://hono.dev/api/context#render-setrenderer
-   */
-  render: Renderer = (...args) => this.renderer(...args)
-
-  setLayout = (
-    layout: Layout<PropsForRenderer & { Layout: Layout }>
-  ): Layout<
-    PropsForRenderer & {
-      Layout: Layout
-    }
-  > => (this.layout = layout)
-
-  getLayout = () => this.layout
-
-  /**
-   * `.setRenderer()` can set the layout in the custom middleware.
-   * @example
-   * ```tsx
-   * app.use('*', async (c, next) => {
-   *   c.setRenderer((content) => {
-   *     return c.html(
-   *       <html>
-   *         <body>
-   *           <p>{content}</p>
-   *         </body>
-   *       </html>
-   *     )
-   *   })
-   *   await next()
-   * })
-   * ```
-   * @see https://hono.dev/api/context#render-setrenderer
-   */
-  setRenderer = (renderer: Renderer) => {
-    this.renderer = renderer
-  }
-
-  /**
-   * `.header()` can set headers.
-   * @example
-   * ```ts
-   * app.get('/welcome', (c) => {
-   *   // Set headers
-   *   c.header('X-Message', 'Hello!')
-   *   c.header('Content-Type', 'text/plain')
-   *
-   *   return c.body('Thank you for coming')
-   * })
-   * ```
-   * @see https://hono.dev/api/context#body
-   */
-  header = (name: string, value: string | undefined, options?: { append?: boolean }): void => {
-    // Clear the header
-    if (value === undefined) {
-      if (this.#headers) {
-        this.#headers.delete(name)
-      } else if (this.#preparedHeaders) {
-        delete this.#preparedHeaders[name.toLocaleLowerCase()]
-      }
-      if (this.finalized) {
-        this.res.headers.delete(name)
-      }
-      return
-    }
-
-    if (options?.append) {
-      if (!this.#headers) {
-        this.#isFresh = false
-        this.#headers = new Headers(this.#preparedHeaders)
-        this.#preparedHeaders = {}
-      }
-      this.#headers.append(name, value)
-    } else {
-      if (this.#headers) {
-        this.#headers.set(name, value)
-      } else {
-        this.#preparedHeaders ??= {}
-        this.#preparedHeaders[name.toLowerCase()] = value
-      }
-    }
-
-    if (this.finalized) {
-      if (options?.append) {
-        this.res.headers.append(name, value)
-      } else {
-        this.res.headers.set(name, value)
-      }
-    }
-  }
-
-  status = (status: StatusCode): void => {
-    this.#isFresh = false
-    this.#status = status
-  }
-
-  /**
-   * `.set()` can set the value specified by the key.
-   * @example
-   * ```ts
-   * app.use('*', async (c, next) => {
-   *   c.set('message', 'Hono is cool!!')
-   *   await next()
-   * })
-   * ```
-   * @see https://hono.dev/api/context#set-get
-```
-   */
-  set: Set<E> = (key: string, value: unknown) => {
-    this._var ??= {}
-    this._var[key as string] = value
-  }
-
-  /**
-   * `.get()` can use the value specified by the key.
-   * @example
-   * ```ts
-   * app.get('/', (c) => {
-   *   const message = c.get('message')
-   *   return c.text(`The message is "${message}"`)
-   * })
-   * ```
-   * @see https://hono.dev/api/context#set-get
-   */
-  get: Get<E> = (key: string) => {
-    return this._var ? this._var[key] : undefined
-  }
-
-  /**
-   * `.var` can access the value of a variable.
-   * @example
-   * ```ts
-   * const result = c.var.client.oneMethod()
-   * ```
-   * @see https://hono.dev/api/context#var
-   */
-  // c.var.propName is a read-only
-  get var(): Readonly<
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    ContextVariableMap & (IsAny<E['Variables']> extends true ? Record<string, any> : E['Variables'])
-  > {
-    return { ...this._var } as never
-  }
-
-  newResponse: NewResponse = (
-    data: Data | null,
-    arg?: StatusCode | ResponseInit,
-    headers?: HeaderRecord
-  ): Response => {
-    // Optimized
-    if (this.#isFresh && !headers && !arg && this.#status === 200) {
-      return new Response(data, {
-        headers: this.#preparedHeaders,
-      })
-    }
-
-    if (arg && typeof arg !== 'number') {
-      const header = new Headers(arg.headers)
-      if (this.#headers) {
-        // If the header is set by c.header() and arg.headers, c.header() will be prioritized.
-        this.#headers.forEach((v, k) => {
-          if (k === 'set-cookie') {
-            header.append(k, v)
-          } else {
-            header.set(k, v)
-          }
-        })
-      }
-      const headers = setHeaders(header, this.#preparedHeaders)
-      return new Response(data, {
-        headers,
-        status: arg.status ?? this.#status,
-      })
-    }
-
-    const status = typeof arg === 'number' ? arg : this.#status
-    this.#preparedHeaders ??= {}
-
-    this.#headers ??= new Headers()
-    setHeaders(this.#headers, this.#preparedHeaders)
-
-    if (this.#res) {
-      this.#res.headers.forEach((v, k) => {
-        if (k === 'set-cookie') {
-          this.#headers?.append(k, v)
-        } else {
-          this.#headers?.set(k, v)
-        }
-      })
-      setHeaders(this.#headers, this.#preparedHeaders)
-    }
-
-    headers ??= {}
-    for (const [k, v] of Object.entries(headers)) {
-      if (typeof v === 'string') {
-        this.#headers.set(k, v)
-      } else {
-        this.#headers.delete(k)
-        for (const v2 of v) {
-          this.#headers.append(k, v2)
-        }
-      }
-    }
-
-    return new Response(data, {
-      status,
-      headers: this.#headers,
-    })
-  }
-
-  /**
-   * `.body()` can return the HTTP response.
-   * You can set headers with `.header()` and set HTTP status code with `.status`.
-   * This can also be set in `.text()`, `.json()` and so on.
-   * @example
-   * ```ts
-   * app.get('/welcome', (c) => {
-   *   // Set headers
-   *   c.header('X-Message', 'Hello!')
-   *   c.header('Content-Type', 'text/plain')
-   *   // Set HTTP status code
-   *   c.status(201)
-   *
-   *   // Return the response body
-   *   return c.body('Thank you for coming')
-   * })
-   * ```
-   * @see https://hono.dev/api/context#body
-   */
-  body: BodyRespond = (
-    data: Data | null,
-    arg?: StatusCode | ResponseInit,
-    headers?: HeaderRecord
-  ): Response => {
-    return typeof arg === 'number'
-      ? this.newResponse(data, arg, headers)
-      : this.newResponse(data, arg)
-  }
-
-  /**
-   * `.text()` can render text as `Content-Type:text/plain`.
-   * @example
-   * ```ts
-   * app.get('/say', (c) => {
-   *   return c.text('Hello!')
-   * })
-   * ```
-   * @see https://hono.dev/api/context#text
-   */
-  text: TextRespond = (
-    text: string,
-    arg?: StatusCode | ResponseInit,
-    headers?: HeaderRecord
-  ): ReturnType<TextRespond> => {
-    // If the header is empty, return Response immediately.
-    // Content-Type will be added automatically as `text/plain`.
-    if (!this.#preparedHeaders) {
-      if (this.#isFresh && !headers && !arg) {
-        // @ts-expect-error `Response` due to missing some types-only keys
-        return new Response(text)
-      }
-      this.#preparedHeaders = {}
-    }
-    this.#preparedHeaders['content-type'] = TEXT_PLAIN
-    // @ts-expect-error `Response` due to missing some types-only keys
-    return typeof arg === 'number'
-      ? this.newResponse(text, arg, headers)
-      : this.newResponse(text, arg)
-  }
-
-  /**
-   * `.json()` can render JSON as `Content-Type:application/json`.
-   * @example
-   * ```ts
-   * app.get('/api', (c) => {
-   *   return c.json({ message: 'Hello!' })
-   * })
-   * ```
-   * @see https://hono.dev/api/context#json
-   */
-  json: JSONRespond = <T extends JSONValue | Simplify<unknown>, U extends StatusCode>(
-    object: T,
-    arg?: U | ResponseInit,
-    headers?: HeaderRecord
-  ): ReturnType<JSONRespond> => {
-    const body = JSON.stringify(object)
-    this.#preparedHeaders ??= {}
-    this.#preparedHeaders['content-type'] = 'application/json; charset=UTF-8'
-    /* eslint-disable @typescript-eslint/no-explicit-any */
-    return (
-      typeof arg === 'number' ? this.newResponse(body, arg, headers) : this.newResponse(body, arg)
-    ) as any
-  }
-
-  html: HTMLRespond = (
-    html: string | Promise<string>,
-    arg?: StatusCode | ResponseInit,
-    headers?: HeaderRecord
-  ): Response | Promise<Response> => {
-    this.#preparedHeaders ??= {}
-    this.#preparedHeaders['content-type'] = 'text/html; charset=UTF-8'
-
-    if (typeof html === 'object') {
-      if (!(html instanceof Promise)) {
-        html = (html as string).toString() // HtmlEscapedString object to string
-      }
-      if ((html as string | Promise<string>) instanceof Promise) {
-        return (html as unknown as Promise<string>)
-          .then((html) => resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}))
-          .then((html) => {
-            return typeof arg === 'number'
-              ? this.newResponse(html, arg, headers)
-              : this.newResponse(html, arg)
-          })
-      }
-    }
-
-    return typeof arg === 'number'
-      ? this.newResponse(html as string, arg, headers)
-      : this.newResponse(html as string, arg)
-  }
-
-  /**
-   * `.redirect()` can Redirect, default status code is 302.
-   * @example
-   * ```ts
-   * app.get('/redirect', (c) => {
-   *   return c.redirect('/')
-   * })
-   * app.get('/redirect-permanently', (c) => {
-   *   return c.redirect('/', 301)
-   * })
-   * ```
-   * @see https://hono.dev/api/context#redirect
-   */
-  redirect = (location: string, status: RedirectStatusCode = 302): Response => {
-    this.#headers ??= new Headers()
-    this.#headers.set('Location', location)
-    return this.newResponse(null, status)
-  }
-
-  /**
-   * `.notFound()` can return the Not Found Response.
-   * @example
-   * ```ts
-   * app.get('/notfound', (c) => {
-   *   return c.notFound()
-   * })
-   * ```
-   * @see https://hono.dev/api/context#notfound
-   */
-  notFound = (): Response | Promise<Response> => {
-    return this.notFoundHandler(this)
-  }
-}
diff --git a/deno_dist/helper.ts b/deno_dist/helper.ts
deleted file mode 100644
index a3dd6d265..000000000
--- a/deno_dist/helper.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file is for Deno to import helpers from `hono/helper.ts`.
-export * from './helper/accepts/index.ts'
-export * from './helper/adapter/index.ts'
-export * from './helper/cookie/index.ts'
-export * from './helper/css/index.ts'
-export * from './helper/factory/index.ts'
-export * from './helper/html/index.ts'
-export * from './helper/streaming/index.ts'
-export * from './helper/testing/index.ts'
-export * from './helper/dev/index.ts'
-export * from './adapter/deno/ssg.ts'
-export * from './adapter/deno/websocket.ts'
-export { decode as jwtDecode, sign as jwtSign, verify as jwtVerify } from './middleware/jwt/index.ts'
diff --git a/deno_dist/helper/accepts/accepts.ts b/deno_dist/helper/accepts/accepts.ts
deleted file mode 100644
index bdf64fd93..000000000
--- a/deno_dist/helper/accepts/accepts.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import type { Context } from '../../context.ts'
-
-export type AcceptHeader =
-  | 'Accept'
-  | 'Accept-Charset'
-  | 'Accept-Encoding'
-  | 'Accept-Language'
-  | 'Accept-Patch'
-  | 'Accept-Post'
-  | 'Accept-Ranges'
-
-export interface Accept {
-  type: string
-  params: Record<string, string>
-  q: number
-}
-
-export interface acceptsConfig {
-  header: AcceptHeader
-  supports: string[]
-  default: string
-}
-
-export interface acceptsOptions extends acceptsConfig {
-  match?: (accepts: Accept[], config: acceptsConfig) => string
-}
-
-export const parseAccept = (acceptHeader: string): Accept[] => {
-  // Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-  const accepts = acceptHeader.split(',') // ['text/html', 'application/xhtml+xml', 'application/xml;q=0.9', 'image/webp', '*/*;q=0.8']
-  return accepts.map((accept) => {
-    const [type, ...params] = accept.trim().split(';') // ['application/xml', 'q=0.9']
-    const q = params.find((param) => param.startsWith('q=')) // 'q=0.9'
-    return {
-      type,
-      params: params.reduce((acc, param) => {
-        const [key, value] = param.split('=')
-        return { ...acc, [key.trim()]: value.trim() }
-      }, {}),
-      q: q ? parseFloat(q.split('=')[1]) : 1,
-    }
-  })
-}
-
-export const defaultMatch = (accepts: Accept[], config: acceptsConfig): string => {
-  const { supports, default: defaultSupport } = config
-  const accept = accepts.sort((a, b) => b.q - a.q).find((accept) => supports.includes(accept.type))
-  return accept ? accept.type : defaultSupport
-}
-
-/**
- * Match the accept header with the given options.
- * @example
- * ```ts
- * app.get('/users', (c) => {
- *   const lang = accepts(c, {
- *     header: 'Accept-Language',
- *     supports: ['en', 'zh'],
- *     default: 'en',
- *   })
- * })
- * ```
- */
-export const accepts = (c: Context, options: acceptsOptions): string => {
-  const acceptHeader = c.req.header(options.header)
-  if (!acceptHeader) {
-    return options.default
-  }
-  const accepts = parseAccept(acceptHeader)
-  const match = options.match || defaultMatch
-
-  return match(accepts, options)
-}
diff --git a/deno_dist/helper/accepts/index.ts b/deno_dist/helper/accepts/index.ts
deleted file mode 100644
index e7723d2af..000000000
--- a/deno_dist/helper/accepts/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { accepts } from './accepts.ts'
diff --git a/deno_dist/helper/adapter/index.ts b/deno_dist/helper/adapter/index.ts
deleted file mode 100644
index c9e46833a..000000000
--- a/deno_dist/helper/adapter/index.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import type { Context } from '../../context.ts'
-
-export type Runtime = 'node' | 'deno' | 'bun' | 'workerd' | 'fastly' | 'edge-light' | 'other'
-
-export const env = <T extends Record<string, unknown>, C extends Context = Context<{}>>(
-  c: C,
-  runtime?: Runtime
-): T & C['env'] => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const global = globalThis as any
-  const globalEnv = global?.process?.env as T
-
-  runtime ??= getRuntimeKey()
-
-  const runtimeEnvHandlers: Record<string, () => T> = {
-    bun: () => globalEnv,
-    node: () => globalEnv,
-    'edge-light': () => globalEnv,
-    deno: () => {
-      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
-      // @ts-ignore
-      return Deno.env.toObject() as T
-    },
-    workerd: () => c.env,
-    // On Fastly Compute, you can use the ConfigStore to manage user-defined data.
-    fastly: () => ({} as T),
-    other: () => ({} as T),
-  }
-
-  return runtimeEnvHandlers[runtime]()
-}
-
-export const getRuntimeKey = (): Runtime => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const global = globalThis as any
-
-  if (global?.Deno !== undefined) {
-    return 'deno'
-  }
-  if (global?.Bun !== undefined) {
-    return 'bun'
-  }
-  if (typeof global?.WebSocketPair === 'function') {
-    return 'workerd'
-  }
-  if (typeof global?.EdgeRuntime === 'string') {
-    return 'edge-light'
-  }
-  if (global?.fastly !== undefined) {
-    return 'fastly'
-  }
-  if (global?.process?.release?.name === 'node') {
-    return 'node'
-  }
-
-  return 'other'
-}
diff --git a/deno_dist/helper/conninfo/index.ts b/deno_dist/helper/conninfo/index.ts
deleted file mode 100644
index f2341e8b0..000000000
--- a/deno_dist/helper/conninfo/index.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import type { Context } from '../../context.ts'
-
-export type AddressType = 'IPv6' | 'IPv4' | 'unknown'
-
-export type NetAddrInfo = {
-  /**
-   * Transport protocol type
-   */
-  transport?: 'tcp' | 'udp'
-  /**
-   * Transport port number
-   */
-  port?: number
-
-  address?: string
-  addressType?: AddressType
-} & (
-  | {
-      /**
-       * Host name such as IP Addr
-       */
-      address: string
-
-      /**
-       * Host name type
-       */
-      addressType: AddressType
-    }
-  | {}
-)
-
-/**
- * HTTP Connection infomation
- */
-export interface ConnInfo {
-  /**
-   * Remote infomation
-   */
-  remote: NetAddrInfo
-}
-
-/**
- * Helper type
- */
-export type GetConnInfo = (c: Context) => ConnInfo
diff --git a/deno_dist/helper/cookie/index.ts b/deno_dist/helper/cookie/index.ts
deleted file mode 100644
index 7c3840fac..000000000
--- a/deno_dist/helper/cookie/index.ts
+++ /dev/null
@@ -1,125 +0,0 @@
-import type { Context } from '../../context.ts'
-import { parse, parseSigned, serialize, serializeSigned } from '../../utils/cookie.ts'
-import type { CookieOptions, Cookie, SignedCookie, CookiePrefixOptions } from '../../utils/cookie.ts'
-
-interface GetCookie {
-  (c: Context, key: string): string | undefined
-  (c: Context): Cookie
-  (c: Context, key: string, prefixOptions: CookiePrefixOptions): string | undefined
-}
-
-interface GetSignedCookie {
-  (c: Context, secret: string | BufferSource, key: string): Promise<string | undefined | false>
-  (c: Context, secret: string): Promise<SignedCookie>
-  (
-    c: Context,
-    secret: string | BufferSource,
-    key: string,
-    prefixOptions: CookiePrefixOptions
-  ): Promise<string | undefined | false>
-}
-
-export const getCookie: GetCookie = (c, key?, prefix?: CookiePrefixOptions) => {
-  const cookie = c.req.raw.headers.get('Cookie')
-  if (typeof key === 'string') {
-    if (!cookie) {
-      return undefined
-    }
-    let finalKey = key
-    if (prefix === 'secure') {
-      finalKey = '__Secure-' + key
-    } else if (prefix === 'host') {
-      finalKey = '__Host-' + key
-    }
-    const obj = parse(cookie, finalKey)
-    return obj[finalKey]
-  }
-  if (!cookie) {
-    return {}
-  }
-  const obj = parse(cookie)
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  return obj as any
-}
-
-export const getSignedCookie: GetSignedCookie = async (
-  c,
-  secret,
-  key?,
-  prefix?: CookiePrefixOptions
-) => {
-  const cookie = c.req.raw.headers.get('Cookie')
-  if (typeof key === 'string') {
-    if (!cookie) {
-      return undefined
-    }
-    let finalKey = key
-    if (prefix === 'secure') {
-      finalKey = '__Secure-' + key
-    } else if (prefix === 'host') {
-      finalKey = '__Host-' + key
-    }
-    const obj = await parseSigned(cookie, secret, finalKey)
-    return obj[finalKey]
-  }
-  if (!cookie) {
-    return {}
-  }
-  const obj = await parseSigned(cookie, secret)
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  return obj as any
-}
-
-export const setCookie = (c: Context, name: string, value: string, opt?: CookieOptions): void => {
-  // Cookie names prefixed with __Secure- can be used only if they are set with the secure attribute.
-  // Cookie names prefixed with __Host- can be used only if they are set with the secure attribute, must have a path of / (meaning any path at the host)
-  // and must not have a Domain attribute.
-  // Read more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes'
-  let cookie
-  if (opt?.prefix === 'secure') {
-    cookie = serialize('__Secure-' + name, value, { path: '/', ...opt, secure: true })
-  } else if (opt?.prefix === 'host') {
-    cookie = serialize('__Host-' + name, value, {
-      ...opt,
-      path: '/',
-      secure: true,
-      domain: undefined,
-    })
-  } else {
-    cookie = serialize(name, value, { path: '/', ...opt })
-  }
-  c.header('set-cookie', cookie, { append: true })
-}
-
-export const setSignedCookie = async (
-  c: Context,
-  name: string,
-  value: string,
-  secret: string | BufferSource,
-  opt?: CookieOptions
-): Promise<void> => {
-  let cookie
-  if (opt?.prefix === 'secure') {
-    cookie = await serializeSigned('__Secure-' + name, value, secret, {
-      path: '/',
-      ...opt,
-      secure: true,
-    })
-  } else if (opt?.prefix === 'host') {
-    cookie = await serializeSigned('__Host-' + name, value, secret, {
-      ...opt,
-      path: '/',
-      secure: true,
-      domain: undefined,
-    })
-  } else {
-    cookie = await serializeSigned(name, value, secret, { path: '/', ...opt })
-  }
-  c.header('set-cookie', cookie, { append: true })
-}
-
-export const deleteCookie = (c: Context, name: string, opt?: CookieOptions): string | undefined => {
-  const deletedCookie = getCookie(c, name)
-  setCookie(c, name, '', { ...opt, maxAge: 0 })
-  return deletedCookie
-}
diff --git a/deno_dist/helper/css/common.ts b/deno_dist/helper/css/common.ts
deleted file mode 100644
index aff38a280..000000000
--- a/deno_dist/helper/css/common.ts
+++ /dev/null
@@ -1,243 +0,0 @@
-// provide utility functions for css helper both on server and client
-export const PSEUDO_GLOBAL_SELECTOR = ':-hono-global'
-export const isPseudoGlobalSelectorRe = new RegExp(`^${PSEUDO_GLOBAL_SELECTOR}{(.*)}$`)
-export const DEFAULT_STYLE_ID = 'hono-css'
-
-export const SELECTOR: unique symbol = Symbol()
-export const CLASS_NAME: unique symbol = Symbol()
-export const STYLE_STRING: unique symbol = Symbol()
-export const SELECTORS: unique symbol = Symbol()
-export const EXTERNAL_CLASS_NAMES: unique symbol = Symbol()
-const CSS_ESCAPED: unique symbol = Symbol()
-
-export interface CssClassName {
-  [SELECTOR]: string
-  [CLASS_NAME]: string
-  [STYLE_STRING]: string
-  [SELECTORS]: CssClassName[]
-  [EXTERNAL_CLASS_NAMES]: string[]
-}
-
-export const IS_CSS_ESCAPED = Symbol()
-
-interface CssEscapedString {
-  [CSS_ESCAPED]: string
-}
-
-/**
- * @experimental
- * `rawCssString` is an experimental feature.
- * The API might be changed.
- */
-export const rawCssString = (value: string): CssEscapedString => {
-  return {
-    [CSS_ESCAPED]: value,
-  }
-}
-
-/**
- * Used the goober'code as a reference:
- * https://github.com/cristianbote/goober/blob/master/src/core/to-hash.js
- * MIT License, Copyright (c) 2019 Cristian Bote
- */
-const toHash = (str: string): string => {
-  let i = 0,
-    out = 11
-  while (i < str.length) {
-    out = (101 * out + str.charCodeAt(i++)) >>> 0
-  }
-  return 'css-' + out
-}
-
-const cssStringReStr: string = [
-  '"(?:(?:\\\\[\\s\\S]|[^"\\\\])*)"', // double quoted string
-  // eslint-disable-next-line quotes
-  "'(?:(?:\\\\[\\s\\S]|[^'\\\\])*)'", // single quoted string
-].join('|')
-const minifyCssRe: RegExp = new RegExp(
-  [
-    '(' + cssStringReStr + ')', // $1: quoted string
-
-    '(?:' +
-      [
-        '^\\s+', // head whitespace
-        '\\/\\*.*?\\*\\/\\s*', // multi-line comment
-        '\\/\\/.*\\n\\s*', // single-line comment
-        '\\s+$', // tail whitespace
-      ].join('|') +
-      ')',
-
-    '\\s*;\\s*(}|$)\\s*', // $2: trailing semicolon
-    '\\s*([{};:,])\\s*', // $3: whitespace around { } : , ;
-    '(\\s)\\s+', // $4: 2+ spaces
-  ].join('|'),
-  'g'
-)
-
-export const minify = (css: string): string => {
-  return css.replace(minifyCssRe, (_, $1, $2, $3, $4) => $1 || $2 || $3 || $4 || '')
-}
-
-type CssVariableBasicType =
-  | CssClassName
-  | CssEscapedString
-  | string
-  | number
-  | boolean
-  | null
-  | undefined
-type CssVariableAsyncType = Promise<CssVariableBasicType>
-type CssVariableArrayType = (CssVariableBasicType | CssVariableAsyncType)[]
-export type CssVariableType = CssVariableBasicType | CssVariableAsyncType | CssVariableArrayType
-
-export const buildStyleString = (
-  strings: TemplateStringsArray,
-  values: CssVariableType[]
-): [string, string, CssClassName[], string[]] => {
-  const selectors: CssClassName[] = []
-  const externalClassNames: string[] = []
-
-  const label = strings[0].match(/^\s*\/\*(.*?)\*\//)?.[1] || ''
-  let styleString = ''
-  for (let i = 0, len = strings.length; i < len; i++) {
-    styleString += strings[i]
-    let vArray = values[i]
-    if (typeof vArray === 'boolean' || vArray === null || vArray === undefined) {
-      continue
-    }
-
-    if (!Array.isArray(vArray)) {
-      vArray = [vArray]
-    }
-    for (let j = 0, len = vArray.length; j < len; j++) {
-      let value = vArray[j]
-      if (typeof value === 'boolean' || value === null || value === undefined) {
-        continue
-      }
-      if (typeof value === 'string') {
-        if (/([\\"'\/])/.test(value)) {
-          styleString += value.replace(/([\\"']|(?<=<)\/)/g, '\\$1')
-        } else {
-          styleString += value
-        }
-      } else if (typeof value === 'number') {
-        styleString += value
-      } else if ((value as CssEscapedString)[CSS_ESCAPED]) {
-        styleString += (value as CssEscapedString)[CSS_ESCAPED]
-      } else if ((value as CssClassName)[CLASS_NAME].startsWith('@keyframes ')) {
-        selectors.push(value as CssClassName)
-        styleString += ` ${(value as CssClassName)[CLASS_NAME].substring(11)} `
-      } else {
-        if (strings[i + 1]?.match(/^\s*{/)) {
-          // assume this value is a class name
-          selectors.push(value as CssClassName)
-          value = `.${(value as CssClassName)[CLASS_NAME]}`
-        } else {
-          selectors.push(...(value as CssClassName)[SELECTORS])
-          externalClassNames.push(...(value as CssClassName)[EXTERNAL_CLASS_NAMES])
-          value = (value as CssClassName)[STYLE_STRING]
-          const valueLen = value.length
-          if (valueLen > 0) {
-            const lastChar = value[valueLen - 1]
-            if (lastChar !== ';' && lastChar !== '}') {
-              value += ';'
-            }
-          }
-        }
-        styleString += `${value || ''}`
-      }
-    }
-  }
-
-  return [label, minify(styleString), selectors, externalClassNames]
-}
-
-export const cssCommon = (
-  strings: TemplateStringsArray,
-  values: CssVariableType[]
-): CssClassName => {
-  let [label, thisStyleString, selectors, externalClassNames] = buildStyleString(strings, values)
-  const isPseudoGlobal = isPseudoGlobalSelectorRe.exec(thisStyleString)
-  if (isPseudoGlobal) {
-    thisStyleString = isPseudoGlobal[1]
-  }
-  const selector = (isPseudoGlobal ? PSEUDO_GLOBAL_SELECTOR : '') + toHash(label + thisStyleString)
-  const className = (
-    isPseudoGlobal ? selectors.map((s) => s[CLASS_NAME]) : [selector, ...externalClassNames]
-  ).join(' ')
-
-  return {
-    [SELECTOR]: selector,
-    [CLASS_NAME]: className,
-    [STYLE_STRING]: thisStyleString,
-    [SELECTORS]: selectors,
-    [EXTERNAL_CLASS_NAMES]: externalClassNames,
-  }
-}
-
-export const cxCommon = (
-  args: (string | boolean | null | undefined | CssClassName)[]
-): (string | boolean | null | undefined | CssClassName)[] => {
-  for (let i = 0, len = args.length; i < len; i++) {
-    const arg = args[i]
-    if (typeof arg === 'string') {
-      args[i] = {
-        [SELECTOR]: '',
-        [CLASS_NAME]: '',
-        [STYLE_STRING]: '',
-        [SELECTORS]: [],
-        [EXTERNAL_CLASS_NAMES]: [arg],
-      }
-    }
-  }
-
-  return args
-}
-
-export const keyframesCommon = (
-  strings: TemplateStringsArray,
-  ...values: CssVariableType[]
-): CssClassName => {
-  const [label, styleString] = buildStyleString(strings, values)
-  return {
-    [SELECTOR]: '',
-    [CLASS_NAME]: `@keyframes ${toHash(label + styleString)}`,
-    [STYLE_STRING]: styleString,
-    [SELECTORS]: [],
-    [EXTERNAL_CLASS_NAMES]: [],
-  }
-}
-
-type ViewTransitionType = {
-  (strings: TemplateStringsArray, values: CssVariableType[]): CssClassName
-  (content: CssClassName): CssClassName
-  (): CssClassName
-}
-
-let viewTransitionNameIndex = 0
-export const viewTransitionCommon: ViewTransitionType = ((
-  strings: TemplateStringsArray | CssClassName | undefined,
-  values: CssVariableType[]
-): CssClassName => {
-  if (!strings) {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    strings = [`/* h-v-t ${viewTransitionNameIndex++} */`] as any
-  }
-  const content = Array.isArray(strings)
-    ? cssCommon(strings as TemplateStringsArray, values)
-    : (strings as CssClassName)
-
-  const transitionName = content[CLASS_NAME]
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const res = cssCommon(['view-transition-name:', ''] as any, [transitionName])
-
-  content[CLASS_NAME] = PSEUDO_GLOBAL_SELECTOR + content[CLASS_NAME]
-  content[STYLE_STRING] = content[STYLE_STRING].replace(
-    /(?<=::view-transition(?:[a-z-]*)\()(?=\))/g,
-    transitionName
-  )
-  res[CLASS_NAME] = res[SELECTOR] = transitionName
-  res[SELECTORS] = [...content[SELECTORS], content]
-
-  return res
-}) as ViewTransitionType
diff --git a/deno_dist/helper/css/index.ts b/deno_dist/helper/css/index.ts
deleted file mode 100644
index 33d53e619..000000000
--- a/deno_dist/helper/css/index.ts
+++ /dev/null
@@ -1,215 +0,0 @@
-import { raw } from '../../helper/html/index.ts'
-import { DOM_RENDERER } from '../../jsx/constants.ts'
-import { createCssJsxDomObjects } from '../../jsx/dom/css.ts'
-import type { HtmlEscapedCallback, HtmlEscapedString } from '../../utils/html.ts'
-import type { CssClassName as CssClassNameCommon, CssVariableType } from './common.ts'
-import {
-  SELECTOR,
-  CLASS_NAME,
-  STYLE_STRING,
-  SELECTORS,
-  PSEUDO_GLOBAL_SELECTOR,
-  DEFAULT_STYLE_ID,
-  cssCommon,
-  cxCommon,
-  keyframesCommon,
-  viewTransitionCommon,
-} from './common.ts'
-export { rawCssString } from './common.ts'
-
-type CssClassName = HtmlEscapedString & CssClassNameCommon
-
-type usedClassNameData = [
-  Record<string, string>, // class name to add
-  Record<string, true> // class name already added
-]
-
-interface CssType {
-  (strings: TemplateStringsArray, ...values: CssVariableType[]): Promise<string>
-}
-
-interface CxType {
-  (
-    ...args: (CssClassName | Promise<string> | string | boolean | null | undefined)[]
-  ): Promise<string>
-}
-
-interface KeyframesType {
-  (strings: TemplateStringsArray, ...values: CssVariableType[]): CssClassNameCommon
-}
-
-interface ViewTransitionType {
-  (strings: TemplateStringsArray, ...values: CssVariableType[]): Promise<string>
-  (content: Promise<string>): Promise<string>
-  (): Promise<string>
-}
-
-interface StyleType {
-  (args?: { children?: Promise<string> }): HtmlEscapedString
-}
-
-/**
- * @experimental
- * `createCssContext` is an experimental feature.
- * The API might be changed.
- */
-export const createCssContext = ({ id }: { id: Readonly<string> }): DefaultContextType => {
-  const [cssJsxDomObject, StyleRenderToDom] = createCssJsxDomObjects({ id })
-
-  const contextMap: WeakMap<object, usedClassNameData> = new WeakMap()
-
-  const replaceStyleRe = new RegExp(`(<style id="${id}">.*?)(</style>)`)
-
-  const newCssClassNameObject = (cssClassName: CssClassNameCommon): Promise<string> => {
-    const appendStyle: HtmlEscapedCallback = ({ buffer, context }): Promise<string> | undefined => {
-      const [toAdd, added] = contextMap.get(context) as usedClassNameData
-      const names = Object.keys(toAdd)
-
-      if (!names.length) {
-        return
-      }
-
-      let stylesStr = ''
-      names.forEach((className) => {
-        added[className] = true
-        stylesStr += className.startsWith(PSEUDO_GLOBAL_SELECTOR)
-          ? toAdd[className]
-          : `${className[0] === '@' ? '' : '.'}${className}{${toAdd[className]}}`
-      })
-      contextMap.set(context, [{}, added])
-
-      if (buffer && replaceStyleRe.test(buffer[0])) {
-        buffer[0] = buffer[0].replace(replaceStyleRe, (_, pre, post) => `${pre}${stylesStr}${post}`)
-        return
-      }
-
-      const appendStyleScript = `<script>document.querySelector('#${id}').textContent+=${JSON.stringify(
-        stylesStr
-      )}</script>`
-      if (buffer) {
-        buffer[0] = `${appendStyleScript}${buffer[0]}`
-        return
-      }
-
-      return Promise.resolve(appendStyleScript)
-    }
-
-    const addClassNameToContext: HtmlEscapedCallback = ({ context }) => {
-      if (!contextMap.get(context)) {
-        contextMap.set(context, [{}, {}])
-      }
-      const [toAdd, added] = contextMap.get(context) as usedClassNameData
-      let allAdded = true
-      if (!added[cssClassName[SELECTOR]]) {
-        allAdded = false
-        toAdd[cssClassName[SELECTOR]] = cssClassName[STYLE_STRING]
-      }
-      cssClassName[SELECTORS].forEach(
-        ({ [CLASS_NAME]: className, [STYLE_STRING]: styleString }) => {
-          if (!added[className]) {
-            allAdded = false
-            toAdd[className] = styleString
-          }
-        }
-      )
-      if (allAdded) {
-        return
-      }
-
-      return Promise.resolve(raw('', [appendStyle]))
-    }
-
-    const className = new String(cssClassName[CLASS_NAME]) as CssClassName
-    Object.assign(className, cssClassName)
-    ;(className as HtmlEscapedString).isEscaped = true
-    ;(className as HtmlEscapedString).callbacks = [addClassNameToContext]
-    const promise = Promise.resolve(className)
-    Object.assign(promise, cssClassName)
-    // eslint-disable-next-line @typescript-eslint/unbound-method
-    promise.toString = cssJsxDomObject.toString
-    return promise
-  }
-
-  const css: CssType = (strings, ...values) => {
-    return newCssClassNameObject(cssCommon(strings, values))
-  }
-
-  const cx: CxType = (...args) => {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    args = cxCommon(args as any) as any
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return css(Array(args.length).fill('') as any, ...args)
-  }
-
-  const keyframes = keyframesCommon
-
-  const viewTransition: ViewTransitionType = ((
-    strings: TemplateStringsArray | Promise<string> | undefined,
-    ...values: CssVariableType[]
-  ) => {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return newCssClassNameObject(viewTransitionCommon(strings as any, values))
-  }) as ViewTransitionType
-
-  const Style: StyleType = ({ children } = {}) =>
-    children
-      ? raw(`<style id="${id}">${(children as unknown as CssClassName)[STYLE_STRING]}</style>`)
-      : raw(`<style id="${id}"></style>`)
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  ;(Style as any)[DOM_RENDERER] = StyleRenderToDom
-
-  return {
-    css,
-    cx,
-    keyframes,
-    viewTransition: viewTransition as ViewTransitionType,
-    Style,
-  }
-}
-
-interface DefaultContextType {
-  css: CssType
-  cx: CxType
-  keyframes: KeyframesType
-  viewTransition: ViewTransitionType
-  Style: StyleType
-}
-
-const defaultContext: DefaultContextType = createCssContext({
-  id: DEFAULT_STYLE_ID,
-})
-
-/**
- * @experimental
- * `css` is an experimental feature.
- * The API might be changed.
- */
-export const css = defaultContext.css
-
-/**
- * @experimental
- * `cx` is an experimental feature.
- * The API might be changed.
- */
-export const cx = defaultContext.cx
-
-/**
- * @experimental
- * `keyframes` is an experimental feature.
- * The API might be changed.
- */
-export const keyframes = defaultContext.keyframes
-
-/**
- * @experimental
- * `viewTransition` is an experimental feature.
- * The API might be changed.
- */
-export const viewTransition = defaultContext.viewTransition
-
-/**
- * @experimental
- * `Style` is an experimental feature.
- * The API might be changed.
- */
-export const Style = defaultContext.Style
diff --git a/deno_dist/helper/dev/index.ts b/deno_dist/helper/dev/index.ts
deleted file mode 100644
index 7ba8613ee..000000000
--- a/deno_dist/helper/dev/index.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import type { Hono } from '../../hono.ts'
-import type { Env, RouterRoute } from '../../types.ts'
-import { getColorEnabled } from '../../utils/color.ts'
-import { findTargetHandler, isMiddleware } from '../../utils/handler.ts'
-
-interface ShowRoutesOptions {
-  verbose?: boolean
-  colorize?: boolean
-}
-
-interface RouteData {
-  path: string
-  method: string
-  name: string
-  isMiddleware: boolean
-}
-
-const handlerName = (handler: Function): string => {
-  return handler.name || (isMiddleware(handler) ? '[middleware]' : '[handler]')
-}
-
-export const inspectRoutes = <E extends Env>(hono: Hono<E>): RouteData[] => {
-  return hono.routes.map(({ path, method, handler }: RouterRoute) => {
-    const targetHandler = findTargetHandler(handler)
-    return {
-      path,
-      method,
-      name: handlerName(targetHandler),
-      isMiddleware: isMiddleware(targetHandler),
-    }
-  })
-}
-
-export const showRoutes = <E extends Env>(hono: Hono<E>, opts?: ShowRoutesOptions) => {
-  const colorEnabled = opts?.colorize ?? getColorEnabled()
-  const routeData: Record<string, RouteData[]> = {}
-  let maxMethodLength = 0
-  let maxPathLength = 0
-
-  inspectRoutes(hono)
-    .filter(({ isMiddleware }) => opts?.verbose || !isMiddleware)
-    .map((route) => {
-      const key = `${route.method}-${route.path}`
-      ;(routeData[key] ||= []).push(route)
-      if (routeData[key].length > 1) {
-        return
-      }
-      maxMethodLength = Math.max(maxMethodLength, route.method.length)
-      maxPathLength = Math.max(maxPathLength, route.path.length)
-      return { method: route.method, path: route.path, routes: routeData[key] }
-    })
-    .forEach((data) => {
-      if (!data) {
-        return
-      }
-      const { method, path, routes } = data
-
-      const methodStr = colorEnabled ? `\x1b[32m${method}\x1b[0m` : method
-      console.log(`${methodStr} ${' '.repeat(maxMethodLength - method.length)} ${path}`)
-
-      if (!opts?.verbose) {
-        return
-      }
-
-      routes.forEach(({ name }) => {
-        console.log(`${' '.repeat(maxMethodLength + 3)} ${name}`)
-      })
-    })
-}
-
-export const getRouterName = <E extends Env>(app: Hono<E>): string => {
-  app.router.match('GET', '/')
-  return app.router.name
-}
diff --git a/deno_dist/helper/factory/index.ts b/deno_dist/helper/factory/index.ts
deleted file mode 100644
index be3e05066..000000000
--- a/deno_dist/helper/factory/index.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { Hono } from '../../hono.ts'
-import type { Env, H, HandlerResponse, Input, MiddlewareHandler } from '../../types.ts'
-
-type InitApp<E extends Env = Env> = (app: Hono<E>) => void
-
-export interface CreateHandlersInterface<E extends Env, P extends string> {
-  <I extends Input = {}, R extends HandlerResponse<any> = any>(handler1: H<E, P, I, R>): [
-    H<E, P, I, R>
-  ]
-  // handler x2
-  <I extends Input = {}, I2 extends Input = I, R extends HandlerResponse<any> = any>(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>
-  ): [H<E, P, I, R>, H<E, P, I2, R>]
-
-  // handler x3
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>
-  ): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>]
-
-  // handler x4
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>
-  ): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>]
-
-  // handler x5
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>
-  ): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>, H<E, P, I5, R>]
-
-  // handler x6
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>,
-    handler6: H<E, P, I6, R>
-  ): [H<E, P, I, R>, H<E, P, I2, R>, H<E, P, I3, R>, H<E, P, I4, R>, H<E, P, I5, R>, H<E, P, I6, R>]
-
-  // handler x7
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>,
-    handler6: H<E, P, I6, R>,
-    handler7: H<E, P, I7, R>
-  ): [
-    H<E, P, I, R>,
-    H<E, P, I2, R>,
-    H<E, P, I3, R>,
-    H<E, P, I4, R>,
-    H<E, P, I5, R>,
-    H<E, P, I6, R>,
-    H<E, P, I7, R>
-  ]
-
-  // handler x8
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>,
-    handler6: H<E, P, I6, R>,
-    handler7: H<E, P, I7, R>,
-    handler8: H<E, P, I8, R>
-  ): [
-    H<E, P, I, R>,
-    H<E, P, I2, R>,
-    H<E, P, I3, R>,
-    H<E, P, I4, R>,
-    H<E, P, I5, R>,
-    H<E, P, I6, R>,
-    H<E, P, I7, R>,
-    H<E, P, I8, R>
-  ]
-
-  // handler x9
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>,
-    handler6: H<E, P, I6, R>,
-    handler7: H<E, P, I7, R>,
-    handler8: H<E, P, I8, R>,
-    handler9: H<E, P, I9, R>
-  ): [
-    H<E, P, I, R>,
-    H<E, P, I2, R>,
-    H<E, P, I3, R>,
-    H<E, P, I4, R>,
-    H<E, P, I5, R>,
-    H<E, P, I6, R>,
-    H<E, P, I7, R>,
-    H<E, P, I8, R>,
-    H<E, P, I9, R>
-  ]
-
-  // handler x10
-  <
-    I extends Input = {},
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9,
-    R extends HandlerResponse<any> = any
-  >(
-    handler1: H<E, P, I, R>,
-    handler2: H<E, P, I2, R>,
-    handler3: H<E, P, I3, R>,
-    handler4: H<E, P, I4, R>,
-    handler5: H<E, P, I5, R>,
-    handler6: H<E, P, I6, R>,
-    handler7: H<E, P, I7, R>,
-    handler8: H<E, P, I8, R>,
-    handler9: H<E, P, I9, R>,
-    handler10: H<E, P, I10, R>
-  ): [
-    H<E, P, I, R>,
-    H<E, P, I2, R>,
-    H<E, P, I3, R>,
-    H<E, P, I4, R>,
-    H<E, P, I5, R>,
-    H<E, P, I6, R>,
-    H<E, P, I7, R>,
-    H<E, P, I8, R>,
-    H<E, P, I9, R>,
-    H<E, P, I10, R>
-  ]
-}
-
-export class Factory<E extends Env = any, P extends string = any> {
-  private initApp?: InitApp<E>
-
-  constructor(init?: { initApp?: InitApp<E> }) {
-    this.initApp = init?.initApp
-  }
-
-  /**
-   * @experimental
-   * `createApp` is an experimental feature.
-   */
-  createApp = (): Hono<E> => {
-    const app = new Hono<E>()
-    if (this.initApp) {
-      this.initApp(app)
-    }
-    return app
-  }
-
-  createMiddleware = <I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => middleware
-
-  createHandlers: CreateHandlersInterface<E, P> = (...handlers: any) => {
-    // @ts-expect-error this should not be typed
-    return handlers.filter((handler) => handler !== undefined)
-  }
-}
-
-export const createFactory = <E extends Env = any, P extends string = any>(init?: {
-  initApp?: InitApp<E>
-}): Factory<E, P> => new Factory<E, P>(init)
-
-export const createMiddleware = <E extends Env = any, P extends string = any, I extends Input = {}>(
-  middleware: MiddlewareHandler<E, P, I>
-): MiddlewareHandler<E, P, I> => createFactory<E, P>().createMiddleware<I>(middleware)
diff --git a/deno_dist/helper/html/index.ts b/deno_dist/helper/html/index.ts
deleted file mode 100644
index dc48e99bd..000000000
--- a/deno_dist/helper/html/index.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { escapeToBuffer, stringBufferToString, raw } from '../../utils/html.ts'
-import type { StringBuffer, HtmlEscaped, HtmlEscapedString } from '../../utils/html.ts'
-
-export { raw }
-
-export const html = (
-  strings: TemplateStringsArray,
-  ...values: unknown[]
-): HtmlEscapedString | Promise<HtmlEscapedString> => {
-  const buffer: StringBuffer = ['']
-
-  for (let i = 0, len = strings.length - 1; i < len; i++) {
-    buffer[0] += strings[i]
-
-    const children =
-      values[i] instanceof Array ? (values[i] as Array<unknown>).flat(Infinity) : [values[i]]
-    for (let i = 0, len = children.length; i < len; i++) {
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      const child = children[i] as any
-      if (typeof child === 'string') {
-        escapeToBuffer(child, buffer)
-      } else if (typeof child === 'number') {
-        ;(buffer[0] as string) += child
-      } else if (typeof child === 'boolean' || child === null || child === undefined) {
-        continue
-      } else if (typeof child === 'object' && (child as HtmlEscaped).isEscaped) {
-        if ((child as HtmlEscapedString).callbacks) {
-          buffer.unshift('', child)
-        } else {
-          const tmp = child.toString()
-          if (tmp instanceof Promise) {
-            buffer.unshift('', tmp)
-          } else {
-            buffer[0] += tmp
-          }
-        }
-      } else if (child instanceof Promise) {
-        buffer.unshift('', child)
-      } else {
-        escapeToBuffer(child.toString(), buffer)
-      }
-    }
-  }
-  buffer[0] += strings[strings.length - 1]
-
-  return buffer.length === 1 ? raw(buffer[0]) : stringBufferToString(buffer)
-}
diff --git a/deno_dist/helper/ssg/index.ts b/deno_dist/helper/ssg/index.ts
deleted file mode 100644
index 813a9d4d5..000000000
--- a/deno_dist/helper/ssg/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export * from './ssg.ts'
-export {
-  X_HONO_DISABLE_SSG_HEADER_KEY,
-  ssgParams,
-  isSSGContext,
-  disableSSG,
-  onlySSG,
-} from './middleware.ts'
diff --git a/deno_dist/helper/ssg/middleware.ts b/deno_dist/helper/ssg/middleware.ts
deleted file mode 100644
index 4d81fc54b..000000000
--- a/deno_dist/helper/ssg/middleware.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import type { Context } from '../../context.ts'
-import type { Env, MiddlewareHandler } from '../../types.ts'
-
-export const SSG_CONTEXT = 'HONO_SSG_CONTEXT'
-export const X_HONO_DISABLE_SSG_HEADER_KEY = 'x-hono-disable-ssg'
-
-/**
- * @deprecated
- * Use `X_HONO_DISABLE_SSG_HEADER_KEY` instead.
- * This constant will be removed in the next minor version.
- */
-export const SSG_DISABLED_RESPONSE = (() => {
-  try {
-    return new Response('SSG is disabled', {
-      status: 404,
-      headers: { [X_HONO_DISABLE_SSG_HEADER_KEY]: 'true' },
-    })
-  } catch (e) {
-    return null
-  }
-})() as Response
-
-interface SSGParam {
-  [key: string]: string
-}
-export type SSGParams = SSGParam[]
-
-interface SSGParamsMiddleware {
-  <E extends Env = Env>(
-    generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>
-  ): MiddlewareHandler<E>
-  <E extends Env = Env>(params: SSGParams): MiddlewareHandler<E>
-}
-
-export type AddedSSGDataRequest = Request & {
-  ssgParams?: SSGParams
-}
-
-/**
- * Define SSG Route
- */
-export const ssgParams: SSGParamsMiddleware = (params) => async (c, next) => {
-  ;(c.req.raw as AddedSSGDataRequest).ssgParams = Array.isArray(params) ? params : await params(c)
-  await next()
-}
-
-/**
- * @experimental
- * `isSSGContext` is an experimental feature.
- * The API might be changed.
- */
-export const isSSGContext = (c: Context): boolean => !!c.env?.[SSG_CONTEXT]
-
-/**
- * @experimental
- * `disableSSG` is an experimental feature.
- * The API might be changed.
- */
-export const disableSSG = (): MiddlewareHandler =>
-  async function disableSSG(c, next) {
-    if (isSSGContext(c)) {
-      c.header(X_HONO_DISABLE_SSG_HEADER_KEY, 'true')
-      return c.notFound()
-    }
-    await next()
-  }
-
-/**
- * @experimental
- * `onlySSG` is an experimental feature.
- * The API might be changed.
- */
-export const onlySSG = (): MiddlewareHandler =>
-  async function onlySSG(c, next) {
-    if (!isSSGContext(c)) {
-      return c.notFound()
-    }
-    await next()
-  }
diff --git a/deno_dist/helper/ssg/ssg.ts b/deno_dist/helper/ssg/ssg.ts
deleted file mode 100644
index 5e506436f..000000000
--- a/deno_dist/helper/ssg/ssg.ts
+++ /dev/null
@@ -1,388 +0,0 @@
-import { replaceUrlParam } from '../../client/utils.ts'
-import type { Hono } from '../../hono.ts'
-import type { Env, Schema } from '../../types.ts'
-import { createPool } from '../../utils/concurrent.ts'
-import { getExtension } from '../../utils/mime.ts'
-import type { AddedSSGDataRequest, SSGParams } from './middleware.ts'
-import { X_HONO_DISABLE_SSG_HEADER_KEY, SSG_CONTEXT } from './middleware.ts'
-import { joinPaths, dirname, filterStaticGenerateRoutes } from './utils.ts'
-
-const DEFAULT_CONCURRENCY = 2 // default concurrency for ssg
-
-// 'default_content_type' is designed according to Bun's performance optimization,
-//  which omits Content-Type by default for text responses.
-//  This is based on benchmarks showing performance gains without Content-Type.
-//  In Hono, using `c.text()` without a Content-Type implicitly assumes 'text/plain; charset=UTF-8'.
-//  This approach maintains performance consistency across different environments.
-//  For details, see GitHub issues: oven-sh/bun#8530 and https://github.com/honojs/hono/issues/2284.
-const DEFAULT_CONTENT_TYPE = 'text/plain'
-
-/**
- * @experimental
- * `FileSystemModule` is an experimental feature.
- * The API might be changed.
- */
-export interface FileSystemModule {
-  writeFile(path: string, data: string | Uint8Array): Promise<void>
-  mkdir(path: string, options: { recursive: boolean }): Promise<void | string>
-}
-
-/**
- * @experimental
- * `ToSSGResult` is an experimental feature.
- * The API might be changed.
- */
-export interface ToSSGResult {
-  success: boolean
-  files: string[]
-  error?: Error
-}
-
-const generateFilePath = (
-  routePath: string,
-  outDir: string,
-  mimeType: string,
-  extensionMap?: Record<string, string>
-) => {
-  const extension = determineExtension(mimeType, extensionMap)
-
-  if (routePath.endsWith(`.${extension}`)) {
-    return joinPaths(outDir, routePath)
-  }
-
-  if (routePath === '/') {
-    return joinPaths(outDir, `index.${extension}`)
-  }
-  if (routePath.endsWith('/')) {
-    return joinPaths(outDir, routePath, `index.${extension}`)
-  }
-  return joinPaths(outDir, `${routePath}.${extension}`)
-}
-
-const parseResponseContent = async (response: Response): Promise<string | ArrayBuffer> => {
-  const contentType = response.headers.get('Content-Type')
-
-  try {
-    if (contentType?.includes('text') || contentType?.includes('json')) {
-      return await response.text()
-    } else {
-      return await response.arrayBuffer()
-    }
-  } catch (error) {
-    throw new Error(
-      `Error processing response: ${error instanceof Error ? error.message : 'Unknown error'}`
-    )
-  }
-}
-
-export const defaultExtensionMap: Record<string, string> = {
-  'text/html': 'html',
-  'text/xml': 'xml',
-  'application/xml': 'xml',
-  'application/yaml': 'yaml',
-}
-
-const determineExtension = (
-  mimeType: string,
-  userExtensionMap?: Record<string, string>
-): string => {
-  const extensionMap = userExtensionMap || defaultExtensionMap
-  if (mimeType in extensionMap) {
-    return extensionMap[mimeType]
-  }
-  return getExtension(mimeType) || 'html'
-}
-
-export type BeforeRequestHook = (req: Request) => Request | false | Promise<Request | false>
-export type AfterResponseHook = (res: Response) => Response | false | Promise<Response | false>
-export type AfterGenerateHook = (result: ToSSGResult) => void | Promise<void>
-
-export const combineBeforeRequestHooks = (
-  hooks: BeforeRequestHook | BeforeRequestHook[]
-): BeforeRequestHook => {
-  if (!Array.isArray(hooks)) {
-    return hooks
-  }
-  return async (req: Request): Promise<Request | false> => {
-    let currentReq = req
-    for (const hook of hooks) {
-      const result = await hook(currentReq)
-      if (result === false) {
-        return false
-      }
-      if (result instanceof Request) {
-        currentReq = result
-      }
-    }
-    return currentReq
-  }
-}
-
-export const combineAfterResponseHooks = (
-  hooks: AfterResponseHook | AfterResponseHook[]
-): AfterResponseHook => {
-  if (!Array.isArray(hooks)) {
-    return hooks
-  }
-  return async (res: Response): Promise<Response | false> => {
-    let currentRes = res
-    for (const hook of hooks) {
-      const result = await hook(currentRes)
-      if (result === false) {
-        return false
-      }
-      if (result instanceof Response) {
-        currentRes = result
-      }
-    }
-    return currentRes
-  }
-}
-
-export const combineAfterGenerateHooks = (
-  hooks: AfterGenerateHook | AfterGenerateHook[]
-): AfterGenerateHook => {
-  if (!Array.isArray(hooks)) {
-    return hooks
-  }
-  return async (result: ToSSGResult): Promise<void> => {
-    for (const hook of hooks) {
-      await hook(result)
-    }
-  }
-}
-
-export interface ToSSGOptions {
-  dir?: string
-  beforeRequestHook?: BeforeRequestHook | BeforeRequestHook[]
-  afterResponseHook?: AfterResponseHook | AfterResponseHook[]
-  afterGenerateHook?: AfterGenerateHook | AfterGenerateHook[]
-  concurrency?: number
-  extensionMap?: Record<string, string>
-}
-
-/**
- * @experimental
- * `fetchRoutesContent` is an experimental feature.
- * The API might be changed.
- */
-export const fetchRoutesContent = function* <
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
->(
-  app: Hono<E, S, BasePath>,
-  beforeRequestHook?: BeforeRequestHook,
-  afterResponseHook?: AfterResponseHook,
-  concurrency?: number
-): Generator<
-  Promise<
-    | Generator<
-        Promise<{ routePath: string; mimeType: string; content: string | ArrayBuffer } | undefined>
-      >
-    | undefined
-  >
-> {
-  const baseURL = 'http://localhost'
-  const pool = createPool({ concurrency })
-
-  for (const route of filterStaticGenerateRoutes(app)) {
-    // GET Route Info
-    const thisRouteBaseURL = new URL(route.path, baseURL).toString()
-
-    let forGetInfoURLRequest = new Request(thisRouteBaseURL) as AddedSSGDataRequest
-
-    // eslint-disable-next-line no-async-promise-executor
-    yield new Promise(async (resolveGetInfo, rejectGetInfo) => {
-      try {
-        if (beforeRequestHook) {
-          const maybeRequest = await beforeRequestHook(forGetInfoURLRequest)
-          if (!maybeRequest) {
-            resolveGetInfo(undefined)
-            return
-          }
-          forGetInfoURLRequest = maybeRequest as unknown as AddedSSGDataRequest
-        }
-
-        await pool.run(() => app.fetch(forGetInfoURLRequest))
-
-        if (!forGetInfoURLRequest.ssgParams) {
-          if (isDynamicRoute(route.path)) {
-            resolveGetInfo(undefined)
-            return
-          }
-          forGetInfoURLRequest.ssgParams = [{}]
-        }
-
-        const requestInit = {
-          method: forGetInfoURLRequest.method,
-          headers: forGetInfoURLRequest.headers,
-        }
-
-        resolveGetInfo(
-          (function* () {
-            for (const param of forGetInfoURLRequest.ssgParams as SSGParams) {
-              // eslint-disable-next-line no-async-promise-executor
-              yield new Promise(async (resolveReq, rejectReq) => {
-                try {
-                  const replacedUrlParam = replaceUrlParam(route.path, param)
-                  let response = await pool.run(() =>
-                    app.request(replacedUrlParam, requestInit, {
-                      [SSG_CONTEXT]: true,
-                    })
-                  )
-                  if (response.headers.get(X_HONO_DISABLE_SSG_HEADER_KEY)) {
-                    resolveReq(undefined)
-                    return
-                  }
-                  if (afterResponseHook) {
-                    const maybeResponse = await afterResponseHook(response)
-                    if (!maybeResponse) {
-                      resolveReq(undefined)
-                      return
-                    }
-                    response = maybeResponse
-                  }
-                  const mimeType =
-                    response.headers.get('Content-Type')?.split(';')[0] || DEFAULT_CONTENT_TYPE
-                  const content = await parseResponseContent(response)
-                  resolveReq({
-                    routePath: replacedUrlParam,
-                    mimeType,
-                    content,
-                  })
-                } catch (error) {
-                  rejectReq(error)
-                }
-              })
-            }
-          })()
-        )
-      } catch (error) {
-        rejectGetInfo(error)
-      }
-    })
-  }
-}
-
-const isDynamicRoute = (path: string): boolean => {
-  return path.split('/').some((segment) => segment.startsWith(':') || segment.includes('*'))
-}
-
-/**
- * @experimental
- * `saveContentToFile` is an experimental feature.
- * The API might be changed.
- */
-const createdDirs: Set<string> = new Set()
-export const saveContentToFile = async (
-  data: Promise<{ routePath: string; content: string | ArrayBuffer; mimeType: string } | undefined>,
-  fsModule: FileSystemModule,
-  outDir: string,
-  extensionMap?: Record<string, string>
-): Promise<string | undefined> => {
-  const awaitedData = await data
-  if (!awaitedData) {
-    return
-  }
-  const { routePath, content, mimeType } = awaitedData
-  const filePath = generateFilePath(routePath, outDir, mimeType, extensionMap)
-  const dirPath = dirname(filePath)
-
-  if (!createdDirs.has(dirPath)) {
-    await fsModule.mkdir(dirPath, { recursive: true })
-    createdDirs.add(dirPath)
-  }
-  if (typeof content === 'string') {
-    await fsModule.writeFile(filePath, content)
-  } else if (content instanceof ArrayBuffer) {
-    await fsModule.writeFile(filePath, new Uint8Array(content))
-  }
-  return filePath
-}
-
-/**
- * @experimental
- * `ToSSGInterface` is an experimental feature.
- * The API might be changed.
- */
-export interface ToSSGInterface {
-  (
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    app: Hono<any, any, any>,
-    fsModule: FileSystemModule,
-    options?: ToSSGOptions
-  ): Promise<ToSSGResult>
-}
-
-/**
- * @experimental
- * `ToSSGAdaptorInterface` is an experimental feature.
- * The API might be changed.
- */
-export interface ToSSGAdaptorInterface<
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> {
-  (app: Hono<E, S, BasePath>, options?: ToSSGOptions): Promise<ToSSGResult>
-}
-
-/**
- * @experimental
- * `toSSG` is an experimental feature.
- * The API might be changed.
- */
-export const toSSG: ToSSGInterface = async (app, fs, options) => {
-  let result: ToSSGResult | undefined
-  const getInfoPromises: Promise<unknown>[] = []
-  const savePromises: Promise<string | undefined>[] = []
-  try {
-    const outputDir = options?.dir ?? './static'
-    const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY
-
-    const combinedBeforeRequestHook = combineBeforeRequestHooks(
-      options?.beforeRequestHook || ((req) => req)
-    )
-    const combinedAfterResponseHook = combineAfterResponseHooks(
-      options?.afterResponseHook || ((req) => req)
-    )
-    const getInfoGen = fetchRoutesContent(
-      app,
-      combinedBeforeRequestHook,
-      combinedAfterResponseHook,
-      concurrency
-    )
-    for (const getInfo of getInfoGen) {
-      getInfoPromises.push(
-        getInfo.then((getContentGen) => {
-          if (!getContentGen) {
-            return
-          }
-          for (const content of getContentGen) {
-            savePromises.push(saveContentToFile(content, fs, outputDir).catch((e) => e))
-          }
-        })
-      )
-    }
-    await Promise.all(getInfoPromises)
-    const files: string[] = []
-    for (const savePromise of savePromises) {
-      const fileOrError = await savePromise
-      if (typeof fileOrError === 'string') {
-        files.push(fileOrError)
-      } else if (fileOrError) {
-        throw fileOrError
-      }
-    }
-    result = { success: true, files }
-  } catch (error) {
-    const errorObj = error instanceof Error ? error : new Error(String(error))
-    result = { success: false, files: [], error: errorObj }
-  }
-  if (options?.afterGenerateHook) {
-    const conbinedAfterGenerateHooks = combineAfterGenerateHooks(options?.afterGenerateHook)
-    await conbinedAfterGenerateHooks(result)
-  }
-  return result
-}
diff --git a/deno_dist/helper/ssg/utils.ts b/deno_dist/helper/ssg/utils.ts
deleted file mode 100644
index 3a37eb290..000000000
--- a/deno_dist/helper/ssg/utils.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import type { Hono } from '../../hono.ts'
-import { METHOD_NAME_ALL } from '../../router.ts'
-import type { Env, RouterRoute } from '../../types.ts'
-import { findTargetHandler, isMiddleware } from '../../utils/handler.ts'
-
-/**
- * Get dirname
- * @param path File Path
- * @returns Parent dir path
- */
-export const dirname = (path: string) => {
-  const splittedPath = path.split(/[\/\\]/)
-  return splittedPath.slice(0, -1).join('/') // Windows supports slash path
-}
-
-const normalizePath = (path: string) => {
-  return path.replace(/(\\)/g, '/').replace(/\/$/g, '')
-}
-
-const handleDotDot = (resultPaths: string[]) => {
-  if (resultPaths.length === 0) {
-    resultPaths.push('..')
-  } else {
-    resultPaths.pop()
-  }
-}
-
-const handleNonDot = (path: string, resultPaths: string[]) => {
-  path = path.replace(/^\.(?!.)/, '')
-  if (path !== '') {
-    resultPaths.push(path)
-  }
-}
-
-const handleSegments = (paths: string[], resultPaths: string[]) => {
-  for (const path of paths) {
-    // Handle `..` or `../`
-    if (path === '..') {
-      handleDotDot(resultPaths)
-    } else {
-      // Handle `.` or `./`
-      handleNonDot(path, resultPaths)
-    }
-  }
-}
-
-export const joinPaths = (...paths: string[]) => {
-  paths = paths.map(normalizePath)
-  const resultPaths: string[] = []
-  handleSegments(paths.join('/').split('/'), resultPaths)
-  return (paths[0][0] === '/' ? '/' : '') + resultPaths.join('/')
-}
-
-interface FilterStaticGenerateRouteData {
-  path: string
-}
-
-export const filterStaticGenerateRoutes = <E extends Env>(
-  hono: Hono<E>
-): FilterStaticGenerateRouteData[] => {
-  return hono.routes.reduce((acc, { method, handler, path }: RouterRoute) => {
-    const targetHandler = findTargetHandler(handler)
-    if (['GET', METHOD_NAME_ALL].includes(method) && !isMiddleware(targetHandler)) {
-      acc.push({ path })
-    }
-    return acc
-  }, [] as FilterStaticGenerateRouteData[])
-}
diff --git a/deno_dist/helper/streaming/index.ts b/deno_dist/helper/streaming/index.ts
deleted file mode 100644
index c19ca0e79..000000000
--- a/deno_dist/helper/streaming/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { stream } from './stream.ts'
-export type { SSEMessage } from './sse.ts'
-export { streamSSE, SSEStreamingApi } from './sse.ts'
-export { streamText } from './text.ts'
diff --git a/deno_dist/helper/streaming/sse.ts b/deno_dist/helper/streaming/sse.ts
deleted file mode 100644
index 4fa30be01..000000000
--- a/deno_dist/helper/streaming/sse.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import type { Context } from '../../context.ts'
-import { StreamingApi } from '../../utils/stream.ts'
-
-export interface SSEMessage {
-  data: string
-  event?: string
-  id?: string
-  retry?: number
-}
-
-export class SSEStreamingApi extends StreamingApi {
-  constructor(writable: WritableStream, readable: ReadableStream) {
-    super(writable, readable)
-  }
-
-  async writeSSE(message: SSEMessage) {
-    const data = message.data
-      .split('\n')
-      .map((line) => {
-        return `data: ${line}`
-      })
-      .join('\n')
-
-    const sseData =
-      [
-        message.event && `event: ${message.event}`,
-        data,
-        message.id && `id: ${message.id}`,
-        message.retry && `retry: ${message.retry}`,
-      ]
-        .filter(Boolean)
-        .join('\n') + '\n\n'
-
-    await this.write(sseData)
-  }
-}
-
-const run = async (
-  stream: SSEStreamingApi,
-  cb: (stream: SSEStreamingApi) => Promise<void>,
-  onError?: (e: Error, stream: SSEStreamingApi) => Promise<void>
-) => {
-  try {
-    await cb(stream)
-  } catch (e) {
-    if (e instanceof Error && onError) {
-      await onError(e, stream)
-
-      await stream.writeSSE({
-        event: 'error',
-        data: e.message,
-      })
-    } else {
-      console.error(e)
-    }
-  } finally {
-    stream.close()
-  }
-}
-
-export const streamSSE = (
-  c: Context,
-  cb: (stream: SSEStreamingApi) => Promise<void>,
-  onError?: (e: Error, stream: SSEStreamingApi) => Promise<void>
-): Response => {
-  const { readable, writable } = new TransformStream()
-  const stream = new SSEStreamingApi(writable, readable)
-
-  c.header('Transfer-Encoding', 'chunked')
-  c.header('Content-Type', 'text/event-stream')
-  c.header('Cache-Control', 'no-cache')
-  c.header('Connection', 'keep-alive')
-
-  run(stream, cb, onError)
-
-  return c.newResponse(stream.responseReadable)
-}
diff --git a/deno_dist/helper/streaming/stream.ts b/deno_dist/helper/streaming/stream.ts
deleted file mode 100644
index 34ce0ca3a..000000000
--- a/deno_dist/helper/streaming/stream.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import type { Context } from '../../context.ts'
-import { StreamingApi } from '../../utils/stream.ts'
-
-export const stream = (
-  c: Context,
-  cb: (stream: StreamingApi) => Promise<void>,
-  onError?: (e: Error, stream: StreamingApi) => Promise<void>
-): Response => {
-  const { readable, writable } = new TransformStream()
-  const stream = new StreamingApi(writable, readable)
-  ;(async () => {
-    try {
-      await cb(stream)
-    } catch (e) {
-      if (e instanceof Error && onError) {
-        await onError(e, stream)
-      } else {
-        console.error(e)
-      }
-    } finally {
-      stream.close()
-    }
-  })()
-  return c.newResponse(stream.responseReadable)
-}
diff --git a/deno_dist/helper/streaming/text.ts b/deno_dist/helper/streaming/text.ts
deleted file mode 100644
index fbdd8a5fe..000000000
--- a/deno_dist/helper/streaming/text.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import type { Context } from '../../context.ts'
-import { TEXT_PLAIN } from '../../context.ts'
-import type { StreamingApi } from '../../utils/stream.ts'
-import { stream } from './index.ts'
-
-export const streamText = (
-  c: Context,
-  cb: (stream: StreamingApi) => Promise<void>,
-  onError?: (e: Error, stream: StreamingApi) => Promise<void>
-): Response => {
-  c.header('Content-Type', TEXT_PLAIN)
-  c.header('X-Content-Type-Options', 'nosniff')
-  c.header('Transfer-Encoding', 'chunked')
-  return stream(c, cb, onError)
-}
diff --git a/deno_dist/helper/testing/index.ts b/deno_dist/helper/testing/index.ts
deleted file mode 100644
index b542ef5dd..000000000
--- a/deno_dist/helper/testing/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { hc } from '../../client/index.ts'
-import type { Client } from '../../client/types.ts'
-import type { ExecutionContext } from '../../context.ts'
-import type { Hono } from '../../hono.ts'
-import type { UnionToIntersection } from '../../utils/types.ts'
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type ExtractEnv<T> = T extends Hono<infer E, any, any> ? E : never
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const testClient = <T extends Hono<any, any, any>>(
-  app: T,
-  Env?: ExtractEnv<T>['Bindings'] | {},
-  executionCtx?: ExecutionContext
-): UnionToIntersection<Client<T>> => {
-  const customFetch = (input: RequestInfo | URL, init?: RequestInit) => {
-    return app.request(input, init, Env, executionCtx)
-  }
-
-  return hc<typeof app>('http://localhost', { fetch: customFetch })
-}
diff --git a/deno_dist/helper/websocket/index.ts b/deno_dist/helper/websocket/index.ts
deleted file mode 100644
index f8089f630..000000000
--- a/deno_dist/helper/websocket/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { Context } from '../../context.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-/**
- * WebSocket Event Listeners type
- */
-export interface WSEvents {
-  onOpen?: (evt: Event, ws: WSContext) => void
-  onMessage?: (evt: MessageEvent<WSMessageReceive>, ws: WSContext) => void
-  onClose?: (evt: CloseEvent, ws: WSContext) => void
-  onError?: (evt: Event, ws: WSContext) => void
-}
-
-/**
- * Upgrade WebSocket Type
- */
-export type UpgradeWebSocket = (
-  createEvents: (c: Context) => WSEvents | Promise<WSEvents>
-) => MiddlewareHandler<
-  any,
-  string,
-  {
-    outputFormat: 'ws'
-  }
->
-
-export type WSReadyState = 0 | 1 | 2 | 3
-
-export type WSContext = {
-  send(
-    source: string | ArrayBuffer | Uint8Array,
-    options?: {
-      compress: boolean
-    }
-  ): void
-  raw?: unknown
-  binaryType: BinaryType
-  readyState: WSReadyState
-  url: URL | null
-  protocol: string | null
-  close(code?: number, reason?: string): void
-}
-
-export type WSMessageReceive = string | Blob | ArrayBufferLike
-
-export const createWSMessageEvent = (source: WSMessageReceive): MessageEvent<WSMessageReceive> => {
-  return new MessageEvent<WSMessageReceive>('message', {
-    data: source,
-  })
-}
diff --git a/deno_dist/hono-base.ts b/deno_dist/hono-base.ts
deleted file mode 100644
index 5a69e8055..000000000
--- a/deno_dist/hono-base.ts
+++ /dev/null
@@ -1,427 +0,0 @@
-import { compose } from './compose.ts'
-import { Context } from './context.ts'
-import type { ExecutionContext } from './context.ts'
-import { HTTPException } from './http-exception.ts'
-import { HonoRequest } from './request.ts'
-import type { Router } from './router.ts'
-import { METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE, METHODS } from './router.ts'
-import type {
-  Env,
-  ErrorHandler,
-  H,
-  HandlerInterface,
-  MiddlewareHandler,
-  MiddlewareHandlerInterface,
-  Next,
-  NotFoundHandler,
-  OnHandlerInterface,
-  MergePath,
-  MergeSchemaPath,
-  FetchEventLike,
-  Schema,
-  RouterRoute,
-} from './types.ts'
-import { getPath, getPathNoStrict, getQueryStrings, mergePath } from './utils/url.ts'
-
-export const COMPOSED_HANDLER = Symbol('composedHandler')
-
-type Methods = (typeof METHODS)[number] | typeof METHOD_NAME_ALL_LOWERCASE
-
-function defineDynamicClass(): {
-  new <E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(): {
-    [M in Methods]: HandlerInterface<E, M, S, BasePath>
-  } & {
-    on: OnHandlerInterface<E, S, BasePath>
-  } & {
-    use: MiddlewareHandlerInterface<E, S, BasePath>
-  }
-} {
-  return class {} as never
-}
-
-const notFoundHandler = (c: Context) => {
-  return c.text('404 Not Found', 404)
-}
-
-const errorHandler = (err: Error, c: Context) => {
-  if (err instanceof HTTPException) {
-    return err.getResponse()
-  }
-  console.error(err)
-  return c.text('Internal Server Error', 500)
-}
-
-type GetPath<E extends Env> = (request: Request, options?: { env?: E['Bindings'] }) => string
-
-export type HonoOptions<E extends Env> = {
-  /**
-   * `strict` option specifies whether to distinguish whether the last path is a directory or not.
-   * @default true
-   * @see https://hono.dev/api/hono#strict-mode
-   */
-  strict?: boolean
-  /**
-   * `router` option specifices which router to use.
-   * ```ts
-   * const app = new Hono({ router: new RegExpRouter() })
-   * ```
-   * @see https://hono.dev/api/hono#router-option
-   */
-  router?: Router<[H, RouterRoute]>
-  /**
-   * `getPath` can handle the host header value.
-   * @example
-   * ```ts
-   * const app = new Hono({
-   *  getPath: (req) =>
-   *   '/' + req.headers.get('host') + req.url.replace(/^https?:\/\/[^/]+(\/[^?]*)/, '$1'),
-   * })
-   *
-   * app.get('/www1.example.com/hello', () => c.text('hello www1'))
-   *
-   * // A following request will match the route:
-   * // new Request('http://www1.example.com/hello', {
-   * //  headers: { host: 'www1.example.com' },
-   * // })
-   * ```
-   * @see https://hono.dev/api/routing#routing-with-host-header-value
-   */
-  getPath?: GetPath<E>
-}
-
-class Hono<
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> extends defineDynamicClass()<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> = {}) {
-    super()
-
-    // Implementation of app.get(...handlers[]) or app.get(path, ...handlers[])
-    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) => {
-          if (typeof handler !== 'string') {
-            this.addRoute(method, this.#path, handler)
-          }
-        })
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        return this as any
-      }
-    })
-
-    // Implementation of app.on(method, path, ...handlers[])
-    this.on = (method: string | string[], path: string | string[], ...handlers: H[]) => {
-      if (!method) {
-        return this
-      }
-      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)
-          })
-        }
-      }
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      return this as any
-    }
-
-    // Implementation of app.use(...handlers[]) or app.use(path, ...handlers[])
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    this.use = (arg1: string | MiddlewareHandler<any>, ...handlers: MiddlewareHandler<any>[]) => {
-      if (typeof arg1 === 'string') {
-        this.#path = arg1
-      } else {
-        this.#path = '*'
-        handlers.unshift(arg1)
-      }
-      handlers.forEach((handler) => {
-        this.addRoute(METHOD_NAME_ALL, this.#path, handler)
-      })
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      return this as any
-    }
-
-    const strict = options.strict ?? true
-    delete options.strict
-    Object.assign(this, options)
-    this.getPath = strict ? options.getPath ?? getPath : getPathNoStrict
-  }
-
-  private clone(): Hono<E, S, BasePath> {
-    const clone = new Hono<E, S, BasePath>({
-      router: this.router,
-      getPath: this.getPath,
-    })
-    clone.routes = this.routes
-    return clone
-  }
-
-  private notFoundHandler: NotFoundHandler = notFoundHandler
-  private errorHandler: ErrorHandler = errorHandler
-
-  route<
-    SubPath extends string,
-    SubEnv extends Env,
-    SubSchema extends Schema,
-    SubBasePath extends string
-  >(
-    path: SubPath,
-    app?: Hono<SubEnv, SubSchema, SubBasePath>
-  ): Hono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath> {
-    const subApp = this.basePath(path)
-
-    if (!app) {
-      return subApp
-    }
-
-    app.routes.map((r) => {
-      let handler
-      if (app.errorHandler === errorHandler) {
-        handler = r.handler
-      } else {
-        handler = async (c: Context, next: Next) =>
-          (await compose<Context>([], app.errorHandler)(c, () => r.handler(c, next))).res
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        ;(handler as any)[COMPOSED_HANDLER] = r.handler
-      }
-
-      subApp.addRoute(r.method, r.path, handler)
-    })
-    return this
-  }
-
-  /**
-   * `.basePath()` allows base paths to be specified.
-   * @example
-   * ```ts
-   * const api = new Hono().basePath('/api')
-   * ```
-   * @see https://hono.dev/api/routing#base-path
-   */
-  basePath<SubPath extends string>(path: SubPath): Hono<E, S, MergePath<BasePath, SubPath>> {
-    const subApp = this.clone()
-    subApp._basePath = mergePath(this._basePath, path)
-    return subApp
-  }
-
-  /**
-   * `.onError()` handles an error and returns a customized Response.
-   * ```ts
-   * app.onError((err, c) => {
-   *   console.error(`${err}`)
-   *   return c.text('Custom Error Message', 500)
-   * })
-   * ```
-   */
-  onError = (handler: ErrorHandler<E>): Hono<E, S, BasePath> => {
-    this.errorHandler = handler
-    return this
-  }
-
-  /**
-   * `.notFound()` allows you to customize a Not Found Response.
-   * ```ts
-   * app.notFound((c) => {
-   *   return c.text('Custom 404 Message', 404)
-   * })
-   * ```
-   * @see https://hono.dev/api/hono#not-found
-   */
-  notFound = (handler: NotFoundHandler<E>): Hono<E, S, BasePath> => {
-    this.notFoundHandler = handler
-    return this
-  }
-
-  mount(
-    path: string,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>,
-    optionHandler?: (c: Context) => unknown
-  ): Hono<E, S, BasePath> {
-    const mergedPath = mergePath(this._basePath, path)
-    const pathPrefixLength = mergedPath === '/' ? 0 : mergedPath.length
-
-    const handler: MiddlewareHandler = async (c, next) => {
-      let executionContext: ExecutionContext | undefined = undefined
-      try {
-        executionContext = c.executionCtx
-      } catch {} // Do nothing
-      const options = optionHandler ? optionHandler(c) : [c.env, executionContext]
-      const optionsArray = Array.isArray(options) ? options : [options]
-
-      const queryStrings = getQueryStrings(c.req.url)
-      const res = await applicationHandler(
-        new Request(
-          new URL((c.req.path.slice(pathPrefixLength) || '/') + queryStrings, c.req.url),
-          c.req.raw
-        ),
-        ...optionsArray
-      )
-
-      if (res) {
-        return res
-      }
-
-      await next()
-    }
-    this.addRoute(METHOD_NAME_ALL, mergePath(path, '*'), handler)
-    return this
-  }
-
-  private addRoute(method: string, path: string, handler: H) {
-    method = method.toUpperCase()
-    path = mergePath(this._basePath, path)
-    const r: RouterRoute = { path: path, method: method, handler: handler }
-    this.router.add(method, path, [handler, r])
-    this.routes.push(r)
-  }
-
-  private matchRoute(method: string, path: string) {
-    return this.router.match(method, path)
-  }
-
-  private handleError(err: unknown, c: Context<E>) {
-    if (err instanceof Error) {
-      return this.errorHandler(err, c)
-    }
-    throw err
-  }
-
-  private dispatch(
-    request: Request,
-    executionCtx: ExecutionContext | FetchEventLike | undefined,
-    env: E['Bindings'],
-    method: string
-  ): Response | Promise<Response> {
-    // Handle HEAD method
-    if (method === 'HEAD') {
-      return (async () =>
-        new Response(null, await this.dispatch(request, executionCtx, env, 'GET')))()
-    }
-
-    const path = this.getPath(request, { env })
-    const matchResult = this.matchRoute(method, path)
-
-    const c = new Context(new HonoRequest(request, path, matchResult), {
-      env,
-      executionCtx,
-      notFoundHandler: this.notFoundHandler,
-    })
-
-    // 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
-    }
-
-    const composed = compose<Context>(matchResult[0], this.errorHandler, this.notFoundHandler)
-
-    return (async () => {
-      try {
-        const context = await composed(c)
-        if (!context.finalized) {
-          throw new Error(
-            'Context is not finalized. You may forget returning Response object or `await next()`'
-          )
-        }
-
-        return context.res
-      } catch (err) {
-        return this.handleError(err, c)
-      }
-    })()
-  }
-
-  /**
-   * `.fetch()` will be entry point of your app.
-   * @see https://hono.dev/api/hono#fetch
-   */
-  fetch: (
-    request: Request,
-    Env?: E['Bindings'] | {},
-    executionCtx?: ExecutionContext
-  ) => Response | Promise<Response> = (request, ...rest) => {
-    return this.dispatch(request, rest[1], rest[0], request.method)
-  }
-
-  /**
-   * `.request()` is a useful method for testing.
-   * You can pass a URL or pathname to send a GET request.
-   * app will return a Response object.
-   * ```ts
-   * test('GET /hello is ok', async () => {
-   *   const res = await app.request('/hello')
-   *   expect(res.status).toBe(200)
-   * })
-   * ```
-   * @see https://hono.dev/api/hono#request
-   */
-  request = (
-    input: RequestInfo | URL,
-    requestInit?: RequestInit,
-    Env?: E['Bindings'] | {},
-    executionCtx?: ExecutionContext
-  ): Response | Promise<Response> => {
-    if (input instanceof Request) {
-      if (requestInit !== undefined) {
-        input = new Request(input, requestInit)
-      }
-      return this.fetch(input, Env, executionCtx)
-    }
-    input = input.toString()
-    const path = /^https?:\/\//.test(input) ? input : `http://localhost${mergePath('/', input)}`
-    const req = new Request(path, requestInit)
-    return this.fetch(req, Env, executionCtx)
-  }
-
-  /**
-   * `.fire()` automatically adds a global fetch event listener.
-   * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
-   * @see https://hono.dev/api/hono#fire
-   * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
-   * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
-   */
-  fire = () => {
-    // @ts-expect-error `event` is not the type expected by addEventListener
-    addEventListener('fetch', (event: FetchEventLike): void => {
-      event.respondWith(this.dispatch(event.request, event, undefined, event.request.method))
-    })
-  }
-}
-
-export { Hono as HonoBase }
diff --git a/deno_dist/hono.ts b/deno_dist/hono.ts
deleted file mode 100644
index 522c18968..000000000
--- a/deno_dist/hono.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { HonoBase } from './hono-base.ts'
-import type { HonoOptions } from './hono-base.ts'
-import { RegExpRouter } from './router/reg-exp-router/index.ts'
-import { SmartRouter } from './router/smart-router/index.ts'
-import { TrieRouter } from './router/trie-router/index.ts'
-import type { BlankSchema, Env, Schema } from './types.ts'
-
-export class Hono<
-  E extends Env = Env,
-  S extends Schema = BlankSchema,
-  BasePath extends string = '/'
-> extends HonoBase<E, S, BasePath> {
-  constructor(options: HonoOptions<E> = {}) {
-    super(options)
-    this.router =
-      options.router ??
-      new SmartRouter({
-        routers: [new RegExpRouter(), new TrieRouter()],
-      })
-  }
-}
diff --git a/deno_dist/http-exception.ts b/deno_dist/http-exception.ts
deleted file mode 100644
index 553b77a35..000000000
--- a/deno_dist/http-exception.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import type { StatusCode } from './utils/http-status.ts'
-
-type HTTPExceptionOptions = {
-  res?: Response
-  message?: string
-  cause?: unknown
-}
-
-/**
- * `HTTPException` must be used when a fatal error such as authentication failure occurs.
- * @example
- * ```ts
- * import { HTTPException } from 'hono/http-exception'
- *
- * // ...
- *
- * app.post('/auth', async (c, next) => {
- *   // authentication
- *   if (authorized === false) {
- *     throw new HTTPException(401, { message: 'Custom error message' })
- *   }
- *   await next()
- * })
- * ```
- * @see https://hono.dev/api/exception
- */
-export class HTTPException extends Error {
-  readonly res?: Response
-  readonly status: StatusCode
-
-  constructor(status: StatusCode = 500, options?: HTTPExceptionOptions) {
-    super(options?.message, { cause: options?.cause })
-    this.res = options?.res
-    this.status = status
-  }
-
-  getResponse(): Response {
-    if (this.res) {
-      const newResponse = new Response(this.res.body, {
-        status: this.status,
-        headers: this.res.headers,
-      })
-      return newResponse
-    }
-    return new Response(this.message, {
-      status: this.status,
-    })
-  }
-}
diff --git a/deno_dist/jsx/base.ts b/deno_dist/jsx/base.ts
deleted file mode 100644
index 01afff680..000000000
--- a/deno_dist/jsx/base.ts
+++ /dev/null
@@ -1,361 +0,0 @@
-import { raw } from '../helper/html/index.ts'
-import { escapeToBuffer, stringBufferToString } from '../utils/html.ts'
-import type { StringBuffer, HtmlEscaped, HtmlEscapedString } from '../utils/html.ts'
-import type { Context } from './context.ts'
-import { globalContexts } from './context.ts'
-import type { IntrinsicElements as IntrinsicElementsDefined } from './intrinsic-elements.ts'
-import { normalizeIntrinsicElementProps, styleObjectForEach } from './utils.ts'
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type Props = Record<string, any>
-export type FC<P = Props> = {
-  (props: P): HtmlEscapedString | Promise<HtmlEscapedString>
-  defaultProps?: Partial<P> | undefined
-  displayName?: string | undefined
-}
-export type DOMAttributes = Hono.HTMLAttributes
-
-declare global {
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace JSX {
-    type Element = HtmlEscapedString | Promise<HtmlEscapedString>
-    interface ElementChildrenAttribute {
-      children: Child
-    }
-    interface IntrinsicElements extends IntrinsicElementsDefined {
-      [tagName: string]: Props
-    }
-  }
-}
-
-const emptyTags = [
-  'area',
-  'base',
-  'br',
-  'col',
-  'embed',
-  'hr',
-  'img',
-  'input',
-  'keygen',
-  'link',
-  'meta',
-  'param',
-  'source',
-  'track',
-  'wbr',
-]
-const booleanAttributes = [
-  'allowfullscreen',
-  'async',
-  'autofocus',
-  'autoplay',
-  'checked',
-  'controls',
-  'default',
-  'defer',
-  'disabled',
-  'formnovalidate',
-  'hidden',
-  'inert',
-  'ismap',
-  'itemscope',
-  'loop',
-  'multiple',
-  'muted',
-  'nomodule',
-  'novalidate',
-  'open',
-  'playsinline',
-  'readonly',
-  'required',
-  'reversed',
-  'selected',
-]
-
-const childrenToStringToBuffer = (children: Child[], buffer: StringBuffer): void => {
-  for (let i = 0, len = children.length; i < len; i++) {
-    const child = children[i]
-    if (typeof child === 'string') {
-      escapeToBuffer(child, buffer)
-    } else if (typeof child === 'boolean' || child === null || child === undefined) {
-      continue
-    } else if (child instanceof JSXNode) {
-      child.toStringToBuffer(buffer)
-    } else if (
-      typeof child === 'number' ||
-      (child as unknown as { isEscaped: boolean }).isEscaped
-    ) {
-      ;(buffer[0] as string) += child
-    } else if (child instanceof Promise) {
-      buffer.unshift('', child)
-    } else {
-      // `child` type is `Child[]`, so stringify recursively
-      childrenToStringToBuffer(child, buffer)
-    }
-  }
-}
-
-type LocalContexts = [Context<unknown>, unknown][]
-export type Child =
-  | string
-  | Promise<string>
-  | number
-  | JSXNode
-  | null
-  | undefined
-  | boolean
-  | Child[]
-export class JSXNode implements HtmlEscaped {
-  tag: string | Function
-  props: Props
-  key?: string
-  children: Child[]
-  isEscaped: true = true as const
-  localContexts?: LocalContexts
-  constructor(tag: string | Function, props: Props, children: Child[]) {
-    this.tag = tag
-    this.props = props
-    this.children = children
-  }
-
-  get type(): string | Function {
-    return this.tag as string
-  }
-
-  // Added for compatibility with libraries that rely on React's internal structure
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  get ref(): any {
-    return this.props.ref || null
-  }
-
-  toString(): string | Promise<string> {
-    const buffer: StringBuffer = ['']
-    this.localContexts?.forEach(([context, value]) => {
-      context.values.push(value)
-    })
-    try {
-      this.toStringToBuffer(buffer)
-    } finally {
-      this.localContexts?.forEach(([context]) => {
-        context.values.pop()
-      })
-    }
-    return buffer.length === 1 ? buffer[0] : stringBufferToString(buffer)
-  }
-
-  toStringToBuffer(buffer: StringBuffer): void {
-    const tag = this.tag as string
-    const props = this.props
-    let { children } = this
-
-    buffer[0] += `<${tag}`
-
-    const propsKeys = Object.keys(props || {})
-
-    for (let i = 0, len = propsKeys.length; i < len; i++) {
-      const key = propsKeys[i]
-      const v = props[key]
-      if (key === 'children') {
-        // skip children
-      } else if (key === 'style' && typeof v === 'object') {
-        // object to style strings
-        let styleStr = ''
-        styleObjectForEach(v, (property, value) => {
-          if (value != null) {
-            styleStr += `${styleStr ? ';' : ''}${property}:${value}`
-          }
-        })
-        buffer[0] += ' style="'
-        escapeToBuffer(styleStr, buffer)
-        buffer[0] += '"'
-      } else if (typeof v === 'string') {
-        buffer[0] += ` ${key}="`
-        escapeToBuffer(v, buffer)
-        buffer[0] += '"'
-      } else if (v === null || v === undefined) {
-        // Do nothing
-      } else if (typeof v === 'number' || (v as HtmlEscaped).isEscaped) {
-        buffer[0] += ` ${key}="${v}"`
-      } else if (typeof v === 'boolean' && booleanAttributes.includes(key)) {
-        if (v) {
-          buffer[0] += ` ${key}=""`
-        }
-      } else if (key === 'dangerouslySetInnerHTML') {
-        if (children.length > 0) {
-          throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
-        }
-
-        children = [raw(v.__html)]
-      } else if (v instanceof Promise) {
-        buffer[0] += ` ${key}="`
-        buffer.unshift('"', v)
-      } else if (typeof v === 'function') {
-        if (!key.startsWith('on')) {
-          throw `Invalid prop '${key}' of type 'function' supplied to '${tag}'.`
-        }
-        // maybe event handler for client components, just ignore in server components
-      } else {
-        buffer[0] += ` ${key}="`
-        escapeToBuffer(v.toString(), buffer)
-        buffer[0] += '"'
-      }
-    }
-
-    if (emptyTags.includes(tag as string) && children.length === 0) {
-      buffer[0] += '/>'
-      return
-    }
-
-    buffer[0] += '>'
-
-    childrenToStringToBuffer(children, buffer)
-
-    buffer[0] += `</${tag}>`
-  }
-}
-
-class JSXFunctionNode extends JSXNode {
-  toStringToBuffer(buffer: StringBuffer): void {
-    const { children } = this
-
-    const res = (this.tag as Function).call(null, {
-      ...this.props,
-      children: children.length <= 1 ? children[0] : children,
-    })
-
-    if (res instanceof Promise) {
-      if (globalContexts.length === 0) {
-        buffer.unshift('', res)
-      } else {
-        // save current contexts for resuming
-        const currentContexts: LocalContexts = globalContexts.map((c) => [c, c.values.at(-1)])
-        buffer.unshift(
-          '',
-          res.then((childRes) => {
-            if (childRes instanceof JSXNode) {
-              childRes.localContexts = currentContexts
-            }
-            return childRes
-          })
-        )
-      }
-    } else if (res instanceof JSXNode) {
-      res.toStringToBuffer(buffer)
-    } else if (typeof res === 'number' || (res as HtmlEscaped).isEscaped) {
-      buffer[0] += res
-    } else {
-      escapeToBuffer(res, buffer)
-    }
-  }
-}
-
-export class JSXFragmentNode extends JSXNode {
-  toStringToBuffer(buffer: StringBuffer): void {
-    childrenToStringToBuffer(this.children, buffer)
-  }
-}
-
-export const jsx = (
-  tag: string | Function,
-  props: Props | null,
-  ...children: (string | number | HtmlEscapedString)[]
-): JSXNode => {
-  props ??= {}
-  if (children.length) {
-    props.children = children.length === 1 ? children[0] : children
-  }
-
-  const key = props.key
-  delete props['key']
-
-  const node = jsxFn(tag, props, children)
-  node.key = key
-  return node
-}
-
-export const jsxFn = (
-  tag: string | Function,
-  props: Props,
-  children: (string | number | HtmlEscapedString)[]
-): JSXNode => {
-  if (typeof tag === 'function') {
-    return new JSXFunctionNode(tag, props, children)
-  } else {
-    normalizeIntrinsicElementProps(props)
-    return new JSXNode(tag, props, children)
-  }
-}
-
-const shallowEqual = (a: Props, b: Props): boolean => {
-  if (a === b) {
-    return true
-  }
-
-  const aKeys = Object.keys(a).sort()
-  const bKeys = Object.keys(b).sort()
-  if (aKeys.length !== bKeys.length) {
-    return false
-  }
-
-  for (let i = 0, len = aKeys.length; i < len; i++) {
-    if (
-      aKeys[i] === 'children' &&
-      bKeys[i] === 'children' &&
-      !a.children?.length &&
-      !b.children?.length
-    ) {
-      continue
-    } else if (a[aKeys[i]] !== b[aKeys[i]]) {
-      return false
-    }
-  }
-
-  return true
-}
-
-export const memo = <T>(
-  component: FC<T>,
-  propsAreEqual: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean = shallowEqual
-): FC<T> => {
-  let computed: HtmlEscapedString | Promise<HtmlEscapedString> | undefined = undefined
-  let prevProps: T | undefined = undefined
-  return ((props: T & { children?: Child }): HtmlEscapedString | Promise<HtmlEscapedString> => {
-    if (prevProps && !propsAreEqual(prevProps, props)) {
-      computed = undefined
-    }
-    prevProps = props
-    return (computed ||= component(props))
-  }) as FC<T>
-}
-
-export const Fragment = ({
-  children,
-}: {
-  key?: string
-  children?: Child | HtmlEscapedString
-}): HtmlEscapedString => {
-  return new JSXFragmentNode(
-    '',
-    {
-      children,
-    },
-    Array.isArray(children) ? children : children ? [children] : []
-  ) as never
-}
-
-export const isValidElement = (element: unknown): element is JSXNode => {
-  return !!(element && typeof element === 'object' && 'tag' in element && 'props' in element)
-}
-
-export const cloneElement = <T extends JSXNode | JSX.Element>(
-  element: T,
-  props: Partial<Props>,
-  ...children: Child[]
-): T => {
-  return jsx(
-    (element as JSXNode).tag,
-    { ...(element as JSXNode).props, ...props },
-    ...(children as (string | number | HtmlEscapedString)[])
-  ) as T
-}
diff --git a/deno_dist/jsx/children.ts b/deno_dist/jsx/children.ts
deleted file mode 100644
index 377bdeb3c..000000000
--- a/deno_dist/jsx/children.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { Child } from './base.ts'
-
-export const toArray = (children: Child): Child[] =>
-  Array.isArray(children) ? children : [children]
-export const Children = {
-  map: (children: Child[], fn: (child: Child, index: number) => Child): Child[] =>
-    toArray(children).map(fn),
-  forEach: (children: Child[], fn: (child: Child, index: number) => void): void => {
-    toArray(children).forEach(fn)
-  },
-  count: (children: Child[]): number => toArray(children).length,
-  only: (_children: Child[]): Child => {
-    const children = toArray(_children)
-    if (children.length !== 1) {
-      throw new Error('Children.only() expects only one child')
-    }
-    return children[0]
-  },
-  toArray,
-}
diff --git a/deno_dist/jsx/components.ts b/deno_dist/jsx/components.ts
deleted file mode 100644
index 00ac0d99c..000000000
--- a/deno_dist/jsx/components.ts
+++ /dev/null
@@ -1,189 +0,0 @@
-import { raw } from '../helper/html/index.ts'
-import type { HtmlEscapedString, HtmlEscapedCallback } from '../utils/html.ts'
-import { HtmlEscapedCallbackPhase, resolveCallback } from '../utils/html.ts'
-import { DOM_RENDERER } from './constants.ts'
-import { ErrorBoundary as ErrorBoundaryDomRenderer } from './dom/components.ts'
-import type { HasRenderToDom } from './dom/render.ts'
-import type { FC, PropsWithChildren, Child } from './index.ts'
-
-let errorBoundaryCounter = 0
-
-export const childrenToString = async (children: Child[]): Promise<HtmlEscapedString[]> => {
-  try {
-    return children
-      .flat()
-      .map((c) => (c == null || typeof c === 'boolean' ? '' : c.toString())) as HtmlEscapedString[]
-  } catch (e) {
-    if (e instanceof Promise) {
-      await e
-      return childrenToString(children)
-    } else {
-      throw e
-    }
-  }
-}
-
-export type ErrorHandler = (error: Error) => void
-export type FallbackRender = (error: Error) => Child
-
-/**
- * @experimental
- * `ErrorBoundary` is an experimental feature.
- * The API might be changed.
- */
-export const ErrorBoundary: FC<
-  PropsWithChildren<{
-    fallback?: Child
-    fallbackRender?: FallbackRender
-    onError?: ErrorHandler
-  }>
-> = async ({ children, fallback, fallbackRender, onError }) => {
-  if (!children) {
-    return raw('')
-  }
-
-  if (!Array.isArray(children)) {
-    children = [children]
-  }
-
-  let fallbackStr: string | undefined
-  const fallbackRes = (error: Error): HtmlEscapedString => {
-    onError?.(error)
-    return (fallbackStr || fallbackRender?.(error) || '').toString() as HtmlEscapedString
-  }
-  let resArray: HtmlEscapedString[] | Promise<HtmlEscapedString[]>[] = []
-  try {
-    resArray = children.map((c) =>
-      c == null || typeof c === 'boolean' ? '' : c.toString()
-    ) as HtmlEscapedString[]
-  } catch (e) {
-    fallbackStr = await fallback?.toString()
-    if (e instanceof Promise) {
-      resArray = [
-        e.then(() => childrenToString(children as Child[])).catch((e) => fallbackRes(e)),
-      ] as Promise<HtmlEscapedString[]>[]
-    } else {
-      resArray = [fallbackRes(e as Error)]
-    }
-  }
-
-  if (resArray.some((res) => (res as {}) instanceof Promise)) {
-    fallbackStr ||= await fallback?.toString()
-    const index = errorBoundaryCounter++
-    const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`)
-    const caught = false
-    const catchCallback = ({ error, buffer }: { error: Error; buffer?: [string] }) => {
-      if (caught) {
-        return ''
-      }
-
-      const fallbackResString = fallbackRes(error)
-      if (buffer) {
-        buffer[0] = buffer[0].replace(replaceRe, fallbackResString)
-      }
-      return buffer
-        ? ''
-        : `<template data-hono-target="E:${index}">${fallbackResString}</template><script>
-((d,c,n) => {
-c=d.currentScript.previousSibling
-d=d.getElementById('E:${index}')
-if(!d)return
-do{n=d.nextSibling;n.remove()}while(n.nodeType!=8||n.nodeValue!='E:${index}')
-d.replaceWith(c.content)
-})(document)
-</script>`
-    }
-    return raw(`<template id="E:${index}"></template><!--E:${index}-->`, [
-      ({ phase, buffer, context }) => {
-        if (phase === HtmlEscapedCallbackPhase.BeforeStream) {
-          return
-        }
-        return Promise.all(resArray)
-          .then(async (htmlArray) => {
-            htmlArray = htmlArray.flat()
-            const content = htmlArray.join('')
-            let html = buffer
-              ? ''
-              : `<template data-hono-target="E:${index}">${content}</template><script>
-((d,c) => {
-c=d.currentScript.previousSibling
-d=d.getElementById('E:${index}')
-if(!d)return
-d.parentElement.insertBefore(c.content,d.nextSibling)
-})(document)
-</script>`
-
-            if (htmlArray.every((html) => !(html as HtmlEscapedString).callbacks?.length)) {
-              if (buffer) {
-                buffer[0] = buffer[0].replace(replaceRe, content)
-              }
-              return html
-            }
-
-            if (buffer) {
-              buffer[0] = buffer[0].replace(
-                replaceRe,
-                (_all, pre, _, post) => `${pre}${content}${post}`
-              )
-            }
-
-            const callbacks = htmlArray
-              .map((html) => (html as HtmlEscapedString).callbacks || [])
-              .flat()
-
-            if (phase === HtmlEscapedCallbackPhase.Stream) {
-              html = await resolveCallback(
-                html,
-                HtmlEscapedCallbackPhase.BeforeStream,
-                true,
-                context
-              )
-            }
-
-            let resolvedCount = 0
-            const promises = callbacks.map<HtmlEscapedCallback>(
-              (c) =>
-                (...args) =>
-                  c(...args)
-                    ?.then((content) => {
-                      resolvedCount++
-
-                      if (buffer) {
-                        if (resolvedCount === callbacks.length) {
-                          buffer[0] = buffer[0].replace(replaceRe, (_all, _pre, content) => content)
-                        }
-                        buffer[0] += content
-                        return raw('', (content as HtmlEscapedString).callbacks)
-                      }
-
-                      return raw(
-                        content +
-                          (resolvedCount !== callbacks.length
-                            ? ''
-                            : `<script>
-((d,c,n) => {
-d=d.getElementById('E:${index}')
-if(!d)return
-n=d.nextSibling
-while(n.nodeType!=8||n.nodeValue!='E:${index}'){n=n.nextSibling}
-n.remove()
-d.remove()
-})(document)
-</script>`),
-                        (content as HtmlEscapedString).callbacks
-                      )
-                    })
-                    .catch((error) => catchCallback({ error, buffer }))
-            )
-
-            // eslint-disable-next-line @typescript-eslint/no-explicit-any
-            return raw(html, promises as any)
-          })
-          .catch((error) => catchCallback({ error, buffer }))
-      },
-    ])
-  } else {
-    return raw(resArray.join(''))
-  }
-}
-;(ErrorBoundary as HasRenderToDom)[DOM_RENDERER] = ErrorBoundaryDomRenderer
diff --git a/deno_dist/jsx/constants.ts b/deno_dist/jsx/constants.ts
deleted file mode 100644
index 1c5a37df7..000000000
--- a/deno_dist/jsx/constants.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const DOM_RENDERER = Symbol('RENDERER')
-export const DOM_ERROR_HANDLER = Symbol('ERROR_HANDLER')
-export const DOM_STASH = Symbol('STASH')
-export const DOM_INTERNAL_TAG = Symbol('INTERNAL')
diff --git a/deno_dist/jsx/context.ts b/deno_dist/jsx/context.ts
deleted file mode 100644
index 55a8a98de..000000000
--- a/deno_dist/jsx/context.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { raw } from '../helper/html/index.ts'
-import type { HtmlEscapedString } from '../utils/html.ts'
-import { JSXFragmentNode } from './base.ts'
-import { DOM_RENDERER } from './constants.ts'
-import { createContextProviderFunction } from './dom/context.ts'
-import type { FC, PropsWithChildren } from './index.ts'
-
-export interface Context<T> {
-  values: T[]
-  Provider: FC<PropsWithChildren<{ value: T }>>
-}
-
-export const globalContexts: Context<unknown>[] = []
-
-export const createContext = <T>(defaultValue: T): Context<T> => {
-  const values = [defaultValue]
-  const context: Context<T> = {
-    values,
-    Provider(props): HtmlEscapedString | Promise<HtmlEscapedString> {
-      values.push(props.value)
-      let string
-      try {
-        string = props.children
-          ? (Array.isArray(props.children)
-              ? new JSXFragmentNode('', {}, props.children)
-              : props.children
-            ).toString()
-          : ''
-      } finally {
-        values.pop()
-      }
-
-      if (string instanceof Promise) {
-        return string.then((resString) =>
-          raw(resString, (resString as HtmlEscapedString).callbacks)
-        )
-      } else {
-        return raw(string)
-      }
-    },
-  }
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  ;(context.Provider as any)[DOM_RENDERER] = createContextProviderFunction(values)
-
-  globalContexts.push(context as Context<unknown>)
-
-  return context
-}
-
-export const useContext = <T>(context: Context<T>): T => {
-  return context.values.at(-1) as T
-}
diff --git a/deno_dist/jsx/dom/components.ts b/deno_dist/jsx/dom/components.ts
deleted file mode 100644
index fe90977c2..000000000
--- a/deno_dist/jsx/dom/components.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import type { FC, PropsWithChildren, Child } from '../index.ts'
-import type { FallbackRender, ErrorHandler } from '../components.ts'
-import { DOM_ERROR_HANDLER } from '../constants.ts'
-import { Fragment } from './jsx-runtime.ts'
-
-/* eslint-disable @typescript-eslint/no-explicit-any */
-export const ErrorBoundary: FC<
-  PropsWithChildren<{
-    fallback?: Child
-    fallbackRender?: FallbackRender
-    onError?: ErrorHandler
-  }>
-> = (({ children, fallback, fallbackRender, onError }: any) => {
-  const res = Fragment({ children })
-  ;(res as any)[DOM_ERROR_HANDLER] = (err: any) => {
-    if (err instanceof Promise) {
-      throw err
-    }
-    onError?.(err)
-    return fallbackRender?.(err) || fallback
-  }
-  return res
-}) as any
-
-export const Suspense: FC<PropsWithChildren<{ fallback: any }>> = (({
-  children,
-  fallback,
-}: any) => {
-  const res = Fragment({ children })
-  ;(res as any)[DOM_ERROR_HANDLER] = (err: any, retry: () => void) => {
-    if (!(err instanceof Promise)) {
-      throw err
-    }
-    err.finally(retry)
-    return fallback
-  }
-  return res
-}) as any
-/* eslint-enable @typescript-eslint/no-explicit-any */
diff --git a/deno_dist/jsx/dom/context.ts b/deno_dist/jsx/dom/context.ts
deleted file mode 100644
index 0089d052b..000000000
--- a/deno_dist/jsx/dom/context.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { Child } from '../base.ts'
-import { DOM_ERROR_HANDLER } from '../constants.ts'
-import type { Context } from '../context.ts'
-import { globalContexts } from '../context.ts'
-import { Fragment } from './jsx-runtime.ts'
-import { setInternalTagFlag } from './utils.ts'
-
-export const createContextProviderFunction = <T>(values: T[]): Function =>
-  setInternalTagFlag(({ value, children }: { value: T; children: Child[] }) => {
-    if (!children) {
-      return undefined
-    }
-
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    const props: { children: any } = {
-      children: [
-        {
-          tag: setInternalTagFlag(() => {
-            values.push(value)
-          }),
-          props: {},
-        },
-      ],
-    }
-    if (Array.isArray(children)) {
-      props.children.push(...children.flat())
-    } else {
-      props.children.push(children)
-    }
-    props.children.push({
-      tag: setInternalTagFlag(() => {
-        values.pop()
-      }),
-      props: {},
-    })
-    const res = Fragment(props)
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    ;(res as any)[DOM_ERROR_HANDLER] = (err: unknown) => {
-      values.pop()
-      throw err
-    }
-    return res
-  })
-
-export const createContext = <T>(defaultValue: T): Context<T> => {
-  const values = [defaultValue]
-  const context = {
-    values,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    Provider: createContextProviderFunction(values) as any,
-  }
-  globalContexts.push(context)
-  return context
-}
diff --git a/deno_dist/jsx/dom/css.ts b/deno_dist/jsx/dom/css.ts
deleted file mode 100644
index 338c078d2..000000000
--- a/deno_dist/jsx/dom/css.ts
+++ /dev/null
@@ -1,220 +0,0 @@
-import type { FC, PropsWithChildren } from '../index.ts'
-import type { CssClassName, CssVariableType } from '../../helper/css/common.ts'
-import {
-  SELECTOR,
-  CLASS_NAME,
-  STYLE_STRING,
-  SELECTORS,
-  PSEUDO_GLOBAL_SELECTOR,
-  DEFAULT_STYLE_ID,
-  cssCommon,
-  cxCommon,
-  keyframesCommon,
-  viewTransitionCommon,
-} from '../../helper/css/common.ts'
-export { rawCssString } from '../../helper/css/common.ts'
-
-const splitRule = (rule: string): string[] => {
-  const result: string[] = []
-  let startPos = 0
-  let depth = 0
-  for (let i = 0, len = rule.length; i < len; i++) {
-    const char = rule[i]
-
-    // consume quote
-    // eslint-disable-next-line quotes
-    if (char === "'" || char === '"') {
-      const quote = char
-      i++
-      for (; i < len; i++) {
-        if (rule[i] === '\\') {
-          i++
-          continue
-        }
-        if (rule[i] === quote) {
-          break
-        }
-      }
-      continue
-    }
-
-    // comments are removed from the rule in advance
-
-    if (char === '{') {
-      depth++
-      continue
-    }
-    if (char === '}') {
-      depth--
-      if (depth === 0) {
-        result.push(rule.slice(startPos, i + 1))
-        startPos = i + 1
-      }
-      continue
-    }
-  }
-  return result
-}
-
-interface CreateCssJsxDomObjectsType {
-  (args: { id: Readonly<string> }): readonly [
-    {
-      toString(this: CssClassName): string
-    },
-    FC<PropsWithChildren<void>>
-  ]
-}
-
-export const createCssJsxDomObjects: CreateCssJsxDomObjectsType = ({ id }) => {
-  let styleSheet: CSSStyleSheet | null | undefined = undefined
-  const findStyleSheet = (): [CSSStyleSheet, Set<string>] | [] => {
-    if (!styleSheet) {
-      styleSheet = document.querySelector<HTMLStyleElement>(`style#${id}`)
-        ?.sheet as CSSStyleSheet | null
-      if (styleSheet) {
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        ;(styleSheet as any).addedStyles = new Set<string>()
-      }
-    }
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return styleSheet ? [styleSheet, (styleSheet as any).addedStyles] : []
-  }
-
-  const insertRule = (className: string, styleString: string) => {
-    const [sheet, addedStyles] = findStyleSheet()
-    if (!sheet || !addedStyles) {
-      Promise.resolve().then(() => {
-        if (!findStyleSheet()[0]) {
-          throw new Error('style sheet not found')
-        }
-        insertRule(className, styleString)
-      })
-      return
-    }
-
-    if (!addedStyles.has(className)) {
-      addedStyles.add(className)
-      ;(className.startsWith(PSEUDO_GLOBAL_SELECTOR)
-        ? splitRule(styleString)
-        : [`${className[0] === '@' ? '' : '.'}${className}{${styleString}}`]
-      ).forEach((rule) => {
-        sheet.insertRule(rule, sheet.cssRules.length)
-      })
-    }
-  }
-
-  const cssObject = {
-    toString(this: CssClassName): string {
-      const selector = this[SELECTOR]
-      insertRule(selector, this[STYLE_STRING])
-      this[SELECTORS].forEach(({ [CLASS_NAME]: className, [STYLE_STRING]: styleString }) => {
-        insertRule(className, styleString)
-      })
-
-      return this[CLASS_NAME]
-    },
-  }
-
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const Style: FC<PropsWithChildren<void>> = ({ children }) =>
-    ({
-      tag: 'style',
-      props: {
-        id,
-        children:
-          children &&
-          (Array.isArray(children) ? children : [children]).map(
-            (c) => (c as unknown as CssClassName)[STYLE_STRING]
-          ),
-      },
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    } as any)
-
-  return [cssObject, Style] as const
-}
-
-/**
- * @experimental
- * `createCssContext` is an experimental feature.
- * The API might be changed.
- */
-export const createCssContext = ({ id }: { id: Readonly<string> }) => {
-  const [cssObject, Style] = createCssJsxDomObjects({ id })
-
-  const newCssClassNameObject = (cssClassName: CssClassName): string => {
-    // eslint-disable-next-line @typescript-eslint/unbound-method
-    cssClassName.toString = cssObject.toString
-    return cssClassName as unknown as string
-  }
-
-  const css = (strings: TemplateStringsArray, ...values: CssVariableType[]): string => {
-    return newCssClassNameObject(cssCommon(strings, values))
-  }
-
-  const cx = (...args: (string | boolean | null | undefined)[]): string => {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    args = cxCommon(args as any) as any
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return css(Array(args.length).fill('') as any, ...args)
-  }
-
-  const keyframes = keyframesCommon
-
-  type ViewTransitionType = {
-    (strings: TemplateStringsArray, ...values: CssVariableType[]): string
-    (content: string): string
-    (): string
-  }
-  const viewTransition: ViewTransitionType = ((
-    strings: TemplateStringsArray | string | undefined,
-    ...values: CssVariableType[]
-  ) => {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return newCssClassNameObject(viewTransitionCommon(strings as any, values))
-  }) as ViewTransitionType
-
-  return {
-    css,
-    cx,
-    keyframes,
-    viewTransition,
-    Style,
-  }
-}
-
-const defaultContext = createCssContext({ id: DEFAULT_STYLE_ID })
-
-/**
- * @experimental
- * `css` is an experimental feature.
- * The API might be changed.
- */
-export const css = defaultContext.css
-
-/**
- * @experimental
- * `cx` is an experimental feature.
- * The API might be changed.
- */
-export const cx = defaultContext.cx
-
-/**
- * @experimental
- * `keyframes` is an experimental feature.
- * The API might be changed.
- */
-export const keyframes = defaultContext.keyframes
-
-/**
- * @experimental
- * `viewTransition` is an experimental feature.
- * The API might be changed.
- */
-export const viewTransition = defaultContext.viewTransition
-
-/**
- * @experimental
- * `Style` is an experimental feature.
- * The API might be changed.
- */
-export const Style = defaultContext.Style
diff --git a/deno_dist/jsx/dom/index.ts b/deno_dist/jsx/dom/index.ts
deleted file mode 100644
index f7b252b77..000000000
--- a/deno_dist/jsx/dom/index.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-import type { Props, Child, DOMAttributes, JSXNode } from '../base.ts'
-import { memo, isValidElement } from '../base.ts'
-import { Children } from '../children.ts'
-import { useContext } from '../context.ts'
-import {
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  useReducer,
-  useId,
-  useDebugValue,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-} from '../hooks/index.ts'
-import { Suspense, ErrorBoundary } from './components.ts'
-import { createContext } from './context.ts'
-import { jsx, Fragment } from './jsx-runtime.ts'
-import { flushSync, createPortal } from './render.ts'
-
-export { render } from './render.ts'
-
-const createElement = (
-  tag: string | ((props: Props) => JSXNode),
-  props: Props | null,
-  ...children: Child[]
-): JSXNode => {
-  const jsxProps: Props = props ? { ...props } : {}
-  if (children.length) {
-    jsxProps.children = children.length === 1 ? children[0] : children
-  }
-
-  let key = undefined
-  if ('key' in jsxProps) {
-    key = jsxProps.key
-    delete jsxProps.key
-  }
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  return jsx(tag, jsxProps, key) as any
-}
-
-const cloneElement = <T extends JSXNode | JSX.Element>(
-  element: T,
-  props: Props,
-  ...children: Child[]
-): T => {
-  return jsx(
-    (element as JSXNode).tag,
-    {
-      ...(element as JSXNode).props,
-      ...props,
-      children: children.length ? children : (element as JSXNode).props.children,
-    },
-    (element as JSXNode).key
-  ) as T
-}
-
-export {
-  createElement as jsx,
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  useReducer,
-  useId,
-  useDebugValue,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-  Suspense,
-  ErrorBoundary,
-  createContext,
-  useContext,
-  memo,
-  isValidElement,
-  createElement,
-  cloneElement,
-  Children,
-  Fragment,
-  DOMAttributes,
-  flushSync,
-  createPortal,
-}
-
-export default {
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  useReducer,
-  useId,
-  useDebugValue,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-  Suspense,
-  ErrorBoundary,
-  createContext,
-  useContext,
-  memo,
-  isValidElement,
-  createElement,
-  cloneElement,
-  Children,
-  Fragment,
-  flushSync,
-  createPortal,
-}
-
-export type { Context } from '../context.ts'
-
-// TODO: change to `export type *` after denoify bug is fixed
-// https://github.com/garronej/denoify/issues/124
-export * from '../types.ts'
diff --git a/deno_dist/jsx/dom/jsx-dev-runtime.ts b/deno_dist/jsx/dom/jsx-dev-runtime.ts
deleted file mode 100644
index f356271e2..000000000
--- a/deno_dist/jsx/dom/jsx-dev-runtime.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { Props, JSXNode } from '../base.ts'
-import { normalizeIntrinsicElementProps } from '../utils.ts'
-import { newJSXNode } from './utils.ts'
-
-export const jsxDEV = (tag: string | Function, props: Props, key?: string): JSXNode => {
-  if (typeof tag === 'string') {
-    normalizeIntrinsicElementProps(props)
-  }
-  return newJSXNode({
-    tag,
-    props,
-    key,
-  })
-}
-
-export const Fragment = (props: Record<string, unknown>): JSXNode => jsxDEV('', props, undefined)
diff --git a/deno_dist/jsx/dom/jsx-runtime.ts b/deno_dist/jsx/dom/jsx-runtime.ts
deleted file mode 100644
index 16a57c172..000000000
--- a/deno_dist/jsx/dom/jsx-runtime.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { jsxDEV as jsx, Fragment } from './jsx-dev-runtime.ts'
-export { jsxDEV as jsxs } from './jsx-dev-runtime.ts'
diff --git a/deno_dist/jsx/dom/render.ts b/deno_dist/jsx/dom/render.ts
deleted file mode 100644
index a19c8b11c..000000000
--- a/deno_dist/jsx/dom/render.ts
+++ /dev/null
@@ -1,628 +0,0 @@
-import type { JSXNode } from '../base.ts'
-import type { FC, Child, Props } from '../base.ts'
-import { toArray } from '../children.ts'
-import { DOM_RENDERER, DOM_ERROR_HANDLER, DOM_STASH, DOM_INTERNAL_TAG } from '../constants.ts'
-import type { Context as JSXContext } from '../context.ts'
-import { globalContexts as globalJSXContexts, useContext } from '../context.ts'
-import type { EffectData } from '../hooks/index.ts'
-import { STASH_EFFECT } from '../hooks/index.ts'
-import { styleObjectForEach } from '../utils.ts'
-import { createContext } from './context.ts' // import dom-specific versions
-import { newJSXNode } from './utils.ts'
-
-const HONO_PORTAL_ELEMENT = '_hp'
-
-const eventAliasMap: Record<string, string> = {
-  Change: 'Input',
-  DoubleClick: 'DblClick',
-} as const
-
-const nameSpaceMap: Record<string, string> = {
-  svg: 'http://www.w3.org/2000/svg',
-  math: 'http://www.w3.org/1998/Math/MathML',
-} as const
-
-const skipProps = new Set(['children'])
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type HasRenderToDom = FC<any> & { [DOM_RENDERER]: FC<any> }
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type ErrorHandler = (error: any, retry: () => void) => Child | undefined
-
-type Container = HTMLElement | DocumentFragment
-type LocalJSXContexts = [JSXContext<unknown>, unknown][] | undefined
-type SupportedElement = HTMLElement | SVGElement | MathMLElement
-
-export type NodeObject = {
-  pP: Props | undefined // previous props
-  nN: Node | undefined // next node
-  vC: Node[] // virtual dom children
-  vR: Node[] // virtual dom children to remove
-  s?: Node[] // shadow virtual dom children
-  n?: string // namespace
-  c: Container | undefined // container
-  e: SupportedElement | Text | undefined // rendered element
-  [DOM_STASH]:
-    | [
-        number, // current hook index
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        any[][], // stash for hooks
-        LocalJSXContexts // context
-      ]
-    | [
-        number,
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        any[][]
-      ]
-} & JSXNode
-type NodeString = {
-  t: string // text content
-  d: boolean // is dirty
-} & {
-  e?: Text
-  // like a NodeObject
-  vC: undefined
-  nN: undefined
-  // from JSXNode
-  key: undefined
-  tag: undefined
-}
-export type Node = NodeString | NodeObject
-
-export type PendingType =
-  | 0 // no pending
-  | 1 // global
-  | 2 // hook
-export type UpdateHook = (
-  context: Context,
-  node: Node,
-  cb: (context: Context) => void
-) => Promise<void>
-export type Context =
-  | [
-      PendingType, // PendingType
-      boolean, // got an error
-      UpdateHook, // update hook
-      boolean, // is in view transition
-      boolean // is in top level render
-    ]
-  | [PendingType, boolean, UpdateHook, boolean]
-  | [PendingType, boolean, UpdateHook]
-  | [PendingType, boolean]
-  | [PendingType]
-  | []
-
-export const buildDataStack: [Context, Node][] = []
-
-let nameSpaceContext: JSXContext<string> | undefined = undefined
-
-const isNodeString = (node: Node): node is NodeString => 't' in (node as NodeString)
-
-const getEventSpec = (key: string): [string, boolean] | undefined => {
-  const match = key.match(/^on([A-Z][a-zA-Z]+?(?:PointerCapture)?)(Capture)?$/)
-  if (match) {
-    const [, eventName, capture] = match
-    return [(eventAliasMap[eventName] || eventName).toLowerCase(), !!capture]
-  }
-  return undefined
-}
-
-const toAttributeName = (element: SupportedElement, key: string): string =>
-  element instanceof SVGElement &&
-  /[A-Z]/.test(key) &&
-  (key in element.style || // Presentation attributes are findable in style object. "clip-path", "font-size", "stroke-width", etc.
-    key.match(/^(?:o|pai|str|u|ve)/)) // Other un-deprecated kebab-case attributes. "overline-position", "paint-order", "strikethrough-position", etc.
-    ? key.replace(/([A-Z])/g, '-$1').toLowerCase()
-    : key
-
-const applyProps = (container: SupportedElement, attributes: Props, oldAttributes?: Props) => {
-  attributes ||= {}
-  for (const [key, value] of Object.entries(attributes)) {
-    if (!skipProps.has(key) && (!oldAttributes || oldAttributes[key] !== value)) {
-      const eventSpec = getEventSpec(key)
-      if (eventSpec) {
-        if (oldAttributes) {
-          container.removeEventListener(eventSpec[0], oldAttributes[key], eventSpec[1])
-        }
-        if (value != null) {
-          if (typeof value !== 'function') {
-            throw new Error(`Event handler for "${key}" is not a function`)
-          }
-          container.addEventListener(eventSpec[0], value, eventSpec[1])
-        }
-      } else if (key === 'dangerouslySetInnerHTML' && value) {
-        container.innerHTML = value.__html
-      } else if (key === 'ref') {
-        if (typeof value === 'function') {
-          value(container)
-        } else if (value && 'current' in value) {
-          value.current = container
-        }
-      } else if (key === 'style') {
-        const style = container.style
-        if (typeof value === 'string') {
-          style.cssText = value
-        } else {
-          style.cssText = ''
-          if (value != null) {
-            styleObjectForEach(value, style.setProperty.bind(style))
-          }
-        }
-      } else {
-        const nodeName = container.nodeName
-        if (key === 'value') {
-          if (nodeName === 'INPUT' || nodeName === 'TEXTAREA' || nodeName === 'SELECT') {
-            ;(container as HTMLInputElement).value =
-              value === null || value === undefined || value === false ? null : value
-
-            if (nodeName === 'TEXTAREA') {
-              container.textContent = value
-              continue
-            } else if (nodeName === 'SELECT') {
-              if ((container as HTMLSelectElement).selectedIndex === -1) {
-                ;(container as HTMLSelectElement).selectedIndex = 0
-              }
-              continue
-            }
-          }
-        } else if (
-          (key === 'checked' && nodeName === 'INPUT') ||
-          (key === 'selected' && nodeName === 'OPTION')
-        ) {
-          // eslint-disable-next-line @typescript-eslint/no-explicit-any
-          ;(container as any)[key] = value
-        }
-
-        const k = toAttributeName(container, key)
-
-        if (value === null || value === undefined || value === false) {
-          container.removeAttribute(k)
-        } else if (value === true) {
-          container.setAttribute(k, '')
-        } else if (typeof value === 'string' || typeof value === 'number') {
-          container.setAttribute(k, value as string)
-        } else {
-          container.setAttribute(k, value.toString())
-        }
-      }
-    }
-  }
-  if (oldAttributes) {
-    for (const [key, value] of Object.entries(oldAttributes)) {
-      if (!skipProps.has(key) && !(key in attributes)) {
-        const eventSpec = getEventSpec(key)
-        if (eventSpec) {
-          container.removeEventListener(eventSpec[0], value, eventSpec[1])
-        } else if (key === 'ref') {
-          if (typeof value === 'function') {
-            value(null)
-          } else {
-            value.current = null
-          }
-        } else {
-          container.removeAttribute(toAttributeName(container, key))
-        }
-      }
-    }
-  }
-}
-
-const invokeTag = (context: Context, node: NodeObject): Child[] => {
-  if (node.s) {
-    const res = node.s
-    node.s = undefined
-    return res as Child[]
-  }
-
-  node[DOM_STASH][0] = 0
-  buildDataStack.push([context, node])
-  const func = (node.tag as HasRenderToDom)[DOM_RENDERER] || node.tag
-  try {
-    return [
-      func.call(null, {
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        ...((func as any).defaultProps || {}),
-        ...node.props,
-      }),
-    ]
-  } finally {
-    buildDataStack.pop()
-  }
-}
-
-const getNextChildren = (
-  node: NodeObject,
-  container: Container,
-  nextChildren: Node[],
-  childrenToRemove: Node[],
-  callbacks: EffectData[]
-) => {
-  childrenToRemove.push(...node.vR)
-  if (typeof node.tag === 'function') {
-    node[DOM_STASH][1][STASH_EFFECT]?.forEach((data: EffectData) => callbacks.push(data))
-  }
-  node.vC.forEach((child) => {
-    if (isNodeString(child)) {
-      nextChildren.push(child)
-    } else {
-      if (typeof child.tag === 'function' || child.tag === '') {
-        child.c = container
-        getNextChildren(child, container, nextChildren, childrenToRemove, callbacks)
-      } else {
-        nextChildren.push(child)
-        childrenToRemove.push(...child.vR)
-      }
-    }
-  })
-}
-
-const findInsertBefore = (node: Node | undefined): ChildNode | null => {
-  if (!node) {
-    return null
-  } else if (node.tag === HONO_PORTAL_ELEMENT) {
-    return findInsertBefore(node.nN)
-  } else if (node.e) {
-    return node.e
-  }
-
-  if (node.vC) {
-    for (let i = 0, len = node.vC.length; i < len; i++) {
-      const e = findInsertBefore(node.vC[i])
-      if (e) {
-        return e
-      }
-    }
-  }
-
-  return findInsertBefore(node.nN)
-}
-
-const removeNode = (node: Node) => {
-  if (!isNodeString(node)) {
-    node[DOM_STASH]?.[1][STASH_EFFECT]?.forEach((data: EffectData) => data[2]?.())
-
-    if (node.e && node.props?.ref) {
-      if (typeof node.props.ref === 'function') {
-        node.props.ref(null)
-      } else {
-        node.props.ref.current = null
-      }
-    }
-    node.vC?.forEach(removeNode)
-  }
-  if (node.tag !== HONO_PORTAL_ELEMENT) {
-    node.e?.remove()
-  }
-  if (typeof node.tag === 'function') {
-    updateMap.delete(node)
-    fallbackUpdateFnArrayMap.delete(node)
-  }
-}
-
-const apply = (node: NodeObject, container: Container) => {
-  node.c = container
-  applyNodeObject(node, container)
-}
-
-const applyNode = (node: Node, container: Container) => {
-  if (isNodeString(node)) {
-    container.textContent = node.t
-  } else {
-    applyNodeObject(node, container)
-  }
-}
-
-const findChildNodeIndex = (
-  childNodes: NodeListOf<ChildNode>,
-  child: ChildNode | null | undefined
-): number | undefined => {
-  if (!child) {
-    return
-  }
-
-  for (let i = 0, len = childNodes.length; i < len; i++) {
-    if (childNodes[i] === child) {
-      return i
-    }
-  }
-
-  return
-}
-
-const applyNodeObject = (node: NodeObject, container: Container) => {
-  const next: Node[] = []
-  const remove: Node[] = []
-  const callbacks: EffectData[] = []
-  getNextChildren(node, container, next, remove, callbacks)
-
-  const childNodes = container.childNodes
-  let offset =
-    findChildNodeIndex(childNodes, findInsertBefore(node.nN)) ??
-    findChildNodeIndex(childNodes, next.find((n) => n.tag !== HONO_PORTAL_ELEMENT && n.e)?.e) ??
-    childNodes.length
-
-  for (let i = 0, len = next.length; i < len; i++, offset++) {
-    const child = next[i]
-
-    let el: SupportedElement | Text
-    if (isNodeString(child)) {
-      if (child.e && child.d) {
-        child.e.textContent = child.t
-      }
-      child.d = false
-      el = child.e ||= document.createTextNode(child.t)
-    } else {
-      el = child.e ||= child.n
-        ? (document.createElementNS(child.n, child.tag as string) as SVGElement | MathMLElement)
-        : document.createElement(child.tag as string)
-      applyProps(el as HTMLElement, child.props, child.pP)
-      applyNode(child, el as HTMLElement)
-    }
-    if (child.tag === HONO_PORTAL_ELEMENT) {
-      offset--
-    } else if (childNodes[offset] !== el && childNodes[offset - 1] !== child.e) {
-      container.insertBefore(el, childNodes[offset] || null)
-    }
-  }
-  remove.forEach(removeNode)
-  callbacks.forEach(([, , , , cb]) => cb?.()) // invoke useInsertionEffect callbacks
-  callbacks.forEach(([, cb]) => cb?.()) // invoke useLayoutEffect callbacks
-  requestAnimationFrame(() => {
-    callbacks.forEach(([, , , cb]) => cb?.()) // invoke useEffect callbacks
-  })
-}
-
-const fallbackUpdateFnArrayMap = new WeakMap<
-  NodeObject,
-  Array<() => Promise<NodeObject | undefined>>
->()
-export const build = (
-  context: Context,
-  node: NodeObject,
-  topLevelErrorHandlerNode: NodeObject | undefined,
-  children?: Child[]
-): void => {
-  let errorHandler: ErrorHandler | undefined
-  children ||=
-    typeof node.tag == 'function' ? invokeTag(context, node) : toArray(node.props.children)
-  if ((children[0] as JSXNode)?.tag === '') {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    errorHandler = (children[0] as any)[DOM_ERROR_HANDLER] as ErrorHandler
-    topLevelErrorHandlerNode ||= node
-  }
-  const oldVChildren: Node[] = node.vC ? [...node.vC] : []
-  const vChildren: Node[] = []
-  node.vR = []
-  let prevNode: Node | undefined
-  try {
-    children.flat().forEach((c: Child) => {
-      let child = buildNode(c)
-      if (child) {
-        if (prevNode) {
-          prevNode.nN = child
-        }
-        prevNode = child
-
-        if (
-          typeof child.tag === 'function' &&
-          // eslint-disable-next-line @typescript-eslint/no-explicit-any
-          !(child.tag as any)[DOM_INTERNAL_TAG] &&
-          globalJSXContexts.length > 0
-        ) {
-          child[DOM_STASH][2] = globalJSXContexts.map((c) => [c, c.values.at(-1)])
-        }
-
-        let oldChild: Node | undefined
-        const i = oldVChildren.findIndex(
-          isNodeString(child)
-            ? (c) => isNodeString(c)
-            : child.key !== undefined
-            ? (c) => c.key === (child as Node).key
-            : (c) => c.tag === (child as Node).tag
-        )
-        if (i !== -1) {
-          oldChild = oldVChildren[i]
-          oldVChildren.splice(i, 1)
-        }
-
-        if (oldChild) {
-          if (isNodeString(child)) {
-            if ((oldChild as NodeString).t !== child.t) {
-              ;(oldChild as NodeString).t = child.t // update text content
-              ;(oldChild as NodeString).d = true
-            }
-            child = oldChild
-          } else if (oldChild.tag !== child.tag) {
-            node.vR.push(oldChild)
-          } else {
-            oldChild.pP = oldChild.props
-            oldChild.props = child.props
-            if (typeof child.tag === 'function') {
-              oldChild[DOM_STASH][2] = child[DOM_STASH][2] || []
-            }
-            child = oldChild
-          }
-        } else if (!isNodeString(child) && nameSpaceContext) {
-          const ns = useContext(nameSpaceContext)
-          if (ns) {
-            child.n = ns
-          }
-        }
-
-        if (!isNodeString(child)) {
-          build(context, child, topLevelErrorHandlerNode)
-        }
-        vChildren.push(child)
-      }
-    })
-    node.vC = vChildren
-    node.vR.push(...oldVChildren)
-  } catch (e) {
-    if (errorHandler) {
-      const fallbackUpdateFn = () =>
-        update([0, false, context[2] as UpdateHook], topLevelErrorHandlerNode as NodeObject)
-      const fallbackUpdateFnArray =
-        fallbackUpdateFnArrayMap.get(topLevelErrorHandlerNode as NodeObject) || []
-      fallbackUpdateFnArray.push(fallbackUpdateFn)
-      fallbackUpdateFnArrayMap.set(topLevelErrorHandlerNode as NodeObject, fallbackUpdateFnArray)
-      const fallback = errorHandler(e, () => {
-        const fnArray = fallbackUpdateFnArrayMap.get(topLevelErrorHandlerNode as NodeObject)
-        if (fnArray) {
-          const i = fnArray.indexOf(fallbackUpdateFn)
-          if (i !== -1) {
-            fnArray.splice(i, 1)
-            return fallbackUpdateFn()
-          }
-        }
-      })
-      if (fallback) {
-        if (context[0] === 1) {
-          context[1] = true
-        } else {
-          build(context, node, topLevelErrorHandlerNode, [fallback])
-        }
-        return
-      }
-    }
-    throw e
-  }
-}
-
-const buildNode = (node: Child): Node | undefined => {
-  if (node === undefined || node === null || typeof node === 'boolean') {
-    return undefined
-  } else if (typeof node === 'string' || typeof node === 'number') {
-    return { t: node.toString(), d: true } as NodeString
-  } else {
-    if ('vR' in node) {
-      node = newJSXNode({
-        tag: (node as NodeObject).tag,
-        props: (node as NodeObject).props,
-        key: (node as NodeObject).key,
-      })
-    }
-    if (typeof (node as JSXNode).tag === 'function') {
-      ;(node as NodeObject)[DOM_STASH] = [0, []]
-    } else {
-      const ns = nameSpaceMap[(node as JSXNode).tag as string]
-      if (ns) {
-        ;(node as NodeObject).n = ns
-        nameSpaceContext ||= createContext('')
-        ;(node as JSXNode).props.children = [
-          {
-            tag: nameSpaceContext.Provider,
-            props: {
-              value: ns,
-              children: (node as JSXNode).props.children,
-            },
-          },
-          // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        ] as any
-      }
-    }
-    return node as NodeObject
-  }
-}
-
-const replaceContainer = (node: NodeObject, from: DocumentFragment, to: Container) => {
-  if (node.c === from) {
-    node.c = to
-    node.vC.forEach((child) => replaceContainer(child as NodeObject, from, to))
-  }
-}
-
-const updateSync = (context: Context, node: NodeObject) => {
-  node[DOM_STASH][2]?.forEach(([c, v]) => {
-    c.values.push(v)
-  })
-  build(context, node, undefined)
-  node[DOM_STASH][2]?.forEach(([c]) => {
-    c.values.pop()
-  })
-  if (context[0] !== 1 || !context[1]) {
-    apply(node, node.c as Container)
-  }
-}
-
-type UpdateMapResolve = (node: NodeObject | undefined) => void
-const updateMap = new WeakMap<NodeObject, [UpdateMapResolve, Function]>()
-const currentUpdateSets: Set<NodeObject>[] = []
-export const update = async (
-  context: Context,
-  node: NodeObject
-): Promise<NodeObject | undefined> => {
-  const existing = updateMap.get(node)
-  if (existing) {
-    // execute only the last update() call, so the previous update will be canceled.
-    existing[0](undefined)
-  }
-
-  let resolve: UpdateMapResolve | undefined
-  const promise = new Promise<NodeObject | undefined>((r) => (resolve = r))
-  updateMap.set(node, [
-    resolve as UpdateMapResolve,
-    () => {
-      if (context[2]) {
-        context[2](context, node, (context) => {
-          updateSync(context, node)
-        }).then(() => (resolve as UpdateMapResolve)(node))
-      } else {
-        updateSync(context, node)
-        ;(resolve as UpdateMapResolve)(node)
-      }
-    },
-  ])
-
-  if (currentUpdateSets.length) {
-    ;(currentUpdateSets.at(-1) as Set<NodeObject>).add(node)
-  } else {
-    await Promise.resolve()
-
-    const latest = updateMap.get(node)
-    if (latest) {
-      updateMap.delete(node)
-      latest[1]()
-    }
-  }
-
-  return promise
-}
-
-export const render = (jsxNode: unknown, container: Container) => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const node = buildNode({ tag: '', props: { children: jsxNode } } as any) as NodeObject
-  const context: Context = []
-  ;(context as Context)[4] = true // start top level render
-  build(context, node, undefined)
-  ;(context as Context)[4] = false // finish top level render
-
-  const fragment = document.createDocumentFragment()
-  apply(node, fragment)
-  replaceContainer(node, fragment, container)
-  container.replaceChildren(fragment)
-}
-
-export const flushSync = (callback: () => void) => {
-  const set = new Set<NodeObject>()
-  currentUpdateSets.push(set)
-  callback()
-  set.forEach((node) => {
-    const latest = updateMap.get(node)
-    if (latest) {
-      updateMap.delete(node)
-      latest[1]()
-    }
-  })
-  currentUpdateSets.pop()
-}
-
-export const createPortal = (children: Child, container: HTMLElement, key?: string): Child =>
-  ({
-    tag: HONO_PORTAL_ELEMENT,
-    props: {
-      children,
-    },
-    key,
-    e: container,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  } as any)
diff --git a/deno_dist/jsx/dom/utils.ts b/deno_dist/jsx/dom/utils.ts
deleted file mode 100644
index 020c45ac9..000000000
--- a/deno_dist/jsx/dom/utils.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { Props, JSXNode } from '../base.ts'
-import { DOM_INTERNAL_TAG } from '../constants.ts'
-
-export const setInternalTagFlag = (fn: Function): Function => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  ;(fn as any)[DOM_INTERNAL_TAG] = true
-  return fn
-}
-
-const JSXNodeCompatPrototype = {
-  type: {
-    get(this: { tag: string | Function }): string | Function {
-      return this.tag
-    },
-  },
-  ref: {
-    get(this: { props?: { ref: unknown } }): unknown {
-      return this.props?.ref
-    },
-  },
-}
-
-export const newJSXNode = (obj: { tag: string | Function; props?: Props; key?: string }): JSXNode =>
-  Object.defineProperties(obj, JSXNodeCompatPrototype) as JSXNode
diff --git a/deno_dist/jsx/hooks/index.ts b/deno_dist/jsx/hooks/index.ts
deleted file mode 100644
index 5ae294b1d..000000000
--- a/deno_dist/jsx/hooks/index.ts
+++ /dev/null
@@ -1,427 +0,0 @@
-import { DOM_STASH } from '../constants.ts'
-import { buildDataStack, update, build } from '../dom/render.ts'
-import type { Node, NodeObject, Context, PendingType, UpdateHook } from '../dom/render.ts'
-
-type UpdateStateFunction<T> = (newState: T | ((currentState: T) => T)) => void
-
-const STASH_SATE = 0
-export const STASH_EFFECT = 1
-const STASH_CALLBACK = 2
-const STASH_USE = 3
-const STASH_MEMO = 4
-const STASH_REF = 5
-
-export type EffectData = [
-  readonly unknown[] | undefined, // deps
-  (() => void | (() => void)) | undefined, // layout effect
-  (() => void) | undefined, // cleanup
-  (() => void) | undefined, // effect
-  (() => void) | undefined // insertion effect
-]
-
-const resolvedPromiseValueMap: WeakMap<Promise<unknown>, unknown> = new WeakMap<
-  Promise<unknown>,
-  unknown
->()
-
-const isDepsChanged = (
-  prevDeps: readonly unknown[] | undefined,
-  deps: readonly unknown[] | undefined
-): boolean =>
-  !prevDeps ||
-  !deps ||
-  prevDeps.length !== deps.length ||
-  deps.some((dep, i) => dep !== prevDeps[i])
-
-let viewTransitionState:
-  | [
-      boolean, // isUpdating
-      boolean // useViewTransition() is called
-    ]
-  | undefined = undefined
-
-const documentStartViewTransition: (cb: () => void) => { finished: Promise<void> } = (cb) => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  if ((document as any)?.startViewTransition) {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    return (document as any).startViewTransition(cb)
-  } else {
-    cb()
-    return { finished: Promise.resolve() }
-  }
-}
-
-let updateHook: UpdateHook | undefined = undefined
-const viewTransitionHook = (
-  context: Context,
-  node: Node,
-  cb: (context: Context) => void
-): Promise<void> => {
-  const state: [boolean, boolean] = [true, false]
-  let lastVC = node.vC
-  return documentStartViewTransition(() => {
-    if (lastVC === node.vC) {
-      viewTransitionState = state
-      cb(context)
-      viewTransitionState = undefined
-      lastVC = node.vC
-    }
-  }).finished.then(() => {
-    if (state[1] && lastVC === node.vC) {
-      state[0] = false
-      viewTransitionState = state
-      cb(context)
-      viewTransitionState = undefined
-    }
-  })
-}
-
-export const startViewTransition = (callback: () => void): void => {
-  updateHook = viewTransitionHook
-
-  try {
-    callback()
-  } finally {
-    updateHook = undefined
-  }
-}
-
-export const useViewTransition = (): [boolean, (callback: () => void) => void] => {
-  const buildData = buildDataStack.at(-1) as [Context, NodeObject]
-  if (!buildData) {
-    return [false, () => {}]
-  }
-
-  if (viewTransitionState) {
-    viewTransitionState[1] = true
-  }
-  return [!!viewTransitionState?.[0], startViewTransition]
-}
-
-const pendingStack: PendingType[] = []
-const runCallback = (type: PendingType, callback: Function): void => {
-  pendingStack.push(type)
-  try {
-    callback()
-  } finally {
-    pendingStack.pop()
-  }
-}
-
-export const startTransition = (callback: () => void): void => {
-  runCallback(1, callback)
-}
-const startTransitionHook = (callback: () => void): void => {
-  runCallback(2, callback)
-}
-
-export const useTransition = (): [boolean, (callback: () => void) => void] => {
-  const buildData = buildDataStack.at(-1) as [Context, NodeObject]
-  if (!buildData) {
-    return [false, () => {}]
-  }
-  const [context] = buildData
-  return [context[0] === 2, startTransitionHook]
-}
-
-export const useDeferredValue = <T>(value: T): T => {
-  const buildData = buildDataStack.at(-1) as [Context, NodeObject]
-  if (buildData) {
-    buildData[0][0] = 1
-  }
-  return value
-}
-
-const setShadow = (node: Node) => {
-  if (node.vC) {
-    node.s = node.vC
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    ;(node as any).vC = undefined
-  }
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  ;(node as any).s?.forEach(setShadow)
-}
-
-type UseStateType = {
-  <T>(initialState: T | (() => T)): [T, UpdateStateFunction<T>]
-  <T = undefined>(): [T | undefined, UpdateStateFunction<T | undefined>]
-}
-export const useState: UseStateType = <T>(
-  initialState?: T | (() => T)
-): [T, UpdateStateFunction<T>] => {
-  const resolveInitialState = () =>
-    typeof initialState === 'function' ? (initialState as () => T)() : (initialState as T)
-
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    return [resolveInitialState(), () => {}]
-  }
-  const [, node] = buildData
-
-  const stateArray = (node[DOM_STASH][1][STASH_SATE] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  return (stateArray[hookIndex] ||= [
-    resolveInitialState(),
-    (newState: T | ((currentState: T) => T)) => {
-      const localUpdateHook = updateHook
-      const stateData = stateArray[hookIndex]
-      if (typeof newState === 'function') {
-        newState = (newState as (currentState: T) => T)(stateData[0])
-      }
-
-      if (!Object.is(newState, stateData[0])) {
-        stateData[0] = newState
-        if (pendingStack.length) {
-          const pendingType = pendingStack.at(-1) as PendingType
-          update([pendingType, false, localUpdateHook as UpdateHook], node).then((node) => {
-            if (!node || pendingType !== 2) {
-              return
-            }
-
-            const lastVC = node.vC
-
-            const addUpdateTask = () => {
-              setTimeout(() => {
-                // `node` is not rerendered after current transition
-                if (lastVC !== node.vC) {
-                  return
-                }
-
-                const shadowNode = Object.assign({}, node) as NodeObject
-
-                // eslint-disable-next-line @typescript-eslint/no-explicit-any
-                ;(shadowNode as any).vC = undefined // delete the prev build data and build with clean state
-                build([], shadowNode, undefined)
-                setShadow(shadowNode) // save the `shadowNode.vC` of the virtual DOM of the build result as a result of shadow virtual DOM `shadowNode.s`
-
-                node.s = shadowNode.s
-                update([0, false, localUpdateHook as UpdateHook], node)
-              })
-            }
-
-            if (localUpdateHook) {
-              // wait for next animation frame, then invoke `update()`
-              requestAnimationFrame(addUpdateTask)
-            } else {
-              addUpdateTask()
-            }
-          })
-        } else {
-          update([0, false, localUpdateHook as UpdateHook], node)
-        }
-      }
-    },
-  ])
-}
-
-export const useReducer = <T, A>(
-  reducer: (state: T, action: A) => T,
-  initialArg: T,
-  init?: (initialState: T) => T
-): [T, (action: A) => void] => {
-  const [state, setState] = useState(() => (init ? init(initialArg) : initialArg))
-  return [
-    state,
-    (action: A) => {
-      setState((state) => reducer(state, action))
-    },
-  ]
-}
-
-const useEffectCommon = (
-  index: number,
-  effect: () => void | (() => void),
-  deps?: readonly unknown[]
-): void => {
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    return
-  }
-  const [, node] = buildData
-
-  const effectDepsArray = (node[DOM_STASH][1][STASH_EFFECT] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  const [prevDeps, , prevCleanup] = (effectDepsArray[hookIndex] ||= [])
-  if (isDepsChanged(prevDeps, deps)) {
-    if (prevCleanup) {
-      prevCleanup()
-    }
-    const runner = () => {
-      data[index] = undefined // clear this effect in order to avoid calling effect twice
-      data[2] = effect() as (() => void) | undefined
-    }
-    const data: EffectData = [deps, undefined, undefined, undefined, undefined]
-    data[index] = runner
-    effectDepsArray[hookIndex] = data
-  }
-}
-export const useEffect = (effect: () => void | (() => void), deps?: readonly unknown[]): void =>
-  useEffectCommon(3, effect, deps)
-export const useLayoutEffect = (
-  effect: () => void | (() => void),
-  deps?: readonly unknown[]
-): void => useEffectCommon(1, effect, deps)
-export const useInsertionEffect = (
-  effect: () => void | (() => void),
-  deps?: readonly unknown[]
-): void => useEffectCommon(4, effect, deps)
-
-export const useCallback = <T extends (...args: unknown[]) => unknown>(
-  callback: T,
-  deps: readonly unknown[]
-): T => {
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    return callback
-  }
-  const [, node] = buildData
-
-  const callbackArray = (node[DOM_STASH][1][STASH_CALLBACK] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  const prevDeps = callbackArray[hookIndex]
-  if (isDepsChanged(prevDeps?.[1], deps)) {
-    callbackArray[hookIndex] = [callback, deps]
-  } else {
-    callback = callbackArray[hookIndex][0] as T
-  }
-  return callback
-}
-
-export type RefObject<T> = { current: T | null }
-export const useRef = <T>(initialValue: T | null): RefObject<T> => {
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    return { current: initialValue }
-  }
-  const [, node] = buildData
-
-  const refArray = (node[DOM_STASH][1][STASH_REF] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  return (refArray[hookIndex] ||= { current: initialValue })
-}
-
-export const use = <T>(promise: Promise<T>): T => {
-  const cachedRes = resolvedPromiseValueMap.get(promise) as [T] | [undefined, unknown] | undefined
-  if (cachedRes) {
-    if (cachedRes.length === 2) {
-      throw cachedRes[1]
-    }
-    return cachedRes[0] as T
-  }
-  promise.then(
-    (res) => resolvedPromiseValueMap.set(promise, [res]),
-    (e) => resolvedPromiseValueMap.set(promise, [undefined, e])
-  )
-
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    throw promise
-  }
-  const [, node] = buildData
-
-  const promiseArray = (node[DOM_STASH][1][STASH_USE] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  promise.then(
-    (res) => {
-      promiseArray[hookIndex] = [res]
-    },
-    (e) => {
-      promiseArray[hookIndex] = [undefined, e]
-    }
-  )
-
-  const res = promiseArray[hookIndex]
-  if (res) {
-    if (res.length === 2) {
-      throw res[1]
-    }
-    return res[0] as T
-  }
-
-  throw promise
-}
-
-export const useMemo = <T>(factory: () => T, deps: readonly unknown[]): T => {
-  const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
-  if (!buildData) {
-    return factory()
-  }
-  const [, node] = buildData
-
-  const memoArray = (node[DOM_STASH][1][STASH_MEMO] ||= [])
-  const hookIndex = node[DOM_STASH][0]++
-
-  const prevDeps = memoArray[hookIndex]
-  if (isDepsChanged(prevDeps?.[1], deps)) {
-    memoArray[hookIndex] = [factory(), deps]
-  }
-  return memoArray[hookIndex][0] as T
-}
-
-let idCounter = 0
-export const useId = (): string => useMemo(() => `:r${(idCounter++).toString(32)}:`, [])
-
-// Define to avoid errors. This hook currently does nothing.
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export const useDebugValue = (_value: unknown, _formatter?: (value: unknown) => string): void => {}
-
-export const createRef = <T>(): RefObject<T> => {
-  return { current: null }
-}
-
-export const forwardRef = <T, P = {}>(
-  Component: (props: P, ref?: RefObject<T>) => JSX.Element
-): ((props: P & { ref?: RefObject<T> }) => JSX.Element) => {
-  return (props) => {
-    const { ref, ...rest } = props
-    return Component(rest as P, ref)
-  }
-}
-
-export const useImperativeHandle = <T>(
-  ref: RefObject<T>,
-  createHandle: () => T,
-  deps: readonly unknown[]
-): void => {
-  useEffect(() => {
-    ref.current = createHandle()
-    return () => {
-      ref.current = null
-    }
-  }, deps)
-}
-
-export const useSyncExternalStore = <T>(
-  subscribe: (callback: (value: T) => void) => () => void,
-  getSnapshot: () => T,
-  getServerSnapshot?: () => T
-): T => {
-  const buildData = buildDataStack.at(-1) as [Context, unknown]
-  if (!buildData) {
-    // now a stringify process, maybe in server side
-    if (!getServerSnapshot) {
-      throw new Error('getServerSnapshot is required for server side rendering')
-    }
-    return getServerSnapshot()
-  }
-
-  const [serverSnapshotIsUsed] = useState<boolean>(!!(buildData[0][4] && getServerSnapshot))
-  const [state, setState] = useState(() =>
-    serverSnapshotIsUsed ? (getServerSnapshot as () => T)() : getSnapshot()
-  )
-  useEffect(() => {
-    if (serverSnapshotIsUsed) {
-      setState(getSnapshot())
-    }
-    return subscribe(() => {
-      setState(getSnapshot())
-    })
-  }, [])
-
-  return state
-}
diff --git a/deno_dist/jsx/index.ts b/deno_dist/jsx/index.ts
deleted file mode 100644
index e5e07401b..000000000
--- a/deno_dist/jsx/index.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { jsx, memo, Fragment, isValidElement, cloneElement } from './base.ts'
-import type { DOMAttributes } from './base.ts'
-import { Children } from './children.ts'
-import { ErrorBoundary } from './components.ts'
-import { createContext, useContext } from './context.ts'
-import {
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  useReducer,
-  useId,
-  useDebugValue,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-} from './hooks/index.ts'
-import { Suspense } from './streaming.ts'
-
-export {
-  jsx,
-  memo,
-  Fragment,
-  isValidElement,
-  jsx as createElement,
-  cloneElement,
-  ErrorBoundary,
-  createContext,
-  useContext,
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  useReducer,
-  useId,
-  useDebugValue,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-  Suspense,
-  Children,
-  DOMAttributes,
-}
-
-export default {
-  memo,
-  Fragment,
-  isValidElement,
-  createElement: jsx,
-  cloneElement,
-  ErrorBoundary,
-  createContext,
-  useContext,
-  useState,
-  useEffect,
-  useRef,
-  useCallback,
-  useReducer,
-  useId,
-  useDebugValue,
-  use,
-  startTransition,
-  useTransition,
-  useDeferredValue,
-  startViewTransition,
-  useViewTransition,
-  useMemo,
-  useLayoutEffect,
-  useInsertionEffect,
-  createRef,
-  forwardRef,
-  useImperativeHandle,
-  useSyncExternalStore,
-  Suspense,
-  Children,
-}
-
-// TODO: change to `export type *` after denoify bug is fixed
-// https://github.com/garronej/denoify/issues/124
-export * from './types.ts'
diff --git a/deno_dist/jsx/intrinsic-elements.ts b/deno_dist/jsx/intrinsic-elements.ts
deleted file mode 100644
index 0d3b01525..000000000
--- a/deno_dist/jsx/intrinsic-elements.ts
+++ /dev/null
@@ -1,731 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
-/**
- * This code is based on React.
- * https://github.com/facebook/react
- * MIT License
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- */
-
-declare global {
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace Hono {
-    type CrossOrigin = 'anonymous' | 'use-credentials' | '' | undefined
-    type CSSProperties = {}
-    type AnyAttributes = { [attributeName: string]: any }
-
-    interface JSXAttributes {
-      dangerouslySetInnerHTML?: {
-        __html: string
-      }
-    }
-
-    interface EventAttributes {
-      onScroll?: (event: Event) => void
-      onScrollCapture?: (event: Event) => void
-      onScrollEnd?: (event: Event) => void
-      onScrollEndCapture?: (event: Event) => void
-      onWheel?: (event: WheelEvent) => void
-      onWheelCapture?: (event: WheelEvent) => void
-      onAnimationCancel?: (event: AnimationEvent) => void
-      onAnimationCancelCapture?: (event: AnimationEvent) => void
-      onAnimationEnd?: (event: AnimationEvent) => void
-      onAnimationEndCapture?: (event: AnimationEvent) => void
-      onAnimationIteration?: (event: AnimationEvent) => void
-      onAnimationIterationCapture?: (event: AnimationEvent) => void
-      onAnimationStart?: (event: AnimationEvent) => void
-      onAnimationStartCapture?: (event: AnimationEvent) => void
-      onCopy?: (event: ClipboardEvent) => void
-      onCopyCapture?: (event: ClipboardEvent) => void
-      onCut?: (event: ClipboardEvent) => void
-      onCutCapture?: (event: ClipboardEvent) => void
-      onPaste?: (event: ClipboardEvent) => void
-      onPasteCapture?: (event: ClipboardEvent) => void
-      onCompositionEnd?: (event: CompositionEvent) => void
-      onCompositionEndCapture?: (event: CompositionEvent) => void
-      onCompositionStart?: (event: CompositionEvent) => void
-      onCompositionStartCapture?: (event: CompositionEvent) => void
-      onCompositionUpdate?: (event: CompositionEvent) => void
-      onCompositionUpdateCapture?: (event: CompositionEvent) => void
-      onBlur?: (event: FocusEvent) => void
-      onBlurCapture?: (event: FocusEvent) => void
-      onFocus?: (event: FocusEvent) => void
-      onFocusCapture?: (event: FocusEvent) => void
-      onFocusIn?: (event: FocusEvent) => void
-      onFocusInCapture?: (event: FocusEvent) => void
-      onFocusOut?: (event: FocusEvent) => void
-      onFocusOutCapture?: (event: FocusEvent) => void
-      onFullscreenChange?: (event: Event) => void
-      onFullscreenChangeCapture?: (event: Event) => void
-      onFullscreenError?: (event: Event) => void
-      onFullscreenErrorCapture?: (event: Event) => void
-      onKeyDown?: (event: KeyboardEvent) => void
-      onKeyDownCapture?: (event: KeyboardEvent) => void
-      onKeyPress?: (event: KeyboardEvent) => void
-      onKeyPressCapture?: (event: KeyboardEvent) => void
-      onKeyUp?: (event: KeyboardEvent) => void
-      onKeyUpCapture?: (event: KeyboardEvent) => void
-      onAuxClick?: (event: MouseEvent) => void
-      onAuxClickCapture?: (event: MouseEvent) => void
-      onClick?: (event: MouseEvent) => void
-      onClickCapture?: (event: MouseEvent) => void
-      onContextMenu?: (event: MouseEvent) => void
-      onContextMenuCapture?: (event: MouseEvent) => void
-      onDoubleClick?: (event: MouseEvent) => void
-      onDoubleClickCapture?: (event: MouseEvent) => void
-      onMouseDown?: (event: MouseEvent) => void
-      onMouseDownCapture?: (event: MouseEvent) => void
-      onMouseEnter?: (event: MouseEvent) => void
-      onMouseEnterCapture?: (event: MouseEvent) => void
-      onMouseLeave?: (event: MouseEvent) => void
-      onMouseLeaveCapture?: (event: MouseEvent) => void
-      onMouseMove?: (event: MouseEvent) => void
-      onMouseMoveCapture?: (event: MouseEvent) => void
-      onMouseOut?: (event: MouseEvent) => void
-      onMouseOutCapture?: (event: MouseEvent) => void
-      onMouseOver?: (event: MouseEvent) => void
-      onMouseOverCapture?: (event: MouseEvent) => void
-      onMouseUp?: (event: MouseEvent) => void
-      onMouseUpCapture?: (event: MouseEvent) => void
-      onMouseWheel?: (event: WheelEvent) => void
-      onMouseWheelCapture?: (event: WheelEvent) => void
-      onGotPointerCapture?: (event: PointerEvent) => void
-      onGotPointerCaptureCapture?: (event: PointerEvent) => void
-      onLostPointerCapture?: (event: PointerEvent) => void
-      onLostPointerCaptureCapture?: (event: PointerEvent) => void
-      onPointerCancel?: (event: PointerEvent) => void
-      onPointerCancelCapture?: (event: PointerEvent) => void
-      onPointerDown?: (event: PointerEvent) => void
-      onPointerDownCapture?: (event: PointerEvent) => void
-      onPointerEnter?: (event: PointerEvent) => void
-      onPointerEnterCapture?: (event: PointerEvent) => void
-      onPointerLeave?: (event: PointerEvent) => void
-      onPointerLeaveCapture?: (event: PointerEvent) => void
-      onPointerMove?: (event: PointerEvent) => void
-      onPointerMoveCapture?: (event: PointerEvent) => void
-      onPointerOut?: (event: PointerEvent) => void
-      onPointerOutCapture?: (event: PointerEvent) => void
-      onPointerOver?: (event: PointerEvent) => void
-      onPointerOverCapture?: (event: PointerEvent) => void
-      onPointerUp?: (event: PointerEvent) => void
-      onPointerUpCapture?: (event: PointerEvent) => void
-      onTouchCancel?: (event: TouchEvent) => void
-      onTouchCancelCapture?: (event: TouchEvent) => void
-      onTouchEnd?: (event: TouchEvent) => void
-      onTouchEndCapture?: (event: TouchEvent) => void
-      onTouchMove?: (event: TouchEvent) => void
-      onTouchMoveCapture?: (event: TouchEvent) => void
-      onTouchStart?: (event: TouchEvent) => void
-      onTouchStartCapture?: (event: TouchEvent) => void
-      onTransitionCancel?: (event: TransitionEvent) => void
-      onTransitionCancelCapture?: (event: TransitionEvent) => void
-      onTransitionEnd?: (event: TransitionEvent) => void
-      onTransitionEndCapture?: (event: TransitionEvent) => void
-      onTransitionRun?: (event: TransitionEvent) => void
-      onTransitionRunCapture?: (event: TransitionEvent) => void
-      onTransitionStart?: (event: TransitionEvent) => void
-      onTransitionStartCapture?: (event: TransitionEvent) => void
-      onFormData?: (event: FormDataEvent) => void
-      onFormDataCapture?: (event: FormDataEvent) => void
-      onReset?: (event: Event) => void
-      onResetCapture?: (event: Event) => void
-      onSubmit?: (event: Event) => void
-      onSubmitCapture?: (event: Event) => void
-      onInvalid?: (event: Event) => void
-      onInvalidCapture?: (event: Event) => void
-      onSelect?: (event: Event) => void
-      onSelectCapture?: (event: Event) => void
-      onSelectChange?: (event: Event) => void
-      onSelectChangeCapture?: (event: Event) => void
-      onInput?: (event: InputEvent) => void
-      onInputCapture?: (event: InputEvent) => void
-      onBeforeInput?: (event: InputEvent) => void
-      onBeforeInputCapture?: (event: InputEvent) => void
-      onChange?: (event: Event) => void
-      onChangeCapture?: (event: Event) => void
-    }
-
-    interface HTMLAttributes extends JSXAttributes, EventAttributes, AnyAttributes {
-      accesskey?: string | undefined
-      autofocus?: boolean | undefined
-      class?: string | Promise<string> | undefined
-      contenteditable?: boolean | 'inherit' | undefined
-      contextmenu?: string | undefined
-      dir?: string | undefined
-      draggable?: boolean | undefined
-      hidden?: boolean | undefined
-      id?: string | undefined
-      lang?: string | undefined
-      nonce?: string | undefined
-      placeholder?: string | undefined
-      slot?: string | undefined
-      spellcheck?: boolean | undefined
-      style?: CSSProperties | undefined
-      tabindex?: number | undefined
-      title?: string | undefined
-      translate?: 'yes' | 'no' | undefined
-    }
-
-    type HTMLAttributeReferrerPolicy =
-      | ''
-      | 'no-referrer'
-      | 'no-referrer-when-downgrade'
-      | 'origin'
-      | 'origin-when-cross-origin'
-      | 'same-origin'
-      | 'strict-origin'
-      | 'strict-origin-when-cross-origin'
-      | 'unsafe-url'
-
-    type HTMLAttributeAnchorTarget = '_self' | '_blank' | '_parent' | '_top' | string
-
-    interface AnchorHTMLAttributes extends HTMLAttributes {
-      download?: any
-      href?: string | undefined
-      hreflang?: string | undefined
-      media?: string | undefined
-      ping?: string | undefined
-      target?: HTMLAttributeAnchorTarget | undefined
-      type?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-    }
-
-    interface AudioHTMLAttributes extends MediaHTMLAttributes {}
-
-    interface AreaHTMLAttributes extends HTMLAttributes {
-      alt?: string | undefined
-      coords?: string | undefined
-      download?: any
-      href?: string | undefined
-      hreflang?: string | undefined
-      media?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      shape?: string | undefined
-      target?: string | undefined
-    }
-
-    interface BaseHTMLAttributes extends HTMLAttributes {
-      href?: string | undefined
-      target?: string | undefined
-    }
-
-    interface BlockquoteHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-    }
-
-    interface ButtonHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      form?: string | undefined
-      formenctype?: string | undefined
-      formmethod?: string | undefined
-      formnovalidate?: boolean | undefined
-      formtarget?: string | undefined
-      name?: string | undefined
-      type?: 'submit' | 'reset' | 'button' | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface CanvasHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      width?: number | string | undefined
-    }
-
-    interface ColHTMLAttributes extends HTMLAttributes {
-      span?: number | undefined
-      width?: number | string | undefined
-    }
-
-    interface ColgroupHTMLAttributes extends HTMLAttributes {
-      span?: number | undefined
-    }
-
-    interface DataHTMLAttributes extends HTMLAttributes {
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface DetailsHTMLAttributes extends HTMLAttributes {
-      open?: boolean | undefined
-    }
-
-    interface DelHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-      dateTime?: string | undefined
-    }
-
-    interface DialogHTMLAttributes extends HTMLAttributes {
-      open?: boolean | undefined
-    }
-
-    interface EmbedHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      src?: string | undefined
-      type?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface FieldsetHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      form?: string | undefined
-      name?: string | undefined
-    }
-
-    interface FormHTMLAttributes extends HTMLAttributes {
-      'accept-charset'?: string | undefined
-      autocomplete?: string | undefined
-      enctype?: string | undefined
-      method?: string | undefined
-      name?: string | undefined
-      novalidate?: boolean | undefined
-      target?: string | undefined
-    }
-
-    interface HtmlHTMLAttributes extends HTMLAttributes {
-      manifest?: string | undefined
-    }
-
-    interface IframeHTMLAttributes extends HTMLAttributes {
-      allow?: string | undefined
-      allowfullscreen?: boolean | undefined
-      height?: number | string | undefined
-      loading?: 'eager' | 'lazy' | undefined
-      name?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sandbox?: string | undefined
-      seamless?: boolean | undefined
-      src?: string | undefined
-      srcdoc?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface ImgHTMLAttributes extends HTMLAttributes {
-      alt?: string | undefined
-      crossorigin?: CrossOrigin
-      decoding?: 'async' | 'auto' | 'sync' | undefined
-      height?: number | string | undefined
-      loading?: 'eager' | 'lazy' | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sizes?: string | undefined
-      src?: string | undefined
-      srcset?: string | undefined
-      usemap?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface InsHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-      datetime?: string | undefined
-    }
-
-    type HTMLInputTypeAttribute =
-      | 'button'
-      | 'checkbox'
-      | 'color'
-      | 'date'
-      | 'datetime-local'
-      | 'email'
-      | 'file'
-      | 'hidden'
-      | 'image'
-      | 'month'
-      | 'number'
-      | 'password'
-      | 'radio'
-      | 'range'
-      | 'reset'
-      | 'search'
-      | 'submit'
-      | 'tel'
-      | 'text'
-      | 'time'
-      | 'url'
-      | 'week'
-      | string
-
-    interface InputHTMLAttributes extends HTMLAttributes {
-      accept?: string | undefined
-      alt?: string | undefined
-      autocomplete?: string | undefined
-      capture?: boolean | 'user' | 'environment' | undefined // https://www.w3.org/TR/html-media-capture/#the-capture-attribute
-      checked?: boolean | undefined
-      disabled?: boolean | undefined
-      enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined
-      form?: string | undefined
-      formenctype?: string | undefined
-      formmethod?: string | undefined
-      formnovalidate?: boolean | undefined
-      formtarget?: string | undefined
-      height?: number | string | undefined
-      list?: string | undefined
-      max?: number | string | undefined
-      maxlength?: number | undefined
-      min?: number | string | undefined
-      minlength?: number | undefined
-      multiple?: boolean | undefined
-      name?: string | undefined
-      pattern?: string | undefined
-      placeholder?: string | undefined
-      readonly?: boolean | undefined
-      required?: boolean | undefined
-      size?: number | undefined
-      src?: string | undefined
-      step?: number | string | undefined
-      type?: HTMLInputTypeAttribute | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-      width?: number | string | undefined
-    }
-
-    interface KeygenHTMLAttributes extends HTMLAttributes {
-      challenge?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      keytype?: string | undefined
-      name?: string | undefined
-    }
-
-    interface LabelHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      for?: string | undefined
-    }
-
-    interface LiHTMLAttributes extends HTMLAttributes {
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface LinkHTMLAttributes extends HTMLAttributes {
-      as?: string | undefined
-      crossorigin?: CrossOrigin
-      href?: string | undefined
-      hreflang?: string | undefined
-      integrity?: string | undefined
-      media?: string | undefined
-      imagesrcset?: string | undefined
-      imagesizes?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sizes?: string | undefined
-      type?: string | undefined
-      charSet?: string | undefined
-    }
-
-    interface MapHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-    }
-
-    interface MenuHTMLAttributes extends HTMLAttributes {
-      type?: string | undefined
-    }
-
-    interface MediaHTMLAttributes extends HTMLAttributes {
-      autoplay?: boolean | undefined
-      controls?: boolean | undefined
-      controlslist?: string | undefined
-      crossorigin?: CrossOrigin
-      loop?: boolean | undefined
-      mediagroup?: string | undefined
-      muted?: boolean | undefined
-      playsinline?: boolean | undefined
-      preload?: string | undefined
-      src?: string | undefined
-    }
-
-    interface MetaHTMLAttributes extends HTMLAttributes {
-      charset?: string | undefined
-      'http-equiv'?: string | undefined
-      name?: string | undefined
-      media?: string | undefined
-      content?: string | undefined
-    }
-
-    interface MeterHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      high?: number | undefined
-      low?: number | undefined
-      max?: number | string | undefined
-      min?: number | string | undefined
-      optimum?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface QuoteHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-    }
-
-    interface ObjectHTMLAttributes extends HTMLAttributes {
-      data?: string | undefined
-      form?: string | undefined
-      height?: number | string | undefined
-      name?: string | undefined
-      type?: string | undefined
-      usemap?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface OlHTMLAttributes extends HTMLAttributes {
-      reversed?: boolean | undefined
-      start?: number | undefined
-      type?: '1' | 'a' | 'A' | 'i' | 'I' | undefined
-    }
-
-    interface OptgroupHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      label?: string | undefined
-    }
-
-    interface OptionHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      label?: string | undefined
-      selected?: boolean | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface OutputHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      for?: string | undefined
-      name?: string | undefined
-    }
-
-    interface ParamHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface ProgressHTMLAttributes extends HTMLAttributes {
-      max?: number | string | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface SlotHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-    }
-
-    interface ScriptHTMLAttributes extends HTMLAttributes {
-      async?: boolean | undefined
-      crossorigin?: CrossOrigin
-      defer?: boolean | undefined
-      integrity?: string | undefined
-      nomodule?: boolean | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      src?: string | undefined
-      type?: string | undefined
-    }
-
-    interface SelectHTMLAttributes extends HTMLAttributes {
-      autocomplete?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      multiple?: boolean | undefined
-      name?: string | undefined
-      required?: boolean | undefined
-      size?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
-
-    interface SourceHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      media?: string | undefined
-      sizes?: string | undefined
-      src?: string | undefined
-      srcset?: string | undefined
-      type?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface StyleHTMLAttributes extends HTMLAttributes {
-      media?: string | undefined
-      scoped?: boolean | undefined
-      type?: string | undefined
-    }
-
-    interface TableHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | undefined
-      bgcolor?: string | undefined
-      border?: number | undefined
-      cellpadding?: number | string | undefined
-      cellspacing?: number | string | undefined
-      frame?: boolean | undefined
-      rules?: 'none' | 'groups' | 'rows' | 'columns' | 'all' | undefined
-      summary?: string | undefined
-      width?: number | string | undefined
-    }
-
-    interface TextareaHTMLAttributes extends HTMLAttributes {
-      autocomplete?: string | undefined
-      cols?: number | undefined
-      dirname?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      maxlength?: number | undefined
-      minlength?: number | undefined
-      name?: string | undefined
-      placeholder?: string | undefined
-      readonly?: boolean | undefined
-      required?: boolean | undefined
-      rows?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-      wrap?: string | undefined
-    }
-
-    interface TdHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
-      colspan?: number | undefined
-      headers?: string | undefined
-      rowspan?: number | undefined
-      scope?: string | undefined
-      abbr?: string | undefined
-      height?: number | string | undefined
-      width?: number | string | undefined
-      valign?: 'top' | 'middle' | 'bottom' | 'baseline' | undefined
-    }
-
-    interface ThHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
-      colspan?: number | undefined
-      headers?: string | undefined
-      rowspan?: number | undefined
-      scope?: string | undefined
-      abbr?: string | undefined
-    }
-
-    interface TimeHTMLAttributes extends HTMLAttributes {
-      datetime?: string | undefined
-    }
-
-    interface TrackHTMLAttributes extends HTMLAttributes {
-      default?: boolean | undefined
-      kind?: string | undefined
-      label?: string | undefined
-      src?: string | undefined
-      srclang?: string | undefined
-    }
-
-    interface VideoHTMLAttributes extends MediaHTMLAttributes {
-      height?: number | string | undefined
-      playsinline?: boolean | undefined
-      poster?: string | undefined
-      width?: number | string | undefined
-      disablePictureInPicture?: boolean | undefined
-      disableRemotePlayback?: boolean | undefined
-    }
-
-    interface IntrinsicElements {
-      a: AnchorHTMLAttributes
-      abbr: HTMLAttributes
-      address: HTMLAttributes
-      area: AreaHTMLAttributes
-      article: HTMLAttributes
-      aside: HTMLAttributes
-      audio: AudioHTMLAttributes
-      b: HTMLAttributes
-      base: BaseHTMLAttributes
-      bdi: HTMLAttributes
-      bdo: HTMLAttributes
-      big: HTMLAttributes
-      blockquote: BlockquoteHTMLAttributes
-      body: HTMLAttributes
-      br: HTMLAttributes
-      button: ButtonHTMLAttributes
-      canvas: CanvasHTMLAttributes
-      caption: HTMLAttributes
-      center: HTMLAttributes
-      cite: HTMLAttributes
-      code: HTMLAttributes
-      col: ColHTMLAttributes
-      colgroup: ColgroupHTMLAttributes
-      data: DataHTMLAttributes
-      datalist: HTMLAttributes
-      dd: HTMLAttributes
-      del: DelHTMLAttributes
-      details: DetailsHTMLAttributes
-      dfn: HTMLAttributes
-      dialog: DialogHTMLAttributes
-      div: HTMLAttributes
-      dl: HTMLAttributes
-      dt: HTMLAttributes
-      em: HTMLAttributes
-      embed: EmbedHTMLAttributes
-      fieldset: FieldsetHTMLAttributes
-      figcaption: HTMLAttributes
-      figure: HTMLAttributes
-      footer: HTMLAttributes
-      form: FormHTMLAttributes
-      h1: HTMLAttributes
-      h2: HTMLAttributes
-      h3: HTMLAttributes
-      h4: HTMLAttributes
-      h5: HTMLAttributes
-      h6: HTMLAttributes
-      head: HTMLAttributes
-      header: HTMLAttributes
-      hgroup: HTMLAttributes
-      hr: HTMLAttributes
-      html: HtmlHTMLAttributes
-      i: HTMLAttributes
-      iframe: IframeHTMLAttributes
-      img: ImgHTMLAttributes
-      input: InputHTMLAttributes
-      ins: InsHTMLAttributes
-      kbd: HTMLAttributes
-      keygen: KeygenHTMLAttributes
-      label: LabelHTMLAttributes
-      legend: HTMLAttributes
-      li: LiHTMLAttributes
-      link: LinkHTMLAttributes
-      main: HTMLAttributes
-      map: MapHTMLAttributes
-      mark: HTMLAttributes
-      menu: MenuHTMLAttributes
-      menuitem: HTMLAttributes
-      meta: MetaHTMLAttributes
-      meter: MeterHTMLAttributes
-      nav: HTMLAttributes
-      noscript: HTMLAttributes
-      object: ObjectHTMLAttributes
-      ol: OlHTMLAttributes
-      optgroup: OptgroupHTMLAttributes
-      option: OptionHTMLAttributes
-      output: OutputHTMLAttributes
-      p: HTMLAttributes
-      param: ParamHTMLAttributes
-      picture: HTMLAttributes
-      pre: HTMLAttributes
-      progress: ProgressHTMLAttributes
-      q: QuoteHTMLAttributes
-      rp: HTMLAttributes
-      rt: HTMLAttributes
-      ruby: HTMLAttributes
-      s: HTMLAttributes
-      samp: HTMLAttributes
-      search: HTMLAttributes
-      slot: SlotHTMLAttributes
-      script: ScriptHTMLAttributes
-      section: HTMLAttributes
-      select: SelectHTMLAttributes
-      small: HTMLAttributes
-      source: SourceHTMLAttributes
-      span: HTMLAttributes
-      strong: HTMLAttributes
-      style: StyleHTMLAttributes
-      sub: HTMLAttributes
-      summary: HTMLAttributes
-      sup: HTMLAttributes
-      table: TableHTMLAttributes
-      template: HTMLAttributes
-      tbody: HTMLAttributes
-      td: TdHTMLAttributes
-      textarea: TextareaHTMLAttributes
-      tfoot: HTMLAttributes
-      th: ThHTMLAttributes
-      thead: HTMLAttributes
-      time: TimeHTMLAttributes
-      title: HTMLAttributes
-      tr: HTMLAttributes
-      track: TrackHTMLAttributes
-      u: HTMLAttributes
-      ul: HTMLAttributes
-      var: HTMLAttributes
-      video: VideoHTMLAttributes
-      wbr: HTMLAttributes
-    }
-  }
-}
-
-export interface IntrinsicElements extends Hono.IntrinsicElements {}
diff --git a/deno_dist/jsx/jsx-dev-runtime.ts b/deno_dist/jsx/jsx-dev-runtime.ts
deleted file mode 100644
index 39492291d..000000000
--- a/deno_dist/jsx/jsx-dev-runtime.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { HtmlEscapedString } from '../utils/html.ts'
-import { jsxFn } from './base.ts'
-import type { JSXNode } from './base.ts'
-export { Fragment } from './base.ts'
-
-export function jsxDEV(
-  tag: string | Function,
-  props: Record<string, unknown>,
-  key?: string
-): JSXNode {
-  let node: JSXNode
-  if (!props || !('children' in props)) {
-    node = jsxFn(tag, props, [])
-  } else {
-    const children = props.children as string | HtmlEscapedString
-    node = Array.isArray(children) ? jsxFn(tag, props, children) : jsxFn(tag, props, [children])
-  }
-  node.key = key
-  return node
-}
diff --git a/deno_dist/jsx/jsx-runtime.ts b/deno_dist/jsx/jsx-runtime.ts
deleted file mode 100644
index cf1c0c0a9..000000000
--- a/deno_dist/jsx/jsx-runtime.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export { jsxDEV as jsx, Fragment } from './jsx-dev-runtime.ts'
-export { jsxDEV as jsxs } from './jsx-dev-runtime.ts'
-
-import { raw, html } from '../helper/html/index.ts'
-import type { HtmlEscapedString } from '../utils/html.ts'
-export { html as jsxTemplate }
-export const jsxAttr = (
-  name: string,
-  value: string | Promise<string>
-): HtmlEscapedString | Promise<HtmlEscapedString> =>
-  typeof value === 'string' ? raw(name + '="' + html`${value}` + '"') : html`${name}="${value}"`
-export const jsxEscape = (value: string) => value
diff --git a/deno_dist/jsx/streaming.ts b/deno_dist/jsx/streaming.ts
deleted file mode 100644
index de419bdbc..000000000
--- a/deno_dist/jsx/streaming.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import { raw } from '../helper/html/index.ts'
-import { HtmlEscapedCallbackPhase, resolveCallback } from '../utils/html.ts'
-import type { HtmlEscapedString } from '../utils/html.ts'
-import { childrenToString } from './components.ts'
-import { DOM_RENDERER, DOM_STASH } from './constants.ts'
-import { Suspense as SuspenseDomRenderer } from './dom/components.ts'
-import { buildDataStack } from './dom/render.ts'
-import type { HasRenderToDom, NodeObject } from './dom/render.ts'
-import type { FC, PropsWithChildren, Child } from './index.ts'
-
-let suspenseCounter = 0
-
-/**
- * @experimental
- * `Suspense` is an experimental feature.
- * The API might be changed.
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const Suspense: FC<PropsWithChildren<{ fallback: any }>> = async ({
-  children,
-  fallback,
-}) => {
-  if (!children) {
-    return fallback.toString()
-  }
-  if (!Array.isArray(children)) {
-    children = [children]
-  }
-
-  let resArray: HtmlEscapedString[] | Promise<HtmlEscapedString[]>[] = []
-
-  // for use() hook
-  const stackNode = { [DOM_STASH]: [0, []] } as unknown as NodeObject
-  const popNodeStack = (value?: unknown) => {
-    buildDataStack.pop()
-    return value
-  }
-
-  try {
-    stackNode[DOM_STASH][0] = 0
-    buildDataStack.push([[], stackNode])
-    resArray = children.map((c) =>
-      c == null || typeof c === 'boolean' ? '' : c.toString()
-    ) as HtmlEscapedString[]
-  } catch (e) {
-    if (e instanceof Promise) {
-      resArray = [
-        e.then(() => {
-          stackNode[DOM_STASH][0] = 0
-          buildDataStack.push([[], stackNode])
-          return childrenToString(children as Child[]).then(popNodeStack)
-        }),
-      ] as Promise<HtmlEscapedString[]>[]
-    } else {
-      throw e
-    }
-  } finally {
-    popNodeStack()
-  }
-
-  if (resArray.some((res) => (res as {}) instanceof Promise)) {
-    const index = suspenseCounter++
-    const fallbackStr = await fallback.toString()
-    return raw(`<template id="H:${index}"></template>${fallbackStr}<!--/$-->`, [
-      ...(fallbackStr.callbacks || []),
-      ({ phase, buffer, context }) => {
-        if (phase === HtmlEscapedCallbackPhase.BeforeStream) {
-          return
-        }
-        return Promise.all(resArray).then(async (htmlArray) => {
-          htmlArray = htmlArray.flat()
-          const content = htmlArray.join('')
-          if (buffer) {
-            buffer[0] = buffer[0].replace(
-              new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
-              content
-            )
-          }
-          let html = buffer
-            ? ''
-            : `<template data-hono-target="H:${index}">${content}</template><script>
-((d,c,n) => {
-c=d.currentScript.previousSibling
-d=d.getElementById('H:${index}')
-if(!d)return
-do{n=d.nextSibling;n.remove()}while(n.nodeType!=8||n.nodeValue!='/$')
-d.replaceWith(c.content)
-})(document)
-</script>`
-
-          const callbacks = htmlArray
-            .map((html) => (html as HtmlEscapedString).callbacks || [])
-            .flat()
-          if (!callbacks.length) {
-            return html
-          }
-
-          if (phase === HtmlEscapedCallbackPhase.Stream) {
-            html = await resolveCallback(html, HtmlEscapedCallbackPhase.BeforeStream, true, context)
-          }
-
-          return raw(html, callbacks)
-        })
-      },
-    ])
-  } else {
-    return raw(resArray.join(''))
-  }
-}
-;(Suspense as HasRenderToDom)[DOM_RENDERER] = SuspenseDomRenderer
-
-const textEncoder = new TextEncoder()
-/**
- * @experimental
- * `renderToReadableStream()` is an experimental feature.
- * The API might be changed.
- */
-export const renderToReadableStream = (
-  str: HtmlEscapedString | Promise<HtmlEscapedString>,
-  onError: (e: unknown) => void = console.trace
-): ReadableStream<Uint8Array> => {
-  const reader = new ReadableStream<Uint8Array>({
-    async start(controller) {
-      try {
-        const tmp = str instanceof Promise ? await str : await str.toString()
-        const context = typeof tmp === 'object' ? tmp : {}
-        const resolved = await resolveCallback(
-          tmp,
-          HtmlEscapedCallbackPhase.BeforeStream,
-          true,
-          context
-        )
-        controller.enqueue(textEncoder.encode(resolved))
-
-        let resolvedCount = 0
-        const callbacks: Promise<void>[] = []
-        const then = (promise: Promise<string>) => {
-          callbacks.push(
-            promise
-              .catch((err) => {
-                console.log(err)
-                onError(err)
-                return ''
-              })
-              .then(async (res) => {
-                res = await resolveCallback(
-                  res,
-                  HtmlEscapedCallbackPhase.BeforeStream,
-                  true,
-                  context
-                )
-                ;(res as HtmlEscapedString).callbacks
-                  ?.map((c) => c({ phase: HtmlEscapedCallbackPhase.Stream, context }))
-                  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-                  .filter<Promise<string>>(Boolean as any)
-                  .forEach(then)
-                resolvedCount++
-                controller.enqueue(textEncoder.encode(res))
-              })
-          )
-        }
-        ;(resolved as HtmlEscapedString).callbacks
-          ?.map((c) => c({ phase: HtmlEscapedCallbackPhase.Stream, context }))
-          // eslint-disable-next-line @typescript-eslint/no-explicit-any
-          .filter<Promise<string>>(Boolean as any)
-          .forEach(then)
-        while (resolvedCount !== callbacks.length) {
-          await Promise.all(callbacks)
-        }
-      } catch (e) {
-        // maybe the connection was closed
-        onError(e)
-      }
-
-      controller.close()
-    },
-  })
-  return reader
-}
diff --git a/deno_dist/jsx/types.ts b/deno_dist/jsx/types.ts
deleted file mode 100644
index 3e1daf437..000000000
--- a/deno_dist/jsx/types.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * All types exported from "hono/jsx" are in this file.
- */
-import type { Child, JSXNode } from './base.ts'
-
-export type { Child, JSXNode, FC } from './base.ts'
-export type { RefObject } from './hooks/index.ts'
-export type { Context } from './context.ts'
-
-export type PropsWithChildren<P = unknown> = P & { children?: Child | undefined }
-export type CSSProperties = Hono.CSSProperties
-
-/**
- * React types
- */
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type ReactElement<P = any, T = string | Function> = JSXNode & {
-  type: T
-  props: P
-  key: string | null
-}
-type ReactNode = ReactElement | string | number | boolean | null | undefined
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-type ComponentClass<P = {}, S = {}> = unknown
-
-export type { ReactElement, ReactNode, ComponentClass }
-
-export type Event = globalThis.Event
-export type MouseEvent = globalThis.MouseEvent
-export type KeyboardEvent = globalThis.KeyboardEvent
-export type FocusEvent = globalThis.FocusEvent
-export type ClipboardEvent = globalThis.ClipboardEvent
-export type InputEvent = globalThis.InputEvent
-export type PointerEvent = globalThis.PointerEvent
-export type TouchEvent = globalThis.TouchEvent
-export type WheelEvent = globalThis.WheelEvent
-export type AnimationEvent = globalThis.AnimationEvent
-export type TransitionEvent = globalThis.TransitionEvent
-export type DragEvent = globalThis.DragEvent
diff --git a/deno_dist/jsx/utils.ts b/deno_dist/jsx/utils.ts
deleted file mode 100644
index dc8926ace..000000000
--- a/deno_dist/jsx/utils.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export const normalizeIntrinsicElementProps = (props: Record<string, unknown>): void => {
-  if (props && 'className' in props) {
-    props['class'] = props['className']
-    delete props['className']
-  }
-}
-
-export const styleObjectForEach = (
-  style: Record<string, string>,
-  fn: (key: string, value: string | null) => void
-): void => {
-  for (const [k, v] of Object.entries(style)) {
-    fn(
-      k[0] === '-'
-        ? k // CSS variable
-        : k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`), // style property. convert to kebab-case
-      v == null ? null : typeof v === 'number' ? v + 'px' : (v as string)
-    )
-  }
-}
diff --git a/deno_dist/middleware.ts b/deno_dist/middleware.ts
deleted file mode 100644
index 6164d61a4..000000000
--- a/deno_dist/middleware.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// This file is for Deno to import middleware from `hono/middleware.ts`.
-export * from './middleware/basic-auth/index.ts'
-export * from './middleware/bearer-auth/index.ts'
-export * from './middleware/body-limit/index.ts'
-export * from './middleware/cache/index.ts'
-export * from './middleware/compress/index.ts'
-export * from './middleware/cors/index.ts'
-export * from './middleware/csrf/index.ts'
-export * from './middleware/etag/index.ts'
-export * from './jsx/index.ts'
-export * from './middleware/jsx-renderer/index.ts'
-export { jwt } from './middleware/jwt/index.ts'
-export * from './middleware/logger/index.ts'
-export * from './middleware/method-override/index.ts'
-export * from './middleware/powered-by/index.ts'
-export * from './middleware/timeout/index.ts'
-export * from './middleware/timing/index.ts'
-export * from './middleware/pretty-json/index.ts'
-export * from './middleware/secure-headers/index.ts'
-export * from './middleware/trailing-slash/index.ts'
-export * from './adapter/deno/serve-static.ts'
diff --git a/deno_dist/middleware/basic-auth/index.ts b/deno_dist/middleware/basic-auth/index.ts
deleted file mode 100644
index aa7a8c059..000000000
--- a/deno_dist/middleware/basic-auth/index.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import type { Context } from '../../context.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { HonoRequest } from '../../request.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import { timingSafeEqual } from '../../utils/buffer.ts'
-import { decodeBase64 } from '../../utils/encode.ts'
-
-const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/
-const USER_PASS_REGEXP = /^([^:]*):(.*)$/
-const utf8Decoder = new TextDecoder()
-const auth = (req: HonoRequest) => {
-  const match = CREDENTIALS_REGEXP.exec(req.header('Authorization') || '')
-  if (!match) {
-    return undefined
-  }
-
-  let userPass = undefined
-  // If an invalid string is passed to atob(), it throws a `DOMException`.
-  try {
-    userPass = USER_PASS_REGEXP.exec(utf8Decoder.decode(decodeBase64(match[1])))
-  } catch {} // Do nothing
-
-  if (!userPass) {
-    return undefined
-  }
-
-  return { username: userPass[1], password: userPass[2] }
-}
-
-type BasicAuthOptions =
-  | {
-      username: string
-      password: string
-      realm?: string
-      hashFunction?: Function
-    }
-  | {
-      verifyUser: (username: string, password: string, c: Context) => boolean | Promise<boolean>
-      realm?: string
-      hashFunction?: Function
-    }
-
-/**
- * Basic authentication middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/basic-auth}
- *
- * @param {BasicAuthOptions} options - The options for the basic authentication middleware.
- * @param {string} options.username - The username for authentication.
- * @param {string} options.password - The password for authentication.
- * @param {string} [options.realm="Secure Area"] - The realm attribute for the WWW-Authenticate header.
- * @param {Function} [options.hashFunction] - The hash function used for secure comparison.
- * @param {Function} [options.verifyUser] - The function to verify user credentials.
- * @returns {MiddlewareHandler} The middleware handler function.
- * @throws {HTTPException} If neither "username and password" nor "verifyUser" options are provided.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(
- *   '/auth/*',
- *   basicAuth({
- *     username: 'hono',
- *     password: 'acoolproject',
- *   })
- * )
- *
- * app.get('/auth/page', (c) => {
- *   return c.text('You are authorized')
- * })
- * ```
- */
-export const basicAuth = (
-  options: BasicAuthOptions,
-  ...users: { username: string; password: string }[]
-): MiddlewareHandler => {
-  const usernamePasswordInOptions = 'username' in options && 'password' in options
-  const verifyUserInOptions = 'verifyUser' in options
-
-  if (!(usernamePasswordInOptions || verifyUserInOptions)) {
-    throw new Error(
-      'basic auth middleware requires options for "username and password" or "verifyUser"'
-    )
-  }
-
-  if (!options.realm) {
-    options.realm = 'Secure Area'
-  }
-
-  if (usernamePasswordInOptions) {
-    users.unshift({ username: options.username, password: options.password })
-  }
-
-  return async function basicAuth(ctx, next) {
-    const requestUser = auth(ctx.req)
-    if (requestUser) {
-      if (verifyUserInOptions) {
-        if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
-          await next()
-          return
-        }
-      } else {
-        for (const user of users) {
-          const [usernameEqual, passwordEqual] = await Promise.all([
-            timingSafeEqual(user.username, requestUser.username, options.hashFunction),
-            timingSafeEqual(user.password, requestUser.password, options.hashFunction),
-          ])
-          if (usernameEqual && passwordEqual) {
-            await next()
-            return
-          }
-        }
-      }
-    }
-    const res = new Response('Unauthorized', {
-      status: 401,
-      headers: {
-        'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"',
-      },
-    })
-    throw new HTTPException(401, { res })
-  }
-}
diff --git a/deno_dist/middleware/bearer-auth/index.ts b/deno_dist/middleware/bearer-auth/index.ts
deleted file mode 100644
index d208065a1..000000000
--- a/deno_dist/middleware/bearer-auth/index.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import type { Context } from '../../context.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import { timingSafeEqual } from '../../utils/buffer.ts'
-
-const TOKEN_STRINGS = '[A-Za-z0-9._~+/-]+=*'
-const PREFIX = 'Bearer'
-const HEADER = 'Authorization'
-
-type BearerAuthOptions =
-  | {
-      token: string | string[]
-      realm?: string
-      prefix?: string
-      headerName?: string
-      hashFunction?: Function
-    }
-  | {
-      realm?: string
-      prefix?: string
-      headerName?: string
-      verifyToken: (token: string, c: Context) => boolean | Promise<boolean>
-      hashFunction?: Function
-    }
-
-/**
- * Bearer authentication middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/bearer-auth}
- *
- * @param {BearerAuthOptions} options - The options for the bearer authentication middleware.
- * @param {string | string[]} [options.token] - The string or array of strings to validate the incoming bearer token against.
- * @param {Function} [options.verifyToken] - The function to verify the token.
- * @param {string} [options.realm=""] - The domain name of the realm, as part of the returned WWW-Authenticate challenge header.
- * @param {string} [options.prefix="Bearer"] - The prefix (or known as `schema`) for the Authorization header value.
- * @param {string} [options.headerName=Authorization] - The header name.
- * @param {Function} [options.hashFunction] - A function to handle hashing for safe comparison of authentication tokens.
- * @returns {MiddlewareHandler} The middleware handler function.
- * @throws {Error} If neither "token" nor "verifyToken" options are provided.
- * @throws {HTTPException} If authentication fails, with 401 status code for missing or invalid token, or 400 status code for invalid request.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * const token = 'honoiscool'
- *
- * app.use('/api/*', bearerAuth({ token }))
- *
- * app.get('/api/page', (c) => {
- *   return c.json({ message: 'You are authorized' })
- * })
- * ```
- */
-export const bearerAuth = (options: BearerAuthOptions): MiddlewareHandler => {
-  if (!('token' in options || 'verifyToken' in options)) {
-    throw new Error('bearer auth middleware requires options for "token"')
-  }
-  if (!options.realm) {
-    options.realm = ''
-  }
-  if (!options.prefix) {
-    options.prefix = PREFIX
-  }
-
-  const realm = options.realm?.replace(/"/g, '\\"')
-
-  return async function bearerAuth(c, next) {
-    const headerToken = c.req.header(options.headerName || HEADER)
-
-    if (!headerToken) {
-      // No Authorization header
-      const res = new Response('Unauthorized', {
-        status: 401,
-        headers: {
-          'WWW-Authenticate': `${options.prefix} realm="` + realm + '"',
-        },
-      })
-      throw new HTTPException(401, { res })
-    } else {
-      const regexp = new RegExp('^' + options.prefix + ' +(' + TOKEN_STRINGS + ') *$')
-      const match = regexp.exec(headerToken)
-      if (!match) {
-        // Invalid Request
-        const res = new Response('Bad Request', {
-          status: 400,
-          headers: {
-            'WWW-Authenticate': `${options.prefix} error="invalid_request"`,
-          },
-        })
-        throw new HTTPException(400, { res })
-      } else {
-        let equal = false
-        if ('verifyToken' in options) {
-          equal = await options.verifyToken(match[1], c)
-        } else if (typeof options.token === 'string') {
-          equal = await timingSafeEqual(options.token, match[1], options.hashFunction)
-        } else if (Array.isArray(options.token) && options.token.length > 0) {
-          for (const token of options.token) {
-            if (await timingSafeEqual(token, match[1], options.hashFunction)) {
-              equal = true
-              break
-            }
-          }
-        }
-        if (!equal) {
-          // Invalid Token
-          const res = new Response('Unauthorized', {
-            status: 401,
-            headers: {
-              'WWW-Authenticate': `${options.prefix} error="invalid_token"`,
-            },
-          })
-          throw new HTTPException(401, { res })
-        }
-      }
-    }
-    await next()
-  }
-}
diff --git a/deno_dist/middleware/body-limit/index.ts b/deno_dist/middleware/body-limit/index.ts
deleted file mode 100644
index a3dd80d1a..000000000
--- a/deno_dist/middleware/body-limit/index.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import type { Context } from '../../context.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-const ERROR_MESSAGE = 'Payload Too Large'
-
-type OnError = (c: Context) => Response | Promise<Response>
-type BodyLimitOptions = {
-  maxSize: number
-  onError?: OnError
-}
-
-class BodyLimitError extends Error {
-  constructor(message: string) {
-    super(message)
-    this.name = 'BodyLimitError'
-  }
-}
-
-/**
- * Body limit middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/body-limit}
- *
- * @param {BodyLimitOptions} options - The options for the body limit middleware.
- * @param {number} options.maxSize - The maximum body size allowed.
- * @param {OnError} [options.onError] - The error handler to be invoked if the specified body size is exceeded.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.post(
- *   '/upload',
- *   bodyLimit({
- *     maxSize: 50 * 1024, // 50kb
- *     onError: (c) => {
- *       return c.text('overflow :(', 413)
- *     },
- *   }),
- *   async (c) => {
- *     const body = await c.req.parseBody()
- *     if (body['file'] instanceof File) {
- *       console.log(`Got file sized: ${body['file'].size}`)
- *     }
- *     return c.text('pass :)')
- *   }
- * )
- * ```
- */
-export const bodyLimit = (options: BodyLimitOptions): MiddlewareHandler => {
-  const onError: OnError =
-    options.onError ||
-    (() => {
-      const res = new Response(ERROR_MESSAGE, {
-        status: 413,
-      })
-      throw new HTTPException(413, { res })
-    })
-  const maxSize = options.maxSize
-
-  return async function bodyLimit(c, next) {
-    if (!c.req.raw.body) {
-      // maybe GET or HEAD request
-      return next()
-    }
-
-    if (c.req.raw.headers.has('content-length')) {
-      // we can trust content-length header because it's already validated by server
-      const contentLength = parseInt(c.req.raw.headers.get('content-length') || '0', 10)
-      return contentLength > maxSize ? onError(c) : next()
-    }
-
-    // maybe chunked transfer encoding
-
-    let size = 0
-    const rawReader = c.req.raw.body.getReader()
-    const reader = new ReadableStream({
-      async start(controller) {
-        try {
-          for (;;) {
-            const { done, value } = await rawReader.read()
-            if (done) {
-              break
-            }
-            size += value.length
-            if (size > maxSize) {
-              controller.error(new BodyLimitError(ERROR_MESSAGE))
-              break
-            }
-
-            controller.enqueue(value)
-          }
-        } finally {
-          controller.close()
-        }
-      },
-    })
-
-    c.req.raw = new Request(c.req.raw, { body: reader })
-
-    await next()
-
-    if (c.error instanceof BodyLimitError) {
-      c.res = await onError(c)
-    }
-  }
-}
diff --git a/deno_dist/middleware/cache/index.ts b/deno_dist/middleware/cache/index.ts
deleted file mode 100644
index b46ee6f16..000000000
--- a/deno_dist/middleware/cache/index.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import type { Context } from '../../context.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-/**
- * cache middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/cache}
- *
- * @param {Object} options - The options for the cache middleware.
- * @param {string | Function} options.cacheName - The name of the cache. Can be used to store multiple caches with different identifiers.
- * @param {boolean} [options.wait=false] - A boolean indicating if Hono should wait for the Promise of the `cache.put` function to resolve before continuing with the request. Required to be true for the Deno environment.
- * @param {string} [options.cacheControl] - A string of directives for the `Cache-Control` header.
- * @param {string | string[]} [options.vary] - Sets the `Vary` header in the response. If the original response header already contains a `Vary` header, the values are merged, removing any duplicates.
- * @param {Function} [options.keyGenerator] - Generates keys for every request in the `cacheName` store. This can be used to cache data based on request parameters or context parameters.
- * @returns {MiddlewareHandler} The middleware handler function.
- * @throws {Error} If the `vary` option includes "*".
- *
- * @example
- * ```ts
- * app.get(
- *   '*',
- *   cache({
- *     cacheName: 'my-app',
- *     cacheControl: 'max-age=3600',
- *   })
- * )
- * ```
- */
-export const cache = (options: {
-  cacheName: string | ((c: Context) => Promise<string> | string)
-  wait?: boolean
-  cacheControl?: string
-  vary?: string | string[]
-  keyGenerator?: (c: Context) => Promise<string> | string
-}): MiddlewareHandler => {
-  if (!globalThis.caches) {
-    console.log('Cache Middleware is not enabled because caches is not defined.')
-    return async (_c, next) => await next()
-  }
-
-  if (options.wait === undefined) {
-    options.wait = false
-  }
-
-  const cacheControlDirectives = options.cacheControl
-    ?.split(',')
-    .map((directive) => directive.toLowerCase())
-  const varyDirectives = Array.isArray(options.vary)
-    ? options.vary
-    : options.vary?.split(',').map((directive) => directive.trim())
-  // RFC 7231 Section 7.1.4 specifies that "*" is not allowed in Vary header.
-  // See: https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.4
-  if (options.vary?.includes('*')) {
-    throw new Error(
-      'Middleware vary configuration cannot include "*", as it disallows effective caching.'
-    )
-  }
-
-  const addHeader = (c: Context) => {
-    if (cacheControlDirectives) {
-      const existingDirectives =
-        c.res.headers
-          .get('Cache-Control')
-          ?.split(',')
-          .map((d) => d.trim().split('=', 1)[0]) ?? []
-      for (const directive of cacheControlDirectives) {
-        let [name, value] = directive.trim().split('=', 2)
-        name = name.toLowerCase()
-        if (!existingDirectives.includes(name)) {
-          c.header('Cache-Control', `${name}${value ? `=${value}` : ''}`, { append: true })
-        }
-      }
-    }
-
-    if (varyDirectives) {
-      const existingDirectives =
-        c.res.headers
-          .get('Vary')
-          ?.split(',')
-          .map((d) => d.trim()) ?? []
-
-      const vary = Array.from(
-        new Set(
-          [...existingDirectives, ...varyDirectives].map((directive) => directive.toLowerCase())
-        )
-      ).sort()
-
-      if (vary.includes('*')) {
-        c.header('Vary', '*')
-      } else {
-        c.header('Vary', vary.join(', '))
-      }
-    }
-  }
-
-  return async function cache(c, next) {
-    let key = c.req.url
-    if (options.keyGenerator) {
-      key = await options.keyGenerator(c)
-    }
-
-    const cacheName =
-      typeof options.cacheName === 'function' ? await options.cacheName(c) : options.cacheName
-    const cache = await caches.open(cacheName)
-    const response = await cache.match(key)
-    if (response) {
-      return new Response(response.body, response)
-    }
-
-    await next()
-    if (!c.res.ok) {
-      return
-    }
-    addHeader(c)
-    const res = c.res.clone()
-    if (options.wait) {
-      await cache.put(key, res)
-    } else {
-      c.executionCtx.waitUntil(cache.put(key, res))
-    }
-  }
-}
diff --git a/deno_dist/middleware/compress/index.ts b/deno_dist/middleware/compress/index.ts
deleted file mode 100644
index dd05ecc6d..000000000
--- a/deno_dist/middleware/compress/index.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-
-const ENCODING_TYPES = ['gzip', 'deflate'] as const
-
-interface CompressionOptions {
-  encoding?: (typeof ENCODING_TYPES)[number]
-}
-
-/**
- * Compress middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/compress}
- *
- * @param {CompressionOptions} [options] - The options for the compress middleware.
- * @param {'gzip' | 'deflate'} [options.encoding] - The compression scheme to allow for response compression. Either 'gzip' or 'deflate'. If not defined, both are allowed and will be used based on the Accept-Encoding header. 'gzip' is prioritized if this option is not provided and the client provides both in the Accept-Encoding header.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(compress())
- * ```
- */
-export const compress = (options?: CompressionOptions): MiddlewareHandler => {
-  return async function compress(ctx, next) {
-    await next()
-    const accepted = ctx.req.header('Accept-Encoding')
-    const encoding =
-      options?.encoding ?? ENCODING_TYPES.find((encoding) => accepted?.includes(encoding))
-    if (!encoding || !ctx.res.body) {
-      return
-    }
-    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
-    // @ts-ignore
-    const stream = new CompressionStream(encoding)
-    ctx.res = new Response(ctx.res.body.pipeThrough(stream), ctx.res)
-    ctx.res.headers.delete('Content-Length')
-    ctx.res.headers.set('Content-Encoding', encoding)
-  }
-}
diff --git a/deno_dist/middleware/cors/index.ts b/deno_dist/middleware/cors/index.ts
deleted file mode 100644
index 7fc0ea53f..000000000
--- a/deno_dist/middleware/cors/index.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import type { Context } from '../../context.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-type CORSOptions = {
-  origin: string | string[] | ((origin: string, c: Context) => string | undefined | null)
-  allowMethods?: string[]
-  allowHeaders?: string[]
-  maxAge?: number
-  credentials?: boolean
-  exposeHeaders?: string[]
-}
-
-/**
- * CORS middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/cors}
- *
- * @param {CORSOptions} [options] - The options for the CORS middleware.
- * @param {string | string[] | ((origin: string, c: Context) => string | undefined | null)} [options.origin='*'] - The value of "Access-Control-Allow-Origin" CORS header.
- * @param {string[]} [options.allowMethods=['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']] - The value of "Access-Control-Allow-Methods" CORS header.
- * @param {string[]} [options.allowHeaders=[]] - The value of "Access-Control-Allow-Headers" CORS header.
- * @param {number} [options.maxAge] - The value of "Access-Control-Max-Age" CORS header.
- * @param {boolean} [options.credentials] - The value of "Access-Control-Allow-Credentials" CORS header.
- * @param {string[]} [options.exposeHeaders=[]] - The value of "Access-Control-Expose-Headers" CORS header.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use('/api/*', cors())
- * app.use(
- *   '/api2/*',
- *   cors({
- *     origin: 'http://example.com',
- *     allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
- *     allowMethods: ['POST', 'GET', 'OPTIONS'],
- *     exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
- *     maxAge: 600,
- *     credentials: true,
- *   })
- * )
- *
- * app.all('/api/abc', (c) => {
- *   return c.json({ success: true })
- * })
- * app.all('/api2/abc', (c) => {
- *   return c.json({ success: true })
- * })
- * ```
- */
-export const cors = (options?: CORSOptions): MiddlewareHandler => {
-  const defaults: CORSOptions = {
-    origin: '*',
-    allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
-    allowHeaders: [],
-    exposeHeaders: [],
-  }
-  const opts = {
-    ...defaults,
-    ...options,
-  }
-
-  const findAllowOrigin = ((optsOrigin) => {
-    if (typeof optsOrigin === 'string') {
-      return () => optsOrigin
-    } else if (typeof optsOrigin === 'function') {
-      return optsOrigin
-    } else {
-      return (origin: string) => (optsOrigin.includes(origin) ? origin : optsOrigin[0])
-    }
-  })(opts.origin)
-
-  return async function cors(c, next) {
-    function set(key: string, value: string) {
-      c.res.headers.set(key, value)
-    }
-
-    const allowOrigin = findAllowOrigin(c.req.header('origin') || '', c)
-    if (allowOrigin) {
-      set('Access-Control-Allow-Origin', allowOrigin)
-    }
-
-    // Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
-    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
-    if (opts.origin !== '*') {
-      set('Vary', 'Origin')
-    }
-
-    if (opts.credentials) {
-      set('Access-Control-Allow-Credentials', 'true')
-    }
-
-    if (opts.exposeHeaders?.length) {
-      set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','))
-    }
-
-    if (c.req.method === 'OPTIONS') {
-      if (opts.maxAge != null) {
-        set('Access-Control-Max-Age', opts.maxAge.toString())
-      }
-
-      if (opts.allowMethods?.length) {
-        set('Access-Control-Allow-Methods', opts.allowMethods.join(','))
-      }
-
-      let headers = opts.allowHeaders
-      if (!headers?.length) {
-        const requestHeaders = c.req.header('Access-Control-Request-Headers')
-        if (requestHeaders) {
-          headers = requestHeaders.split(/\s*,\s*/)
-        }
-      }
-      if (headers?.length) {
-        set('Access-Control-Allow-Headers', headers.join(','))
-        c.res.headers.append('Vary', 'Access-Control-Request-Headers')
-      }
-
-      c.res.headers.delete('Content-Length')
-      c.res.headers.delete('Content-Type')
-
-      return new Response(null, {
-        headers: c.res.headers,
-        status: 204,
-        statusText: c.res.statusText,
-      })
-    }
-    await next()
-  }
-}
diff --git a/deno_dist/middleware/csrf/index.ts b/deno_dist/middleware/csrf/index.ts
deleted file mode 100644
index 135331e46..000000000
--- a/deno_dist/middleware/csrf/index.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import type { Context } from '../../context.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-type IsAllowedOriginHandler = (origin: string, context: Context) => boolean
-interface CSRFOptions {
-  origin?: string | string[] | IsAllowedOriginHandler
-}
-
-const isSafeMethodRe = /^(GET|HEAD)$/
-const isRequestedByFormElementRe =
-  /^\b(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)\b/
-
-/**
- * CSRF protection middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/csrf}
- *
- * @param {CSRFOptions} [options] - The options for the CSRF protection middleware.
- * @param {string|string[]|(origin: string, context: Context) => boolean} [options.origin] - Specify origins.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(csrf())
- *
- * // Specifying origins with using `origin` option
- * // string
- * app.use(csrf({ origin: 'myapp.example.com' }))
- *
- * // string[]
- * app.use(
- *   csrf({
- *     origin: ['myapp.example.com', 'development.myapp.example.com'],
- *   })
- * )
- *
- * // Function
- * // It is strongly recommended that the protocol be verified to ensure a match to `$`.
- * // You should *never* do a forward match.
- * app.use(
- *   '*',
- *   csrf({
- *     origin: (origin) => /https:\/\/(\w+\.)?myapp\.example\.com$/.test(origin),
- *   })
- * )
- * ```
- */
-export const csrf = (options?: CSRFOptions): MiddlewareHandler => {
-  const handler: IsAllowedOriginHandler = ((optsOrigin) => {
-    if (!optsOrigin) {
-      return (origin, c) => origin === new URL(c.req.url).origin
-    } else if (typeof optsOrigin === 'string') {
-      return (origin) => origin === optsOrigin
-    } else if (typeof optsOrigin === 'function') {
-      return optsOrigin
-    } else {
-      return (origin) => optsOrigin.includes(origin)
-    }
-  })(options?.origin)
-  const isAllowedOrigin = (origin: string | undefined, c: Context) => {
-    if (origin === undefined) {
-      // denied always when origin header is not present
-      return false
-    }
-    return handler(origin, c)
-  }
-
-  return async function cors(c, next) {
-    if (
-      !isSafeMethodRe.test(c.req.method) &&
-      isRequestedByFormElementRe.test(c.req.header('content-type') || '') &&
-      !isAllowedOrigin(c.req.header('origin'), c)
-    ) {
-      const res = new Response('Forbidden', {
-        status: 403,
-      })
-      throw new HTTPException(403, { res })
-    }
-
-    await next()
-  }
-}
diff --git a/deno_dist/middleware/etag/index.ts b/deno_dist/middleware/etag/index.ts
deleted file mode 100644
index aa137a407..000000000
--- a/deno_dist/middleware/etag/index.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-import { sha1 } from '../../utils/crypto.ts'
-
-type ETagOptions = {
-  retainedHeaders?: string[]
-  weak?: boolean
-}
-
-/**
- * Default headers to pass through on 304 responses. From the spec:
- * > The response must not contain a body and must include the headers that
- * > would have been sent in an equivalent 200 OK response: Cache-Control,
- * > Content-Location, Date, ETag, Expires, and Vary.
- */
-export const RETAINED_304_HEADERS = [
-  'cache-control',
-  'content-location',
-  'date',
-  'etag',
-  'expires',
-  'vary',
-]
-
-function etagMatches(etag: string, ifNoneMatch: string | null) {
-  return ifNoneMatch != null && ifNoneMatch.split(/,\s*/).indexOf(etag) > -1
-}
-
-/**
- * ETag middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/etag}
- *
- * @param {ETagOptions} [options] - The options for the ETag middleware.
- * @param {boolean} [options.weak=false] - Define using or not using a weak validation. If true is set, then `W/` is added to the prefix of the value.
- * @param {string[]} [options.retainedHeaders=RETAINED_304_HEADERS] - The headers that you want to retain in the 304 Response.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use('/etag/*', etag())
- * app.get('/etag/abc', (c) => {
- *   return c.text('Hono is cool')
- * })
- * ```
- */
-export const etag = (options?: ETagOptions): MiddlewareHandler => {
-  const retainedHeaders = options?.retainedHeaders ?? RETAINED_304_HEADERS
-  const weak = options?.weak ?? false
-
-  return async function etag(c, next) {
-    const ifNoneMatch = c.req.header('If-None-Match') ?? null
-
-    await next()
-
-    const res = c.res as Response
-    let etag = res.headers.get('ETag')
-
-    if (!etag) {
-      const hash = await sha1(res.clone().body || '')
-      etag = weak ? `W/"${hash}"` : `"${hash}"`
-    }
-
-    if (etagMatches(etag, ifNoneMatch)) {
-      await c.res.blob() // Force using body
-      c.res = new Response(null, {
-        status: 304,
-        statusText: 'Not Modified',
-        headers: {
-          ETag: etag,
-        },
-      })
-      c.res.headers.forEach((_, key) => {
-        if (retainedHeaders.indexOf(key.toLowerCase()) === -1) {
-          c.res.headers.delete(key)
-        }
-      })
-    } else {
-      c.res.headers.set('ETag', etag)
-    }
-  }
-}
diff --git a/deno_dist/middleware/jsx-renderer/index.ts b/deno_dist/middleware/jsx-renderer/index.ts
deleted file mode 100644
index c33a1bc52..000000000
--- a/deno_dist/middleware/jsx-renderer/index.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { Context, PropsForRenderer } from '../../context.ts'
-import { html, raw } from '../../helper/html/index.ts'
-import { jsx, createContext, useContext, Fragment } from '../../jsx/index.ts'
-import type { FC, PropsWithChildren, JSXNode } from '../../jsx/index.ts'
-import type { Context as JSXContext } from '../../jsx/index.ts'
-import { renderToReadableStream } from '../../jsx/streaming.ts'
-import type { Env, Input, MiddlewareHandler } from '../../types.ts'
-import type { HtmlEscapedString } from '../../utils/html.ts'
-
-export const RequestContext: JSXContext<Context<any, any, {}> | null> =
-  createContext<Context | null>(null)
-
-type RendererOptions = {
-  docType?: boolean | string
-  stream?: boolean | Record<string, string>
-}
-
-type Component = (
-  props: PropsForRenderer & { Layout: FC },
-  c: Context
-) => HtmlEscapedString | Promise<HtmlEscapedString>
-
-type ComponentWithChildren = (
-  props: PropsWithChildren<PropsForRenderer & { Layout: FC }>,
-  c: Context
-) => HtmlEscapedString | Promise<HtmlEscapedString>
-
-const createRenderer =
-  (c: Context, Layout: FC, component?: Component, options?: RendererOptions) =>
-  (children: JSXNode, props: PropsForRenderer) => {
-    const docType =
-      typeof options?.docType === 'string'
-        ? options.docType
-        : options?.docType === false
-        ? ''
-        : '<!DOCTYPE html>'
-
-    const currentLayout = component
-      ? jsx(
-          (props: any) => component(props, c),
-          {
-            ...{ Layout, ...(props as any) },
-          },
-          children as any
-        )
-      : children
-
-    const body = html`${raw(docType)}${jsx(
-      RequestContext.Provider,
-      { value: c },
-      currentLayout as any
-    )}`
-
-    if (options?.stream) {
-      if (options.stream === true) {
-        c.header('Transfer-Encoding', 'chunked')
-        c.header('Content-Type', 'text/html; charset=UTF-8')
-      } else {
-        for (const [key, value] of Object.entries(options.stream)) {
-          c.header(key, value)
-        }
-      }
-      return c.body(renderToReadableStream(body))
-    } else {
-      return c.html(body)
-    }
-  }
-
-/**
- * JSX renderer middleware for hono.
- *
- * @see {@link{https://hono.dev/middleware/builtin/jsx-renderer}}
- *
- * @param {ComponentWithChildren} [component] - The component to render, which can accept children and props.
- * @param {RendererOptions} [options] - The options for the JSX renderer middleware.
- * @param {boolean | string} [options.docType=true] - The DOCTYPE to be added at the beginning of the HTML. If set to false, no DOCTYPE will be added.
- * @param {boolean | Record<string, string>} [options.stream=false] - If set to true, enables streaming response with default headers. If a record is provided, custom headers will be used.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.get(
- *   '/page/*',
- *   jsxRenderer(({ children }) => {
- *     return (
- *       <html>
- *         <body>
- *           <header>Menu</header>
- *           <div>{children}</div>
- *         </body>
- *       </html>
- *     )
- *   })
- * )
- *
- * app.get('/page/about', (c) => {
- *   return c.render(<h1>About me!</h1>)
- * })
- * ```
- */
-export const jsxRenderer = (
-  component?: ComponentWithChildren,
-  options?: RendererOptions
-): MiddlewareHandler =>
-  function jsxRenderer(c, next) {
-    const Layout = (c.getLayout() ?? Fragment) as FC
-    if (component) {
-      c.setLayout((props) => {
-        return component({ ...props, Layout }, c)
-      })
-    }
-    c.setRenderer(createRenderer(c, Layout, component, options) as any)
-    return next()
-  }
-
-/**
- * useRequestContext for Hono.
- *
- * @template E - The environment type.
- * @template P - The parameter type.
- * @template I - The input type.
- * @returns {Context<E, P, I>} An instance of Context.
- *
- * @example
- * ```ts
- * const RequestUrlBadge: FC = () => {
- *   const c = useRequestContext()
- *   return <b>{c.req.url}</b>
- * }
- *
- * app.get('/page/info', (c) => {
- *   return c.render(
- *     <div>
- *       You are accessing: <RequestUrlBadge />
- *     </div>
- *   )
- * })
- * ```
- */
-export const useRequestContext = <
-  E extends Env = any,
-  P extends string = any,
-  I extends Input = {}
->(): Context<E, P, I> => {
-  const c = useContext(RequestContext)
-  if (!c) {
-    throw new Error('RequestContext is not provided.')
-  }
-  return c
-}
diff --git a/deno_dist/middleware/logger/index.ts b/deno_dist/middleware/logger/index.ts
deleted file mode 100644
index 353af1854..000000000
--- a/deno_dist/middleware/logger/index.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-import { getColorEnabled } from '../../utils/color.ts'
-import { getPath } from '../../utils/url.ts'
-
-enum LogPrefix {
-  Outgoing = '-->',
-  Incoming = '<--',
-  Error = 'xxx',
-}
-
-const humanize = (times: string[]) => {
-  const [delimiter, separator] = [',', '.']
-
-  const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter))
-
-  return orderTimes.join(separator)
-}
-
-const time = (start: number) => {
-  const delta = Date.now() - start
-  return humanize([delta < 1000 ? delta + 'ms' : Math.round(delta / 1000) + 's'])
-}
-
-const colorStatus = (status: number) => {
-  const colorEnabled = getColorEnabled()
-  const out: { [key: string]: string } = {
-    7: colorEnabled ? `\x1b[35m${status}\x1b[0m` : `${status}`,
-    5: colorEnabled ? `\x1b[31m${status}\x1b[0m` : `${status}`,
-    4: colorEnabled ? `\x1b[33m${status}\x1b[0m` : `${status}`,
-    3: colorEnabled ? `\x1b[36m${status}\x1b[0m` : `${status}`,
-    2: colorEnabled ? `\x1b[32m${status}\x1b[0m` : `${status}`,
-    1: colorEnabled ? `\x1b[32m${status}\x1b[0m` : `${status}`,
-    0: colorEnabled ? `\x1b[33m${status}\x1b[0m` : `${status}`,
-  }
-
-  const calculateStatus = (status / 100) | 0
-
-  return out[calculateStatus]
-}
-
-type PrintFunc = (str: string, ...rest: string[]) => void
-
-function log(
-  fn: PrintFunc,
-  prefix: string,
-  method: string,
-  path: string,
-  status: number = 0,
-  elapsed?: string
-) {
-  const out =
-    prefix === LogPrefix.Incoming
-      ? `  ${prefix} ${method} ${path}`
-      : `  ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`
-  fn(out)
-}
-
-/**
- * Logger middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/logger}
- *
- * @param {PrintFunc} [fn=console.log] - Optional function for customized logging behavior.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(logger())
- * app.get('/', (c) => c.text('Hello Hono!'))
- * ```
- */
-export const logger = (fn: PrintFunc = console.log): MiddlewareHandler => {
-  return async function logger(c, next) {
-    const { method } = c.req
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    const path = getPath(c.req.raw)
-
-    log(fn, LogPrefix.Incoming, method, path)
-
-    const start = Date.now()
-
-    await next()
-
-    log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start))
-  }
-}
diff --git a/deno_dist/middleware/method-override/index.ts b/deno_dist/middleware/method-override/index.ts
deleted file mode 100644
index f09591a6a..000000000
--- a/deno_dist/middleware/method-override/index.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import type { Context } from '../../context.ts'
-import type { Hono } from '../../hono.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import { parseBody } from '../../utils/body.ts'
-
-type MethodOverrideOptions = {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  app: Hono<any, any, any>
-} & (
-  | {
-      // Default is 'form' and the value is `_method`
-      form?: string
-      header?: never
-      query?: never
-    }
-  | {
-      form?: never
-      header: string
-      query?: never
-    }
-  | {
-      form?: never
-      header?: never
-      query: string
-    }
-)
-
-const DEFAULT_METHOD_FORM_NAME = '_method'
-
-/**
- * Method Override Middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/method-override}
- *
- * @param {MethodOverrideOptions} options - The options for the method override middleware.
- * @param {Hono} options.app - The instance of Hono is used in your application.
- * @param {string} [options.form=_method] - Form key with a value containing the method name.
- * @param {string} [options.header] - Header name with a value containing the method name.
- * @param {string} [options.query] - Query parameter key with a value containing the method name.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * // If no options are specified, the value of `_method` in the form,
- * // e.g. DELETE, is used as the method.
- * app.use('/posts', methodOverride({ app }))
- *
- * app.delete('/posts', (c) => {
- *   // ....
- * })
- * ```
- */
-export const methodOverride = (options: MethodOverrideOptions): MiddlewareHandler =>
-  async function methodOverride(c, next) {
-    if (c.req.method === 'GET') {
-      return await next()
-    }
-
-    const app = options.app
-    // Method override by form
-    if (!(options.header || options.query)) {
-      const contentType = c.req.header('content-type')
-      const methodFormName = options.form || DEFAULT_METHOD_FORM_NAME
-      const clonedRequest = c.req.raw.clone()
-      const newRequest = clonedRequest.clone()
-      // Content-Type is `multipart/form-data`
-      if (contentType?.startsWith('multipart/form-data')) {
-        const form = await clonedRequest.formData()
-        const method = form.get(methodFormName)
-        if (method) {
-          const newForm = await newRequest.formData()
-          newForm.delete(methodFormName)
-          const newHeaders = new Headers(clonedRequest.headers)
-          newHeaders.delete('content-type')
-          newHeaders.delete('content-length')
-          const request = new Request(c.req.url, {
-            body: newForm,
-            headers: newHeaders,
-            method: method as string,
-          })
-          return app.fetch(request, c.env, getExecutionCtx(c))
-        }
-      }
-      // Content-Type is `application/x-www-form-urlencoded`
-      if (contentType === 'application/x-www-form-urlencoded') {
-        const params = await parseBody<Record<string, string>>(clonedRequest)
-        const method = params[methodFormName]
-        if (method) {
-          delete params[methodFormName]
-          const newParams = new URLSearchParams(params)
-          const request = new Request(newRequest, {
-            body: newParams,
-            method: method as string,
-          })
-          return app.fetch(request, c.env, getExecutionCtx(c))
-        }
-      }
-    }
-    // Method override by header
-    else if (options.header) {
-      const headerName = options.header
-      const method = c.req.header(headerName)
-      if (method) {
-        const newHeaders = new Headers(c.req.raw.headers)
-        newHeaders.delete(headerName)
-        const request = new Request(c.req.raw, {
-          headers: newHeaders,
-          method,
-        })
-        return app.fetch(request, c.env, getExecutionCtx(c))
-      }
-    }
-    // Method override by query
-    else if (options.query) {
-      const queryName = options.query
-      const method = c.req.query(queryName)
-      if (method) {
-        const url = new URL(c.req.url)
-        url.searchParams.delete(queryName)
-        const request = new Request(url.toString(), {
-          body: c.req.raw.body,
-          headers: c.req.raw.headers,
-          method,
-        })
-        return app.fetch(request, c.env, getExecutionCtx(c))
-      }
-    }
-    await next()
-  }
-
-const getExecutionCtx = (c: Context) => {
-  let executionCtx: ExecutionContext | undefined
-  try {
-    executionCtx = c.executionCtx
-  } catch {
-    // Do nothing
-  }
-  return executionCtx
-}
diff --git a/deno_dist/middleware/powered-by/index.ts b/deno_dist/middleware/powered-by/index.ts
deleted file mode 100644
index 4b1e12db0..000000000
--- a/deno_dist/middleware/powered-by/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-
-export const poweredBy = (): MiddlewareHandler => {
-  return async function poweredBy(c, next) {
-    await next()
-    c.res.headers.set('X-Powered-By', 'Hono')
-  }
-}
diff --git a/deno_dist/middleware/pretty-json/index.ts b/deno_dist/middleware/pretty-json/index.ts
deleted file mode 100644
index 1faac1768..000000000
--- a/deno_dist/middleware/pretty-json/index.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-
-type prettyOptions = {
-  space: number
-}
-
-/**
- * Pretty JSON middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/pretty-json}
- *
- * @param {prettyOptions} [options] - The options for the pretty JSON middleware.
- * @param {number} [options.space=2] - Number of spaces for indentation.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(prettyJSON()) // With options: prettyJSON({ space: 4 })
- * app.get('/', (c) => {
- *   return c.json({ message: 'Hono!' })
- * })
- * ```
- */
-export const prettyJSON = (options: prettyOptions = { space: 2 }): MiddlewareHandler => {
-  return async function prettyJSON(c, next) {
-    const pretty = c.req.query('pretty') || c.req.query('pretty') === '' ? true : false
-    await next()
-    if (pretty && c.res.headers.get('Content-Type')?.startsWith('application/json')) {
-      const obj = await c.res.json()
-      c.res = new Response(JSON.stringify(obj, null, options.space), c.res)
-    }
-  }
-}
diff --git a/deno_dist/middleware/serve-static/index.ts b/deno_dist/middleware/serve-static/index.ts
deleted file mode 100644
index ffe71e392..000000000
--- a/deno_dist/middleware/serve-static/index.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import type { Context, Data } from '../../context.ts'
-import type { Env, MiddlewareHandler } from '../../types.ts'
-import { getFilePath, getFilePathWithoutDefaultDocument } from '../../utils/filepath.ts'
-import { getMimeType } from '../../utils/mime.ts'
-
-export type ServeStaticOptions<E extends Env = Env> = {
-  root?: string
-  path?: string
-  mimes?: Record<string, string>
-  rewriteRequestPath?: (path: string) => string
-  onNotFound?: (path: string, c: Context<E>) => void | Promise<void>
-}
-
-const DEFAULT_DOCUMENT = 'index.html'
-const defaultPathResolve = (path: string) => path
-
-/**
- * This middleware is not directly used by the user. Create a wrapper specifying `getContent()` by the environment such as Deno or Bun.
- */
-export const serveStatic = <E extends Env = Env>(
-  options: ServeStaticOptions<E> & {
-    getContent: (path: string, c: Context<E>) => Promise<Data | Response | null>
-    pathResolve?: (path: string) => string
-  }
-): MiddlewareHandler => {
-  return async (c, next) => {
-    // Do nothing if Response is already set
-    if (c.finalized) {
-      await next()
-      return
-    }
-
-    let filename = options.path ?? decodeURI(c.req.path)
-    filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
-    const root = options.root
-
-    let path = getFilePath({
-      filename,
-      root,
-      defaultDocument: DEFAULT_DOCUMENT,
-    })
-
-    if (!path) {
-      return await next()
-    }
-
-    const getContent = options.getContent
-    const pathResolve = options.pathResolve ?? defaultPathResolve
-
-    path = pathResolve(path)
-    let content = await getContent(path, c)
-
-    if (!content) {
-      let pathWithOutDefaultDocument = getFilePathWithoutDefaultDocument({
-        filename,
-        root,
-      })
-      if (!pathWithOutDefaultDocument) {
-        return await next()
-      }
-      pathWithOutDefaultDocument = pathResolve(pathWithOutDefaultDocument)
-      content = await getContent(pathWithOutDefaultDocument, c)
-      if (content) {
-        path = pathWithOutDefaultDocument
-      }
-    }
-
-    if (content instanceof Response) {
-      return c.newResponse(content.body, content)
-    }
-
-    if (content) {
-      let mimeType: string | undefined
-      if (options.mimes) {
-        mimeType = getMimeType(path, options.mimes) ?? getMimeType(path)
-      } else {
-        mimeType = getMimeType(path)
-      }
-      if (mimeType) {
-        c.header('Content-Type', mimeType)
-      }
-      return c.body(content)
-    }
-
-    await options.onNotFound?.(path, c)
-    await next()
-    return
-  }
-}
diff --git a/deno_dist/middleware/timeout/index.ts b/deno_dist/middleware/timeout/index.ts
deleted file mode 100644
index 076bd80aa..000000000
--- a/deno_dist/middleware/timeout/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import type { Context } from '../../context.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-
-export type HTTPExceptionFunction = (context: Context) => HTTPException
-
-const defaultTimeoutException = new HTTPException(504, {
-  message: 'Gateway Timeout',
-})
-
-/**
- * Timeout middleware for Hono.
- *
- * @param {number} duration - The timeout duration in milliseconds.
- * @param {HTTPExceptionFunction | HTTPException} [exception=defaultTimeoutException] - The exception to throw when the timeout occurs. Can be a function that returns an HTTPException or an HTTPException object.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(
- *   '/long-request',
- *   timeout(5000) // Set timeout to 5 seconds
- * )
- *
- * app.get('/long-request', async (c) => {
- *   await someLongRunningFunction()
- *   return c.text('Completed within time limit')
- * })
- * ```
- */
-export const timeout = (
-  duration: number,
-  exception: HTTPExceptionFunction | HTTPException = defaultTimeoutException
-): MiddlewareHandler => {
-  return async function timeout(context, next) {
-    let timer: number | undefined
-    const timeoutPromise = new Promise<void>((_, reject) => {
-      timer = setTimeout(() => {
-        reject(typeof exception === 'function' ? exception(context) : exception)
-      }, duration) as unknown as number
-    })
-
-    try {
-      await Promise.race([next(), timeoutPromise])
-    } finally {
-      if (timer !== undefined) {
-        clearTimeout(timer)
-      }
-    }
-  }
-}
diff --git a/deno_dist/middleware/trailing-slash/index.ts b/deno_dist/middleware/trailing-slash/index.ts
deleted file mode 100644
index 688c4e2e2..000000000
--- a/deno_dist/middleware/trailing-slash/index.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import type { MiddlewareHandler } from '../../types.ts'
-
-/**
- * Trailing slash middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/trailing-slash}
- *
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(trimTrailingSlash())
- * app.get('/about/me/', (c) => c.text('With Trailing Slash'))
- * ```
- */
-export const trimTrailingSlash = (): MiddlewareHandler => {
-  return async function trimTrailingSlash(c, next) {
-    await next()
-
-    if (
-      c.res.status === 404 &&
-      c.req.method === 'GET' &&
-      c.req.path !== '/' &&
-      c.req.path[c.req.path.length - 1] === '/'
-    ) {
-      const url = new URL(c.req.url)
-      url.pathname = url.pathname.substring(0, url.pathname.length - 1)
-
-      c.res = c.redirect(url.toString(), 301)
-    }
-  }
-}
-
-/**
- * Append trailing slash middleware for Hono.
- * Append a trailing slash to the URL if it doesn't have one. For example, `/path/to/page` will be redirected to `/path/to/page/`.
- *
- * @see {@link https://hono.dev/middleware/builtin/trailing-slash}
- *
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(appendTrailingSlash())
- * ```
- */
-export const appendTrailingSlash = (): MiddlewareHandler => {
-  return async function appendTrailingSlash(c, next) {
-    await next()
-
-    if (
-      c.res.status === 404 &&
-      c.req.method === 'GET' &&
-      c.req.path[c.req.path.length - 1] !== '/'
-    ) {
-      const url = new URL(c.req.url)
-      url.pathname += '/'
-
-      c.res = c.redirect(url.toString(), 301)
-    }
-  }
-}
diff --git a/deno_dist/mod.ts b/deno_dist/mod.ts
deleted file mode 100644
index 4f0441b56..000000000
--- a/deno_dist/mod.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Hono } from './hono.ts'
-
-declare global {
-  interface ExecutionContext {
-    waitUntil(promise: Promise<void>): void
-    passThroughOnException(): void
-  }
-}
-
-export type {
-  Env,
-  ErrorHandler,
-  Handler,
-  MiddlewareHandler,
-  Next,
-  NotFoundHandler,
-  ValidationTargets,
-  Input,
-  Schema,
-  ToSchema,
-  TypedResponse,
-} from './types.ts'
-export type { Context, ContextVariableMap, ContextRenderer, ExecutionContext } from './context.ts'
-export type { HonoRequest } from './request.ts'
-export { Hono }
-export { HTTPException } from './http-exception.ts'
-
-// Router
-export { RegExpRouter } from './router/reg-exp-router/index.ts'
-export { TrieRouter } from './router/trie-router/index.ts'
-export { SmartRouter } from './router/smart-router/index.ts'
-export { PatternRouter } from './router/pattern-router/index.ts'
-export { LinearRouter } from './router/linear-router/index.ts'
-
-// Validator
-export { validator } from './validator/index.ts'
-
-// Client
-export { hc } from './client/index.ts'
-export type { InferRequestType, InferResponseType, ClientRequestOptions } from './client/index.ts'
diff --git a/deno_dist/preset/quick.ts b/deno_dist/preset/quick.ts
deleted file mode 100644
index 39b6a468c..000000000
--- a/deno_dist/preset/quick.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { HonoBase } from '../hono-base.ts'
-import type { HonoOptions } from '../hono-base.ts'
-import { LinearRouter } from '../router/linear-router/index.ts'
-import { SmartRouter } from '../router/smart-router/index.ts'
-import { TrieRouter } from '../router/trie-router/index.ts'
-import type { BlankSchema, Env, Schema } from '../types.ts'
-
-export class Hono<
-  E extends Env = Env,
-  S extends Schema = BlankSchema,
-  BasePath extends string = '/'
-> extends HonoBase<E, S, BasePath> {
-  constructor(options: HonoOptions<E> = {}) {
-    super(options)
-    this.router = new SmartRouter({
-      routers: [new LinearRouter(), new TrieRouter()],
-    })
-  }
-}
diff --git a/deno_dist/preset/tiny.ts b/deno_dist/preset/tiny.ts
deleted file mode 100644
index 435a8d968..000000000
--- a/deno_dist/preset/tiny.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { HonoBase } from '../hono-base.ts'
-import type { HonoOptions } from '../hono-base.ts'
-import { PatternRouter } from '../router/pattern-router/index.ts'
-import type { BlankSchema, Env, Schema } from '../types.ts'
-
-export class Hono<
-  E extends Env = Env,
-  S extends Schema = BlankSchema,
-  BasePath extends string = '/'
-> extends HonoBase<E, S, BasePath> {
-  constructor(options: HonoOptions<E> = {}) {
-    super(options)
-    this.router = new PatternRouter()
-  }
-}
diff --git a/deno_dist/request.ts b/deno_dist/request.ts
deleted file mode 100644
index c74d1d2d3..000000000
--- a/deno_dist/request.ts
+++ /dev/null
@@ -1,352 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { Result } from './router.ts'
-import type {
-  Input,
-  InputToDataByTarget,
-  ParamKeys,
-  ParamKeyToRecord,
-  RemoveQuestion,
-  ValidationTargets,
-  RouterRoute,
-} from './types.ts'
-import { parseBody } from './utils/body.ts'
-import type { BodyData, ParseBodyOptions } from './utils/body.ts'
-import type { UnionToIntersection } from './utils/types.ts'
-import { getQueryParam, getQueryParams, decodeURIComponent_ } from './utils/url.ts'
-
-type Body = {
-  json: any
-  text: string
-  arrayBuffer: ArrayBuffer
-  blob: Blob
-  formData: FormData
-}
-type BodyCache = Partial<Body & { parsedBody: BodyData }>
-
-export class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
-  /**
-   * `.raw` can get the raw Request object.
-   * @example
-   * ```ts
-   * // For Cloudflare Workers
-   * app.post('/', async (c) => {
-   *   const metadata = c.req.raw.cf?.hostMetadata?
-   *   ...
-   * })
-   * ```
-   * @see https://hono.dev/api/request#raw
-   */
-  raw: Request
-
-  #validatedData: { [K in keyof ValidationTargets]?: {} } // Short name of validatedData
-  #matchResult: Result<[unknown, RouterRoute]>
-  routeIndex: number = 0
-  /**
-   * `.path` can get the pathname of the request.
-   * @example
-   * ```ts
-   * app.get('/about/me', (c) => {
-   *   const pathname = c.req.path // `/about/me`
-   * })
-   * ```
-   * @see https://hono.dev/api/request#path
-   */
-  path: string
-  bodyCache: BodyCache = {}
-
-  constructor(
-    request: Request,
-    path: string = '/',
-    matchResult: Result<[unknown, RouterRoute]> = [[]]
-  ) {
-    this.raw = request
-    this.path = path
-    this.#matchResult = matchResult
-    this.#validatedData = {}
-  }
-
-  /**
-   * `.req.param()` gets the path parameters.
-   * @example
-   * ```ts
-   * const name = c.req.param('name')
-   * // or all parameters at once
-   * const { id, comment_id } = c.req.param()
-   * ```
-   * @see https://hono.dev/api/routing#path-parameter
-   */
-  param<P2 extends ParamKeys<P> = ParamKeys<P>>(key: P2 extends `${infer _}?` ? never : P2): string
-  param<P2 extends RemoveQuestion<ParamKeys<P>> = RemoveQuestion<ParamKeys<P>>>(
-    key: P2
-  ): string | undefined
-  param(key: string): string | undefined
-  param<P2 extends string = P>(): UnionToIntersection<ParamKeyToRecord<ParamKeys<P2>>>
-  param(key?: string): unknown {
-    return key ? this.getDecodedParam(key) : this.getAllDecodedParams()
-  }
-
-  private getDecodedParam(key: string): string | undefined {
-    const paramKey = this.#matchResult[0][this.routeIndex][1][key]
-    const param = this.getParamValue(paramKey)
-
-    return param ? (/\%/.test(param) ? decodeURIComponent_(param) : param) : undefined
-  }
-
-  private getAllDecodedParams(): Record<string, string> {
-    const decoded: Record<string, string> = {}
-
-    const keys = Object.keys(this.#matchResult[0][this.routeIndex][1])
-    for (const key of keys) {
-      const value = this.getParamValue(this.#matchResult[0][this.routeIndex][1][key])
-      if (value && typeof value === 'string') {
-        decoded[key] = /\%/.test(value) ? decodeURIComponent_(value) : value
-      }
-    }
-
-    return decoded
-  }
-
-  private getParamValue(paramKey: any): string | undefined {
-    return this.#matchResult[1] ? this.#matchResult[1][paramKey as any] : paramKey
-  }
-
-  /**
-   * `.query()` can get querystring parameters.
-   * @example
-   * ```ts
-   * // Query params
-   * app.get('/search', (c) => {
-   *   const query = c.req.query('q')
-   * })
-   *
-   * // Get all params at once
-   * app.get('/search', (c) => {
-   *   const { q, limit, offset } = c.req.query()
-   * })
-   * ```
-   * @see https://hono.dev/api/request#query
-   */
-  query(key: string): string | undefined
-  query(): Record<string, string>
-  query(key?: string) {
-    return getQueryParam(this.url, key)
-  }
-
-  /**
-   * `.queries()` can get multiple querystring parameter values, e.g. /search?tags=A&tags=B
-   * @example
-   * ```ts
-   * app.get('/search', (c) => {
-   *   // tags will be string[]
-   *   const tags = c.req.queries('tags')
-   * })
-   * ```
-   * @see https://hono.dev/api/request#queries
-   */
-  queries(key: string): string[] | undefined
-  queries(): Record<string, string[]>
-  queries(key?: string) {
-    return getQueryParams(this.url, key)
-  }
-
-  /**
-   * `.header()` can get the request header value.
-   * @example
-   * ```ts
-   * app.get('/', (c) => {
-   *   const userAgent = c.req.header('User-Agent')
-   * })
-   * ```
-   * @see https://hono.dev/api/request#header
-   */
-  header(name: string): string | undefined
-  header(): Record<string, string>
-  header(name?: string) {
-    if (name) {
-      return this.raw.headers.get(name.toLowerCase()) ?? undefined
-    }
-
-    const headerData: Record<string, string | undefined> = {}
-    this.raw.headers.forEach((value, key) => {
-      headerData[key] = value
-    })
-    return headerData
-  }
-
-  /**
-   * `.parseBody()` can parse Request body of type `multipart/form-data` or `application/x-www-form-urlencoded`
-   * @example
-   * ```ts
-   * app.post('/entry', async (c) => {
-   *   const body = await c.req.parseBody()
-   * })
-   * ```
-   * @see https://hono.dev/api/request#parsebody
-   */
-  async parseBody<Options extends Partial<ParseBodyOptions>, T extends BodyData<Options>>(
-    options?: Options
-  ): Promise<T>
-  async parseBody<T extends BodyData>(options?: Partial<ParseBodyOptions>): Promise<T>
-  async parseBody(options?: Partial<ParseBodyOptions>) {
-    if (this.bodyCache.parsedBody) {
-      return this.bodyCache.parsedBody
-    }
-    const parsedBody = await parseBody(this, options)
-    this.bodyCache.parsedBody = parsedBody
-    return parsedBody
-  }
-
-  private cachedBody = (key: keyof Body) => {
-    const { bodyCache, raw } = this
-    const cachedBody = bodyCache[key]
-
-    if (cachedBody) {
-      return cachedBody
-    }
-
-    if (!bodyCache[key]) {
-      for (const keyOfBodyCache of Object.keys(bodyCache)) {
-        if (keyOfBodyCache === 'parsedBody') {
-          continue
-        }
-        return (async () => {
-          // @ts-expect-error bodyCache[keyOfBodyCache] can be passed as a body
-          let body = await bodyCache[keyOfBodyCache]
-          if (keyOfBodyCache === 'json') {
-            body = JSON.stringify(body)
-          }
-          return await new Response(body)[key]()
-        })()
-      }
-    }
-
-    return (bodyCache[key] = raw[key]())
-  }
-
-  /**
-   * `.json()` can parse Request body of type `application/json`
-   * @example
-   * ```ts
-   * app.post('/entry', async (c) => {
-   *   const body = await c.req.json()
-   * })
-   * ```
-   * @see https://hono.dev/api/request#json
-   */
-  json<T = any>(): Promise<T> {
-    return this.cachedBody('json')
-  }
-
-  /**
-   * `.text()` can parse Request body of type `text/plain`
-   * @example
-   * ```ts
-   * app.post('/entry', async (c) => {
-   *   const body = await c.req.text()
-   * })
-   * ```
-   * @see https://hono.dev/api/request#text
-   */
-  text(): Promise<string> {
-    return this.cachedBody('text')
-  }
-
-  /**
-   * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
-   * @example
-   * ```ts
-   * app.post('/entry', async (c) => {
-   *   const body = await c.req.arrayBuffer()
-   * })
-   * ```
-   * @see https://hono.dev/api/request#arraybuffer
-   */
-  arrayBuffer(): Promise<ArrayBuffer> {
-    return this.cachedBody('arrayBuffer')
-  }
-
-  blob(): Promise<Blob> {
-    return this.cachedBody('blob')
-  }
-
-  formData(): Promise<FormData> {
-    return this.cachedBody('formData')
-  }
-
-  addValidatedData(target: keyof ValidationTargets, data: {}) {
-    this.#validatedData[target] = data
-  }
-
-  valid<T extends keyof I & keyof ValidationTargets>(target: T): InputToDataByTarget<I, T>
-  valid(target: keyof ValidationTargets) {
-    return this.#validatedData[target] as unknown
-  }
-
-  /**
-   * `.url()` can get the request url strings.
-   * @example
-   * ```ts
-   * app.get('/about/me', (c) => {
-   *   const url = c.req.url // `http://localhost:8787/about/me`
-   *   ...
-   * })
-   * ```
-   * @see https://hono.dev/api/request#url
-   */
-  get url(): string {
-    return this.raw.url
-  }
-
-  /**
-   * `.method()` can get the method name of the request.
-   * @example
-   * ```ts
-   * app.get('/about/me', (c) => {
-   *   const method = c.req.method // `GET`
-   * })
-   * ```
-   * @see https://hono.dev/api/request#method
-   */
-  get method(): string {
-    return this.raw.method
-  }
-
-  /**
-   * `.matchedRoutes()` can return a matched route in the handler
-   * @example
-   * ```ts
-   * app.use('*', async function logger(c, next) {
-   *   await next()
-   *   c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
-   *     const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
-   *     console.log(
-   *       method,
-   *       ' ',
-   *       path,
-   *       ' '.repeat(Math.max(10 - path.length, 0)),
-   *       name,
-   *       i === c.req.routeIndex ? '<- respond from here' : ''
-   *     )
-   *   })
-   * })
-   * ```
-   * @see https://hono.dev/api/request#matchedroutes
-   */
-  get matchedRoutes(): RouterRoute[] {
-    return this.#matchResult[0].map(([[, route]]) => route)
-  }
-
-  /**
-   * `routePath()` can retrieve the path registered within the handler
-   * @example
-   * ```ts
-   * app.get('/posts/:id', (c) => {
-   *   return c.json({ path: c.req.routePath })
-   * })
-   * ```
-   * @see https://hono.dev/api/request#routepath
-   */
-  get routePath(): string {
-    return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path
-  }
-}
diff --git a/deno_dist/router.ts b/deno_dist/router.ts
deleted file mode 100644
index 78cd65e54..000000000
--- a/deno_dist/router.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-export const METHOD_NAME_ALL = 'ALL' as const
-export const METHOD_NAME_ALL_LOWERCASE = 'all' as const
-export const METHODS = ['get', 'post', 'put', 'delete', 'options', 'patch'] as const
-export const MESSAGE_MATCHER_IS_ALREADY_BUILT =
-  'Can not add a route since the matcher is already built.'
-
-export interface Router<T> {
-  name: string
-  add(method: string, path: string, handler: T): void
-  match(method: string, path: string): Result<T>
-}
-
-export type ParamIndexMap = Record<string, number>
-export type ParamStash = string[]
-export type Params = Record<string, string>
-export type Result<T> = [[T, ParamIndexMap][], ParamStash] | [[T, Params][]]
-/*
-The router returns the result of `match` in either format.
-
-[[handler, paramIndexMap][], paramArray]
-e.g.
-[
-  [
-    [middlewareA, {}],                     // '*'
-    [funcA,       {'id': 0}],              // '/user/:id/*'
-    [funcB,       {'id': 0, 'action': 1}], // '/user/:id/:action'
-  ],
-  ['123', 'abc']
-]
-
-[[handler, params][]]
-e.g.
-[
-  [
-    [middlewareA, {}],                             // '*'
-    [funcA,       {'id': '123'}],                  // '/user/:id/*'
-    [funcB,       {'id': '123', 'action': 'abc'}], // '/user/:id/:action'
-  ]
-]
-*/
-
-export class UnsupportedPathError extends Error {}
diff --git a/deno_dist/router/linear-router/index.ts b/deno_dist/router/linear-router/index.ts
deleted file mode 100644
index 5cc0dcfa7..000000000
--- a/deno_dist/router/linear-router/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { LinearRouter } from './router.ts'
diff --git a/deno_dist/router/linear-router/router.ts b/deno_dist/router/linear-router/router.ts
deleted file mode 100644
index f0d0e65d0..000000000
--- a/deno_dist/router/linear-router/router.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import type { Router, Result, Params } from '../../router.ts'
-import { METHOD_NAME_ALL, UnsupportedPathError } from '../../router.ts'
-import { checkOptionalParameter } from '../../utils/url.ts'
-
-type RegExpMatchArrayWithIndices = RegExpMatchArray & { indices: [number, number][] }
-
-const emptyParams = Object.create(null)
-
-const splitPathRe = /\/(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/[^\/\?]+|(\?)/g
-const splitByStarRe = /\*/
-export class LinearRouter<T> implements Router<T> {
-  name: string = 'LinearRouter'
-  routes: [string, string, T][] = []
-
-  add(method: string, path: string, handler: T) {
-    ;(checkOptionalParameter(path) || [path]).forEach((p) => {
-      this.routes.push([method, p, handler])
-    })
-  }
-
-  match(method: string, path: string): Result<T> {
-    const handlers: [T, Params][] = []
-    ROUTES_LOOP: for (let i = 0, len = this.routes.length; i < len; i++) {
-      const [routeMethod, routePath, handler] = this.routes[i]
-      if (routeMethod !== method && routeMethod !== METHOD_NAME_ALL) {
-        continue
-      }
-      if (routePath === '*' || routePath === '/*') {
-        handlers.push([handler, emptyParams])
-        continue
-      }
-
-      const hasStar = routePath.indexOf('*') !== -1
-      const hasLabel = routePath.indexOf(':') !== -1
-      if (!hasStar && !hasLabel) {
-        if (routePath === path || routePath + '/' === path) {
-          handlers.push([handler, emptyParams])
-        }
-      } else if (hasStar && !hasLabel) {
-        const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42
-        const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe)
-
-        const lastIndex = parts.length - 1
-        for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
-          const part = parts[j]
-          const index = path.indexOf(part, pos)
-          if (index !== pos) {
-            continue ROUTES_LOOP
-          }
-          pos += part.length
-          if (j === lastIndex) {
-            if (
-              !endsWithStar &&
-              pos !== path.length &&
-              !(pos === path.length - 1 && path.charCodeAt(pos) === 47)
-            ) {
-              continue ROUTES_LOOP
-            }
-          } else {
-            const index = path.indexOf('/', pos)
-            if (index === -1) {
-              continue ROUTES_LOOP
-            }
-            pos = index
-          }
-        }
-        handlers.push([handler, emptyParams])
-      } else if (hasLabel && !hasStar) {
-        const params: Record<string, string> = Object.create(null)
-        const parts = routePath.match(splitPathRe) as string[]
-
-        const lastIndex = parts.length - 1
-        for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
-          if (pos === -1 || pos >= path.length) {
-            continue ROUTES_LOOP
-          }
-
-          const part = parts[j]
-          if (part.charCodeAt(1) === 58) {
-            // /:label
-            let name = part.slice(2)
-            let value
-
-            if (name.charCodeAt(name.length - 1) === 125) {
-              // :label{pattern}
-              const openBracePos = name.indexOf('{')
-              const pattern = name.slice(openBracePos + 1, -1)
-              const restPath = path.slice(pos + 1)
-              const match = new RegExp(pattern, 'd').exec(restPath) as RegExpMatchArrayWithIndices
-              if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
-                continue ROUTES_LOOP
-              }
-              name = name.slice(0, openBracePos)
-              value = restPath.slice(...match.indices[0])
-              pos += match.indices[0][1] + 1
-            } else {
-              let endValuePos = path.indexOf('/', pos + 1)
-              if (endValuePos === -1) {
-                if (pos + 1 === path.length) {
-                  continue ROUTES_LOOP
-                }
-                endValuePos = path.length
-              }
-              value = path.slice(pos + 1, endValuePos)
-              pos = endValuePos
-            }
-
-            params[name] ||= value as string
-          } else {
-            const index = path.indexOf(part, pos)
-            if (index !== pos) {
-              continue ROUTES_LOOP
-            }
-            pos += part.length
-          }
-
-          if (j === lastIndex) {
-            if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
-              continue ROUTES_LOOP
-            }
-          }
-        }
-
-        handlers.push([handler, params])
-      } else if (hasLabel && hasStar) {
-        throw new UnsupportedPathError()
-      }
-    }
-
-    return [handlers]
-  }
-}
diff --git a/deno_dist/router/pattern-router/index.ts b/deno_dist/router/pattern-router/index.ts
deleted file mode 100644
index 769001511..000000000
--- a/deno_dist/router/pattern-router/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { PatternRouter } from './router.ts'
diff --git a/deno_dist/router/pattern-router/router.ts b/deno_dist/router/pattern-router/router.ts
deleted file mode 100644
index 30898ed3c..000000000
--- a/deno_dist/router/pattern-router/router.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { Result, Router, Params } from '../../router.ts'
-import { METHOD_NAME_ALL, UnsupportedPathError } from '../../router.ts'
-
-type Route<T> = [RegExp, string, T] // [pattern, method, handler, path]
-
-export class PatternRouter<T> implements Router<T> {
-  name: string = 'PatternRouter'
-  private routes: Route<T>[] = []
-
-  add(method: string, path: string, handler: T) {
-    const endsWithWildcard = path[path.length - 1] === '*'
-    if (endsWithWildcard) {
-      path = path.slice(0, -2)
-    }
-    if (path.at(-1) === '?') {
-      path = path.slice(0, -1)
-      this.add(method, path.replace(/\/[^/]+$/, ''), handler)
-    }
-
-    const parts = (path.match(/\/?(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/?[^\/\?]+/g) || []).map(
-      (part) => {
-        const match = part.match(/^\/:([^{]+)(?:{(.*)})?/)
-        return match
-          ? `/(?<${match[1]}>${match[2] || '[^/]+'})`
-          : part === '/*'
-          ? '/[^/]+'
-          : part.replace(/[.\\+*[^\]$()]/g, '\\$&')
-      }
-    )
-
-    let re
-    try {
-      re = new RegExp(`^${parts.join('')}${endsWithWildcard ? '' : '/?$'}`)
-    } catch (e) {
-      throw new UnsupportedPathError()
-    }
-    this.routes.push([re, method, handler])
-  }
-
-  match(method: string, path: string): Result<T> {
-    const handlers: [T, Params][] = []
-
-    for (const [pattern, routeMethod, handler] of this.routes) {
-      if (routeMethod === METHOD_NAME_ALL || routeMethod === method) {
-        const match = pattern.exec(path)
-        if (match) {
-          handlers.push([handler, match.groups || Object.create(null)])
-        }
-      }
-    }
-
-    return [handlers]
-  }
-}
diff --git a/deno_dist/router/reg-exp-router/index.ts b/deno_dist/router/reg-exp-router/index.ts
deleted file mode 100644
index c9347fb82..000000000
--- a/deno_dist/router/reg-exp-router/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { RegExpRouter } from './router.ts'
diff --git a/deno_dist/router/reg-exp-router/node.ts b/deno_dist/router/reg-exp-router/node.ts
deleted file mode 100644
index c894c898f..000000000
--- a/deno_dist/router/reg-exp-router/node.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-const LABEL_REG_EXP_STR = '[^/]+'
-const ONLY_WILDCARD_REG_EXP_STR = '.*'
-const TAIL_WILDCARD_REG_EXP_STR = '(?:|/.*)'
-export const PATH_ERROR = Symbol()
-
-export type ParamAssocArray = [string, number][]
-export interface Context {
-  varIndex: number
-}
-
-const regExpMetaChars = new Set('.\\+*[^]$()')
-
-/**
- * Sort order:
- * 1. literal
- * 2. special pattern (e.g. :label{[0-9]+})
- * 3. common label pattern (e.g. :label)
- * 4. wildcard
- */
-function compareKey(a: string, b: string): number {
-  if (a.length === 1) {
-    return b.length === 1 ? (a < b ? -1 : 1) : -1
-  }
-  if (b.length === 1) {
-    return 1
-  }
-
-  // wildcard
-  if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
-    return 1
-  } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
-    return -1
-  }
-
-  // label
-  if (a === LABEL_REG_EXP_STR) {
-    return 1
-  } else if (b === LABEL_REG_EXP_STR) {
-    return -1
-  }
-
-  return a.length === b.length ? (a < b ? -1 : 1) : b.length - a.length
-}
-
-export class Node {
-  index?: number
-  varIndex?: number
-  children: Record<string, Node> = Object.create(null)
-
-  insert(
-    tokens: readonly string[],
-    index: number,
-    paramMap: ParamAssocArray,
-    context: Context,
-    pathErrorCheckOnly: boolean
-  ): void {
-    if (tokens.length === 0) {
-      if (this.index !== undefined) {
-        throw PATH_ERROR
-      }
-      if (pathErrorCheckOnly) {
-        return
-      }
-
-      this.index = index
-      return
-    }
-
-    const [token, ...restTokens] = tokens
-    const pattern =
-      token === '*'
-        ? restTokens.length === 0
-          ? ['', '', ONLY_WILDCARD_REG_EXP_STR] // '*' matches to all the trailing paths
-          : ['', '', LABEL_REG_EXP_STR]
-        : token === '/*'
-        ? ['', '', TAIL_WILDCARD_REG_EXP_STR] // '/path/to/*' is /\/path\/to(?:|/.*)$
-        : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/)
-
-    let node
-    if (pattern) {
-      const name = pattern[1]
-      let regexpStr = pattern[2] || LABEL_REG_EXP_STR
-      if (name && pattern[2]) {
-        regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, '(?:') // (a|b) => (?:a|b)
-        if (/\((?!\?:)/.test(regexpStr)) {
-          // prefix(?:a|b) is allowed, but prefix(a|b) is not
-          throw PATH_ERROR
-        }
-      }
-
-      node = this.children[regexpStr]
-      if (!node) {
-        if (
-          Object.keys(this.children).some(
-            (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
-          )
-        ) {
-          throw PATH_ERROR
-        }
-        if (pathErrorCheckOnly) {
-          return
-        }
-        node = this.children[regexpStr] = new Node()
-        if (name !== '') {
-          node.varIndex = context.varIndex++
-        }
-      }
-      if (!pathErrorCheckOnly && name !== '') {
-        paramMap.push([name, node.varIndex as number])
-      }
-    } else {
-      node = this.children[token]
-      if (!node) {
-        if (
-          Object.keys(this.children).some(
-            (k) =>
-              k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
-          )
-        ) {
-          throw PATH_ERROR
-        }
-        if (pathErrorCheckOnly) {
-          return
-        }
-        node = this.children[token] = new Node()
-      }
-    }
-
-    node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly)
-  }
-
-  buildRegExpStr(): string {
-    const childKeys = Object.keys(this.children).sort(compareKey)
-
-    const strList = childKeys.map((k) => {
-      const c = this.children[k]
-      return (
-        (typeof c.varIndex === 'number'
-          ? `(${k})@${c.varIndex}`
-          : regExpMetaChars.has(k)
-          ? `\\${k}`
-          : k) + c.buildRegExpStr()
-      )
-    })
-
-    if (typeof this.index === 'number') {
-      strList.unshift(`#${this.index}`)
-    }
-
-    if (strList.length === 0) {
-      return ''
-    }
-    if (strList.length === 1) {
-      return strList[0]
-    }
-
-    return '(?:' + strList.join('|') + ')'
-  }
-}
diff --git a/deno_dist/router/reg-exp-router/router.ts b/deno_dist/router/reg-exp-router/router.ts
deleted file mode 100644
index 1302c6d17..000000000
--- a/deno_dist/router/reg-exp-router/router.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-/* eslint-disable @typescript-eslint/ban-ts-comment */
-import type { Router, Result, ParamIndexMap } from '../../router.ts'
-import {
-  METHOD_NAME_ALL,
-  UnsupportedPathError,
-  MESSAGE_MATCHER_IS_ALREADY_BUILT,
-} from '../../router.ts'
-import { checkOptionalParameter } from '../../utils/url.ts'
-import { PATH_ERROR, type ParamAssocArray } from './node.ts'
-import { Trie } from './trie.ts'
-
-type HandlerData<T> = [T, ParamIndexMap][]
-type StaticMap<T> = Record<string, Result<T>>
-type Matcher<T> = [RegExp, HandlerData<T>[], StaticMap<T>]
-type HandlerWithMetadata<T> = [T, number] // [handler, paramCount]
-
-const emptyParam: string[] = []
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const nullMatcher: Matcher<any> = [/^$/, [], Object.create(null)]
-
-let wildcardRegExpCache: Record<string, RegExp> = Object.create(null)
-function buildWildcardRegExp(path: string): RegExp {
-  return (wildcardRegExpCache[path] ??= new RegExp(
-    path === '*'
-      ? ''
-      : `^${path.replace(/\/\*$|([.\\+*[^\]$()])/g, (_, metaChar) =>
-          metaChar ? `\\${metaChar}` : '(?:|/.*)'
-        )}$`
-  ))
-}
-
-function clearWildcardRegExpCache() {
-  wildcardRegExpCache = Object.create(null)
-}
-
-function buildMatcherFromPreprocessedRoutes<T>(
-  routes: [string, HandlerWithMetadata<T>[]][]
-): Matcher<T> {
-  const trie = new Trie()
-  const handlerData: HandlerData<T>[] = []
-  if (routes.length === 0) {
-    return nullMatcher
-  }
-
-  const routesWithStaticPathFlag = routes
-    .map(
-      (route) => [!/\*|\/:/.test(route[0]), ...route] as [boolean, string, HandlerWithMetadata<T>[]]
-    )
-    .sort(([isStaticA, pathA], [isStaticB, pathB]) =>
-      isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
-    )
-
-  const staticMap: StaticMap<T> = Object.create(null)
-  for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
-    const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i]
-    if (pathErrorCheckOnly) {
-      staticMap[path] = [handlers.map(([h]) => [h, Object.create(null)]), emptyParam]
-    } else {
-      j++
-    }
-
-    let paramAssoc: ParamAssocArray
-    try {
-      paramAssoc = trie.insert(path, j, pathErrorCheckOnly)
-    } catch (e) {
-      throw e === PATH_ERROR ? new UnsupportedPathError(path) : e
-    }
-
-    if (pathErrorCheckOnly) {
-      continue
-    }
-
-    handlerData[j] = handlers.map(([h, paramCount]) => {
-      const paramIndexMap: ParamIndexMap = Object.create(null)
-      paramCount -= 1
-      for (; paramCount >= 0; paramCount--) {
-        const [key, value] = paramAssoc[paramCount]
-        paramIndexMap[key] = value
-      }
-      return [h, paramIndexMap]
-    })
-  }
-
-  const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp()
-  for (let i = 0, len = handlerData.length; i < len; i++) {
-    for (let j = 0, len = handlerData[i].length; j < len; j++) {
-      const map = handlerData[i][j]?.[1]
-      if (!map) {
-        continue
-      }
-      const keys = Object.keys(map)
-      for (let k = 0, len = keys.length; k < len; k++) {
-        map[keys[k]] = paramReplacementMap[map[keys[k]]]
-      }
-    }
-  }
-
-  const handlerMap: HandlerData<T>[] = []
-  // using `in` because indexReplacementMap is a sparse array
-  for (const i in indexReplacementMap) {
-    handlerMap[i] = handlerData[indexReplacementMap[i]]
-  }
-
-  return [regexp, handlerMap, staticMap] as Matcher<T>
-}
-
-function findMiddleware<T>(
-  middleware: Record<string, T[]> | undefined,
-  path: string
-): T[] | undefined {
-  if (!middleware) {
-    return undefined
-  }
-
-  for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
-    if (buildWildcardRegExp(k).test(path)) {
-      return [...middleware[k]]
-    }
-  }
-
-  return undefined
-}
-
-export class RegExpRouter<T> implements Router<T> {
-  name: string = 'RegExpRouter'
-  middleware?: Record<string, Record<string, HandlerWithMetadata<T>[]>>
-  routes?: Record<string, Record<string, HandlerWithMetadata<T>[]>>
-
-  constructor() {
-    this.middleware = { [METHOD_NAME_ALL]: Object.create(null) }
-    this.routes = { [METHOD_NAME_ALL]: Object.create(null) }
-  }
-
-  add(method: string, path: string, handler: T) {
-    const { middleware, routes } = this
-
-    if (!middleware || !routes) {
-      throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT)
-    }
-
-    if (!middleware[method]) {
-      ;[middleware, routes].forEach((handlerMap) => {
-        handlerMap[method] = Object.create(null)
-        Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
-          handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]]
-        })
-      })
-    }
-
-    if (path === '/*') {
-      path = '*'
-    }
-
-    const paramCount = (path.match(/\/:/g) || []).length
-
-    if (/\*$/.test(path)) {
-      const re = buildWildcardRegExp(path)
-      if (method === METHOD_NAME_ALL) {
-        Object.keys(middleware).forEach((m) => {
-          middleware[m][path] ||=
-            findMiddleware(middleware[m], path) ||
-            findMiddleware(middleware[METHOD_NAME_ALL], path) ||
-            []
-        })
-      } else {
-        middleware[method][path] ||=
-          findMiddleware(middleware[method], path) ||
-          findMiddleware(middleware[METHOD_NAME_ALL], path) ||
-          []
-      }
-      Object.keys(middleware).forEach((m) => {
-        if (method === METHOD_NAME_ALL || method === m) {
-          Object.keys(middleware[m]).forEach((p) => {
-            re.test(p) && middleware[m][p].push([handler, paramCount])
-          })
-        }
-      })
-
-      Object.keys(routes).forEach((m) => {
-        if (method === METHOD_NAME_ALL || method === m) {
-          Object.keys(routes[m]).forEach(
-            (p) => re.test(p) && routes[m][p].push([handler, paramCount])
-          )
-        }
-      })
-
-      return
-    }
-
-    const paths = checkOptionalParameter(path) || [path]
-    for (let i = 0, len = paths.length; i < len; i++) {
-      const path = paths[i]
-
-      Object.keys(routes).forEach((m) => {
-        if (method === METHOD_NAME_ALL || method === m) {
-          routes[m][path] ||= [
-            ...(findMiddleware(middleware[m], path) ||
-              findMiddleware(middleware[METHOD_NAME_ALL], path) ||
-              []),
-          ]
-          routes[m][path].push([handler, paramCount - len + i + 1])
-        }
-      })
-    }
-  }
-
-  match(method: string, path: string): Result<T> {
-    clearWildcardRegExpCache() // no longer used.
-
-    const matchers = this.buildAllMatchers()
-
-    this.match = (method, path) => {
-      const matcher = (matchers[method] || matchers[METHOD_NAME_ALL]) as Matcher<T>
-
-      const staticMatch = matcher[2][path]
-      if (staticMatch) {
-        return staticMatch
-      }
-
-      const match = path.match(matcher[0])
-      if (!match) {
-        return [[], emptyParam]
-      }
-
-      const index = match.indexOf('', 1)
-      return [matcher[1][index], match]
-    }
-
-    return this.match(method, path)
-  }
-
-  private buildAllMatchers(): Record<string, Matcher<T> | null> {
-    const matchers: Record<string, Matcher<T> | null> = Object.create(null)
-
-    ;[...Object.keys(this.routes!), ...Object.keys(this.middleware!)].forEach((method) => {
-      matchers[method] ||= this.buildMatcher(method)
-    })
-
-    // Release cache
-    this.middleware = this.routes = undefined
-
-    return matchers
-  }
-
-  private buildMatcher(method: string): Matcher<T> | null {
-    const routes: [string, HandlerWithMetadata<T>[]][] = []
-
-    let hasOwnRoute = method === METHOD_NAME_ALL
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    ;[this.middleware!, this.routes!].forEach((r) => {
-      const ownRoute = r[method]
-        ? Object.keys(r[method]).map((path) => [path, r[method][path]])
-        : []
-      if (ownRoute.length !== 0) {
-        hasOwnRoute ||= true
-        routes.push(...(ownRoute as [string, HandlerWithMetadata<T>[]][]))
-      } else if (method !== METHOD_NAME_ALL) {
-        routes.push(
-          ...(Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]]) as [
-            string,
-            HandlerWithMetadata<T>[]
-          ][])
-        )
-      }
-    })
-
-    if (!hasOwnRoute) {
-      return null
-    } else {
-      return buildMatcherFromPreprocessedRoutes(routes)
-    }
-  }
-}
diff --git a/deno_dist/router/reg-exp-router/trie.ts b/deno_dist/router/reg-exp-router/trie.ts
deleted file mode 100644
index 3e00ad0c0..000000000
--- a/deno_dist/router/reg-exp-router/trie.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import type { ParamAssocArray, Context } from './node.ts'
-import { Node } from './node.ts'
-
-export type ReplacementMap = number[]
-
-export class Trie {
-  context: Context = { varIndex: 0 }
-  root: Node = new Node()
-
-  insert(path: string, index: number, pathErrorCheckOnly: boolean): ParamAssocArray {
-    const paramAssoc: ParamAssocArray = []
-
-    const groups: [string, string][] = [] // [mark, original string]
-    for (let i = 0; ; ) {
-      let replaced = false
-      path = path.replace(/\{[^}]+\}/g, (m) => {
-        const mark = `@\\${i}`
-        groups[i] = [mark, m]
-        i++
-        replaced = true
-        return mark
-      })
-      if (!replaced) {
-        break
-      }
-    }
-
-    /**
-     *  - pattern (:label, :label{0-9]+}, ...)
-     *  - /* wildcard
-     *  - character
-     */
-    const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) || []
-    for (let i = groups.length - 1; i >= 0; i--) {
-      const [mark] = groups[i]
-      for (let j = tokens.length - 1; j >= 0; j--) {
-        if (tokens[j].indexOf(mark) !== -1) {
-          tokens[j] = tokens[j].replace(mark, groups[i][1])
-          break
-        }
-      }
-    }
-
-    this.root.insert(tokens, index, paramAssoc, this.context, pathErrorCheckOnly)
-
-    return paramAssoc
-  }
-
-  buildRegExp(): [RegExp, ReplacementMap, ReplacementMap] {
-    let regexp = this.root.buildRegExpStr()
-    if (regexp === '') {
-      return [/^$/, [], []] // never match
-    }
-
-    let captureIndex = 0
-    const indexReplacementMap: ReplacementMap = []
-    const paramReplacementMap: ReplacementMap = []
-
-    regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
-      if (typeof handlerIndex !== 'undefined') {
-        indexReplacementMap[++captureIndex] = Number(handlerIndex)
-        return '$()'
-      }
-      if (typeof paramIndex !== 'undefined') {
-        paramReplacementMap[Number(paramIndex)] = ++captureIndex
-        return ''
-      }
-
-      return ''
-    })
-
-    return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap]
-  }
-}
diff --git a/deno_dist/router/smart-router/index.ts b/deno_dist/router/smart-router/index.ts
deleted file mode 100644
index 8832c6c46..000000000
--- a/deno_dist/router/smart-router/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { SmartRouter } from './router.ts'
diff --git a/deno_dist/router/smart-router/router.ts b/deno_dist/router/smart-router/router.ts
deleted file mode 100644
index f0ade4671..000000000
--- a/deno_dist/router/smart-router/router.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/* eslint-disable @typescript-eslint/ban-ts-comment */
-import type { Router, Result } from '../../router.ts'
-import { UnsupportedPathError, MESSAGE_MATCHER_IS_ALREADY_BUILT } from '../../router.ts'
-
-export class SmartRouter<T> implements Router<T> {
-  name: string = 'SmartRouter'
-  routers: Router<T>[] = []
-  routes?: [string, string, T][] = []
-
-  constructor(init: Pick<SmartRouter<T>, 'routers'>) {
-    Object.assign(this, init)
-  }
-
-  add(method: string, path: string, handler: T) {
-    if (!this.routes) {
-      throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT)
-    }
-
-    this.routes.push([method, path, handler])
-  }
-
-  match(method: string, path: string): Result<T> {
-    if (!this.routes) {
-      throw new Error('Fatal error')
-    }
-
-    const { routers, routes } = this
-    const len = routers.length
-    let i = 0
-    let res
-    for (; i < len; i++) {
-      const router = routers[i]
-      try {
-        routes.forEach((args) => {
-          router.add(...args)
-        })
-        res = router.match(method, path)
-      } catch (e) {
-        if (e instanceof UnsupportedPathError) {
-          continue
-        }
-        throw e
-      }
-
-      this.match = router.match.bind(router)
-      this.routers = [router]
-      this.routes = undefined
-      break
-    }
-
-    if (i === len) {
-      // not found
-      throw new Error('Fatal error')
-    }
-
-    // e.g. "SmartRouter + RegExpRouter"
-    this.name = `SmartRouter + ${this.activeRouter.name}`
-
-    return res as Result<T>
-  }
-
-  get activeRouter(): Router<T> {
-    if (this.routes || this.routers.length !== 1) {
-      throw new Error('No active router has been determined yet.')
-    }
-
-    return this.routers[0]
-  }
-}
diff --git a/deno_dist/router/trie-router/index.ts b/deno_dist/router/trie-router/index.ts
deleted file mode 100644
index 6417d095b..000000000
--- a/deno_dist/router/trie-router/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { TrieRouter } from './router.ts'
diff --git a/deno_dist/router/trie-router/node.ts b/deno_dist/router/trie-router/node.ts
deleted file mode 100644
index 30f99c85b..000000000
--- a/deno_dist/router/trie-router/node.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-import type { Params } from '../../router.ts'
-import { METHOD_NAME_ALL } from '../../router.ts'
-import type { Pattern } from '../../utils/url.ts'
-import { splitPath, splitRoutingPath, getPattern } from '../../utils/url.ts'
-
-type HandlerSet<T> = {
-  handler: T
-  possibleKeys: string[]
-  score: number
-  name: string // For debug
-}
-
-type HandlerParamsSet<T> = HandlerSet<T> & {
-  params: Record<string, string>
-}
-
-export class Node<T> {
-  methods: Record<string, HandlerSet<T>>[]
-
-  children: Record<string, Node<T>>
-  patterns: Pattern[]
-  order: number = 0
-  name: string
-  params: Record<string, string> = Object.create(null)
-
-  constructor(method?: string, handler?: T, children?: Record<string, Node<T>>) {
-    this.children = children || Object.create(null)
-    this.methods = []
-    this.name = ''
-    if (method && handler) {
-      const m: Record<string, HandlerSet<T>> = Object.create(null)
-      m[method] = { handler, possibleKeys: [], score: 0, name: this.name }
-      this.methods = [m]
-    }
-    this.patterns = []
-  }
-
-  insert(method: string, path: string, handler: T): Node<T> {
-    this.name = `${method} ${path}`
-    this.order = ++this.order
-
-    // eslint-disable-next-line @typescript-eslint/no-this-alias
-    let curNode: Node<T> = this
-    const parts = splitRoutingPath(path)
-
-    const possibleKeys: string[] = []
-
-    for (let i = 0, len = parts.length; i < len; i++) {
-      const p: string = parts[i]
-
-      if (Object.keys(curNode.children).includes(p)) {
-        curNode = curNode.children[p]
-        const pattern = getPattern(p)
-        if (pattern) {
-          possibleKeys.push(pattern[1])
-        }
-        continue
-      }
-
-      curNode.children[p] = new Node()
-
-      const pattern = getPattern(p)
-      if (pattern) {
-        curNode.patterns.push(pattern)
-        possibleKeys.push(pattern[1])
-      }
-      curNode = curNode.children[p]
-    }
-
-    if (!curNode.methods.length) {
-      curNode.methods = []
-    }
-
-    const m: Record<string, HandlerSet<T>> = Object.create(null)
-
-    const handlerSet: HandlerSet<T> = {
-      handler,
-      possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
-      name: this.name,
-      score: this.order,
-    }
-
-    m[method] = handlerSet
-    curNode.methods.push(m)
-
-    return curNode
-  }
-
-  // getHandlerSets
-  private gHSets(
-    node: Node<T>,
-    method: string,
-    nodeParams: Record<string, string>,
-    params: Record<string, string>
-  ): HandlerParamsSet<T>[] {
-    const handlerSets: HandlerParamsSet<T>[] = []
-    for (let i = 0, len = node.methods.length; i < len; i++) {
-      const m = node.methods[i]
-      const handlerSet = (m[method] || m[METHOD_NAME_ALL]) as HandlerParamsSet<T>
-      const processedSet: Record<string, boolean> = Object.create(null)
-      if (handlerSet !== undefined) {
-        handlerSet.params = Object.create(null)
-        handlerSet.possibleKeys.forEach((key) => {
-          const processed = processedSet[handlerSet.name]
-          handlerSet.params[key] =
-            params[key] && !processed ? params[key] : nodeParams[key] ?? params[key]
-          processedSet[handlerSet.name] = true
-        })
-        handlerSets.push(handlerSet)
-      }
-    }
-    return handlerSets
-  }
-
-  search(method: string, path: string): [[T, Params][]] {
-    const handlerSets: HandlerParamsSet<T>[] = []
-    this.params = Object.create(null)
-
-    // eslint-disable-next-line @typescript-eslint/no-this-alias
-    const curNode: Node<T> = this
-    let curNodes = [curNode]
-    const parts = splitPath(path)
-
-    for (let i = 0, len = parts.length; i < len; i++) {
-      const part: string = parts[i]
-      const isLast = i === len - 1
-      const tempNodes: Node<T>[] = []
-
-      for (let j = 0, len2 = curNodes.length; j < len2; j++) {
-        const node = curNodes[j]
-        const nextNode = node.children[part]
-
-        if (nextNode) {
-          nextNode.params = node.params
-          if (isLast === true) {
-            // '/hello/*' => match '/hello'
-            if (nextNode.children['*']) {
-              handlerSets.push(
-                ...this.gHSets(nextNode.children['*'], method, node.params, Object.create(null))
-              )
-            }
-            handlerSets.push(...this.gHSets(nextNode, method, node.params, Object.create(null)))
-          } else {
-            tempNodes.push(nextNode)
-          }
-        }
-
-        for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
-          const pattern = node.patterns[k]
-
-          const params = { ...node.params }
-
-          // Wildcard
-          // '/hello/*/foo' => match /hello/bar/foo
-          if (pattern === '*') {
-            const astNode = node.children['*']
-            if (astNode) {
-              handlerSets.push(...this.gHSets(astNode, method, node.params, Object.create(null)))
-              tempNodes.push(astNode)
-            }
-            continue
-          }
-
-          if (part === '') {
-            continue
-          }
-
-          const [key, name, matcher] = pattern
-
-          const child = node.children[key]
-
-          // `/js/:filename{[a-z]+.js}` => match /js/chunk/123.js
-          const restPathString = parts.slice(i).join('/')
-          if (matcher instanceof RegExp && matcher.test(restPathString)) {
-            params[name] = restPathString
-            handlerSets.push(...this.gHSets(child, method, node.params, params))
-            continue
-          }
-
-          if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
-            if (typeof key === 'string') {
-              params[name] = part
-              if (isLast === true) {
-                handlerSets.push(...this.gHSets(child, method, params, node.params))
-                if (child.children['*']) {
-                  handlerSets.push(...this.gHSets(child.children['*'], method, params, node.params))
-                }
-              } else {
-                child.params = params
-                tempNodes.push(child)
-              }
-            }
-          }
-        }
-      }
-
-      curNodes = tempNodes
-    }
-    const results = handlerSets.sort((a, b) => {
-      return a.score - b.score
-    })
-
-    return [results.map(({ handler, params }) => [handler, params] as [T, Params])]
-  }
-}
diff --git a/deno_dist/router/trie-router/router.ts b/deno_dist/router/trie-router/router.ts
deleted file mode 100644
index 8ae4548c2..000000000
--- a/deno_dist/router/trie-router/router.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { Result, Router } from '../../router.ts'
-import { checkOptionalParameter } from '../../utils/url.ts'
-import { Node } from './node.ts'
-
-export class TrieRouter<T> implements Router<T> {
-  name: string = 'TrieRouter'
-  node: Node<T>
-
-  constructor() {
-    this.node = new Node()
-  }
-
-  add(method: string, path: string, handler: T) {
-    const results = checkOptionalParameter(path)
-    if (results) {
-      for (const p of results) {
-        this.node.insert(method, p, handler)
-      }
-      return
-    }
-
-    this.node.insert(method, path, handler)
-  }
-
-  match(method: string, path: string): Result<T> {
-    return this.node.search(method, path)
-  }
-}
diff --git a/deno_dist/types.ts b/deno_dist/types.ts
deleted file mode 100644
index 00dddc994..000000000
--- a/deno_dist/types.ts
+++ /dev/null
@@ -1,1839 +0,0 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/ban-types */
-import type { Context } from './context.ts'
-import type { Hono } from './hono.ts'
-import type { StatusCode } from './utils/http-status.ts'
-import type {
-  IfAnyThenEmptyObject,
-  IsAny,
-  JSONValue,
-  Prettify,
-  RemoveBlankRecord,
-  Simplify,
-  UnionToIntersection,
-} from './utils/types.ts'
-
-////////////////////////////////////////
-//////                            //////
-//////           Values           //////
-//////                            //////
-////////////////////////////////////////
-
-export type Bindings = Record<string, unknown>
-export type Variables = Record<string, unknown>
-
-export type Env = {
-  Bindings?: Bindings
-  Variables?: Variables
-}
-
-export type Next = () => Promise<void>
-
-export type ExtractInput<I extends Input | Input['in']> = I extends Input
-  ? unknown extends I['in']
-    ? {}
-    : I['in']
-  : I
-export type Input = {
-  in?: {}
-  out?: {}
-  outputFormat?: ResponseFormat
-}
-
-export type BlankSchema = {}
-export type BlankInput = {}
-
-////////////////////////////////////////
-//////                            //////
-//////          Routes            //////
-//////                            //////
-////////////////////////////////////////
-
-export interface RouterRoute {
-  path: string
-  method: string
-  handler: H
-}
-
-////////////////////////////////////////
-//////                            //////
-//////          Handlers          //////
-//////                            //////
-////////////////////////////////////////
-
-export type HandlerResponse<O> = Response | TypedResponse<O> | Promise<Response | TypedResponse<O>>
-
-export type Handler<
-  E extends Env = any,
-  P extends string = any,
-  I extends Input = BlankInput,
-  R extends HandlerResponse<any> = any
-> = (c: Context<E, P, I>, next: Next) => R
-
-export type MiddlewareHandler<
-  E extends Env = any,
-  P extends string = string,
-  I extends Input = {}
-> = (c: Context<E, P, I>, next: Next) => Promise<Response | void>
-
-export type H<
-  E extends Env = any,
-  P extends string = any,
-  I extends Input = BlankInput,
-  R extends HandlerResponse<any> = any
-> = Handler<E, P, I, R> | MiddlewareHandler<E, P, I>
-
-export type NotFoundHandler<E extends Env = any> = (c: Context<E>) => Response | Promise<Response>
-export type ErrorHandler<E extends Env = any> = (
-  err: Error,
-  c: Context<E>
-) => Response | Promise<Response>
-
-////////////////////////////////////////
-//////                            //////
-//////     HandlerInterface       //////
-//////                            //////
-////////////////////////////////////////
-
-export interface HandlerInterface<
-  E extends Env = Env,
-  M extends string = string,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> {
-  // app.get(handler)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    I extends Input = BlankInput,
-    R extends HandlerResponse<any> = any,
-    E2 extends Env = E
-  >(
-    handler: H<E2, P, I, R>
-  ): Hono<IntersectNonAnyTypes<[E, E2]>, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath>
-
-  // app.get(path, handler)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    E2 extends Env = E
-  >(
-    path: P,
-    handler: H<E2, MergedPath, I, R>
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x2)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    R extends HandlerResponse<any> = any,
-    E2 extends Env = E,
-    E3 extends Env = IntersectNonAnyTypes<[E, E2]>
-  >(
-    ...handlers: [H<E2, P, I>, H<E3, P, I2, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3]>,
-    S & ToSchema<M, P, I2, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x2)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    E2 extends Env = E,
-    E3 extends Env = IntersectNonAnyTypes<[E, E2]>
-  >(
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 3)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
-  >(
-    ...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4]>,
-    S & ToSchema<M, P, I3, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x3)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
-  >(
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 4)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
-  >(
-    ...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3>, H<E5, P, I4, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
-    S & ToSchema<M, P, I4, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x4)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 5)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
-  >(
-    ...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3>, H<E5, P, I4>, H<E6, P, I5, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
-    S & ToSchema<M, P, I5, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x5)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 6)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
-  >(
-    ...handlers: [
-      H<E2, P, I>,
-      H<E3, P, I2>,
-      H<E4, P, I3>,
-      H<E5, P, I4>,
-      H<E6, P, I5>,
-      H<E7, P, I6, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
-    S & ToSchema<M, P, I6, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x6)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 7)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
-  >(
-    ...handlers: [
-      H<E2, P, I>,
-      H<E3, P, I2>,
-      H<E4, P, I3>,
-      H<E5, P, I4>,
-      H<E6, P, I5>,
-      H<E7, P, I6>,
-      H<E8, P, I7, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
-    S & ToSchema<M, P, I7, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x7)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 8)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
-  >(
-    ...handlers: [
-      H<E2, P, I>,
-      H<E3, P, I2>,
-      H<E4, P, I3>,
-      H<E5, P, I4>,
-      H<E6, P, I5>,
-      H<E7, P, I6>,
-      H<E8, P, I7>,
-      H<E9, P, I8, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
-    S & ToSchema<M, P, I8, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x8)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 9)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
-  >(
-    ...handlers: [
-      H<E2, P, I>,
-      H<E3, P, I2>,
-      H<E4, P, I3>,
-      H<E5, P, I4>,
-      H<E6, P, I5>,
-      H<E7, P, I6>,
-      H<E8, P, I7>,
-      H<E9, P, I8>,
-      H<E10, P, I9, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
-    S & ToSchema<M, P, I9, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x9)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(handler x 10)
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = E,
-    E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>
-  >(
-    ...handlers: [
-      H<E2, P, I>,
-      H<E3, P, I2>,
-      H<E4, P, I3>,
-      H<E5, P, I4>,
-      H<E6, P, I5>,
-      H<E7, P, I6>,
-      H<E8, P, I7>,
-      H<E9, P, I8>,
-      H<E10, P, I9>,
-      H<E11, P, I10, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
-    S & ToSchema<M, P, I10, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(path, handler x10)
-  <
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = E,
-    E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>
-  >(
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9>,
-      H<E11, MergedPath, I10, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(...handlers[])
-  <
-    P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>,
-    I extends Input = BlankInput,
-    R extends HandlerResponse<any> = any
-  >(
-    ...handlers: H<E, P, I, R>[]
-  ): Hono<E, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath>
-
-  // app.get(path, ...handlers[])
-  <P extends string, I extends Input = BlankInput, R extends HandlerResponse<any> = any>(
-    path: P,
-    ...handlers: H<E, MergePath<BasePath, P>, I, R>[]
-  ): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>
-
-  // app.get(path)
-  <P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(path: P): Hono<
-    E,
-    S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
-    BasePath
-  >
-}
-
-////////////////////////////////////////
-//////                            //////
-////// MiddlewareHandlerInterface //////
-//////                            //////
-////////////////////////////////////////
-
-export interface MiddlewareHandlerInterface<
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> {
-  //// app.use(...handlers[])
-  <E2 extends Env = E>(
-    ...handlers: MiddlewareHandler<E2, MergePath<BasePath, ExtractKey<S>>>[]
-  ): Hono<IntersectNonAnyTypes<[E, E2]>, S, BasePath>
-
-  // app.use(handler)
-  <E2 extends Env = E>(handler: MiddlewareHandler<E2, MergePath<BasePath, ExtractKey<S>>>): Hono<
-    IntersectNonAnyTypes<[E, E2]>,
-    S,
-    BasePath
-  >
-
-  // app.use(handler x2)
-  <
-    E2 extends Env = E,
-    E3 extends Env = IntersectNonAnyTypes<[E, E2]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S, BasePath>
-
-  // app.use(handler x3)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S, BasePath>
-
-  // app.use(handler x4)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S, BasePath>
-
-  // app.use(handler x5)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S, BasePath>
-
-  // app.use(handler x6)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>,
-      MiddlewareHandler<E7, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S, BasePath>
-
-  // app.use(handler x7)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>,
-      MiddlewareHandler<E7, P>,
-      MiddlewareHandler<E8, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S, BasePath>
-
-  // app.use(handler x8)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>,
-      MiddlewareHandler<E7, P>,
-      MiddlewareHandler<E8, P>,
-      MiddlewareHandler<E9, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S, BasePath>
-
-  // app.use(handler x9)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>,
-      MiddlewareHandler<E7, P>,
-      MiddlewareHandler<E8, P>,
-      MiddlewareHandler<E9, P>,
-      MiddlewareHandler<E10, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S, BasePath>
-
-  // app.use(handler x10)
-  <
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = E,
-    E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
-    P extends string = MergePath<BasePath, ExtractKey<S>>
-  >(
-    ...handlers: [
-      MiddlewareHandler<E2, P>,
-      MiddlewareHandler<E3, P>,
-      MiddlewareHandler<E4, P>,
-      MiddlewareHandler<E5, P>,
-      MiddlewareHandler<E6, P>,
-      MiddlewareHandler<E7, P>,
-      MiddlewareHandler<E8, P>,
-      MiddlewareHandler<E9, P>,
-      MiddlewareHandler<E10, P>,
-      MiddlewareHandler<E11, P>
-    ]
-  ): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S, BasePath>
-
-  //// app.use(path, ...handlers[])
-  <P extends string, E2 extends Env = E>(
-    path: P,
-    ...handlers: MiddlewareHandler<E2, MergePath<BasePath, P>>[]
-  ): Hono<E, S, BasePath>
-}
-
-////////////////////////////////////////
-//////                            //////
-//////     OnHandlerInterface     //////
-//////                            //////
-////////////////////////////////////////
-
-export interface OnHandlerInterface<
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> {
-  // app.on(method, path, handler)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    E2 extends Env = E
-  >(
-    method: M,
-    path: P,
-    handler: H<E2, MergedPath, I, R>
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x2)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    E2 extends Env = E,
-    E3 extends Env = IntersectNonAnyTypes<[E, E2]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x3)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x4)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x5)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x6)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x7)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x8)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x9)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.on(method, path, handler x10)
-  <
-    M extends string,
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = E,
-    E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>
-  >(
-    method: M,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9>,
-      H<E11, MergedPath, I10>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
-    S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<HandlerResponse<any>>>,
-    BasePath
-  >
-
-  // app.get(method, path, ...handler)
-  <M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(
-    method: M,
-    path: P,
-    ...handlers: H<E, MergePath<BasePath, P>, I, R>[]
-  ): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>
-
-  // app.get(method[], path, handler)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    E2 extends Env = E
-  >(
-    methods: Ms,
-    path: P,
-    handler: H<E2, MergedPath, I, R>
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x2)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    E2 extends Env = E,
-    E3 extends Env = IntersectNonAnyTypes<[E, E2]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I2, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x3)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I3, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x4)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I4, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x5)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I5, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x6)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I6, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x7)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I7, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x8)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    R extends HandlerResponse<any> = any,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8, R>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I8, MergeTypedResponse<R>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x9)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I9, MergeTypedResponse<HandlerResponse<any>>>,
-    BasePath
-  >
-
-  // app.get(method[], path, handler x10)
-  <
-    Ms extends string[],
-    P extends string,
-    MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
-    I extends Input = BlankInput,
-    I2 extends Input = I,
-    I3 extends Input = I & I2,
-    I4 extends Input = I & I2 & I3,
-    I5 extends Input = I & I2 & I3 & I4,
-    I6 extends Input = I & I2 & I3 & I4 & I5,
-    I7 extends Input = I & I2 & I3 & I4 & I5 & I6,
-    I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7,
-    I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8,
-    I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9,
-    E2 extends Env = E,
-    E3 extends Env = E,
-    E4 extends Env = E,
-    E5 extends Env = E,
-    E6 extends Env = E,
-    E7 extends Env = E,
-    E8 extends Env = E,
-    E9 extends Env = E,
-    E10 extends Env = E,
-    E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>
-  >(
-    methods: Ms,
-    path: P,
-    ...handlers: [
-      H<E2, MergedPath, I>,
-      H<E3, MergedPath, I2>,
-      H<E4, MergedPath, I3>,
-      H<E5, MergedPath, I4>,
-      H<E6, MergedPath, I5>,
-      H<E7, MergedPath, I6>,
-      H<E8, MergedPath, I7>,
-      H<E9, MergedPath, I8>,
-      H<E10, MergedPath, I9>,
-      H<E11, MergedPath, I10>
-    ]
-  ): Hono<
-    IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
-    S & ToSchema<Ms[number], MergePath<BasePath, P>, I10, MergeTypedResponse<HandlerResponse<any>>>,
-    BasePath
-  >
-
-  // app.on(method[], path, ...handler)
-  <P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(
-    methods: string[],
-    path: P,
-    ...handlers: H<E, MergePath<BasePath, P>, I, R>[]
-  ): Hono<E, S & ToSchema<string, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>
-
-  // app.on(method | method[], path[], ...handlers[])
-  <I extends Input = BlankInput, R extends HandlerResponse<any> = any>(
-    methods: string | string[],
-    paths: string[],
-    ...handlers: H<E, any, I, R>[]
-  ): Hono<E, S & ToSchema<string, string, I, MergeTypedResponse<R>>, BasePath>
-}
-
-type ExtractKey<S> = S extends Record<infer Key, unknown>
-  ? Key extends string
-    ? Key
-    : never
-  : string
-
-////////////////////////////////////////
-//////                            //////
-//////           ToSchema           //////
-//////                            //////
-////////////////////////////////////////
-
-export type ToSchema<
-  M extends string,
-  P extends string,
-  I extends Input | Input['in'],
-  RorO // Response or Output
-> = Prettify<{
-  [K in P]: {
-    [K2 in M as AddDollar<K2>]: Simplify<
-      {
-        input: AddParam<ExtractInput<I>, P>
-      } & (IsAny<RorO> extends true
-        ? {
-            output: {}
-            outputFormat: ResponseFormat
-            status: StatusCode
-          }
-        : RorO extends TypedResponse<infer T, infer U, infer F>
-        ? {
-            output: unknown extends T ? {} : T
-            outputFormat: I extends { outputFormat: string } ? I['outputFormat'] : F
-            status: U
-          }
-        : {
-            output: unknown extends RorO ? {} : RorO
-            outputFormat: unknown extends RorO
-              ? 'json'
-              : I extends { outputFormat: string }
-              ? I['outputFormat']
-              : 'json'
-            status: StatusCode
-          })
-    >
-  }
-}>
-
-export type Schema = {
-  [Path: string]: {
-    [Method: `$${Lowercase<string>}`]: Endpoint
-  }
-}
-
-export type Endpoint = {
-  input: Partial<ValidationTargets>
-  output: any
-  outputFormat: ResponseFormat
-  status: StatusCode
-}
-
-type ExtractParams<Path extends string> = string extends Path
-  ? Record<string, string>
-  : Path extends `${infer _Start}:${infer Param}/${infer Rest}`
-  ? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string }
-  : Path extends `${infer _Start}:${infer Param}`
-  ? { [K in Param]: string }
-  : never
-
-type FlattenIfIntersect<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
-
-export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = Prettify<{
-  [P in keyof OrigSchema as MergePath<SubPath, P & string>]: {
-    [M in keyof OrigSchema[P]]: MergeEndpointParamsWithPath<OrigSchema[P][M], SubPath>
-  }
-}>
-
-type MergeEndpointParamsWithPath<T, SubPath extends string> = T extends {
-  input: infer Input
-  output: infer Output
-  outputFormat: infer OutputFormat
-  status: infer Status
-}
-  ? {
-      input: Input extends { param: infer _ }
-        ? ExtractParams<SubPath> extends never
-          ? Input
-          : FlattenIfIntersect<
-              Input & {
-                param: {
-                  // Maps extracted keys, stripping braces, to a string-typed record.
-                  [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}`
-                    ? Prefix
-                    : K]: string
-                }
-              }
-            >
-        : RemoveBlankRecord<ExtractParams<SubPath>> extends never
-        ? Input
-        : Input & {
-            // Maps extracted keys, stripping braces, to a string-typed record.
-            param: {
-              [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}`
-                ? Prefix
-                : K]: string
-            }
-          }
-      output: Output
-      outputFormat: OutputFormat
-      status: Status
-    }
-  : never
-
-export type AddParam<I, P extends string> = ParamKeys<P> extends never
-  ? I
-  : I extends { param: infer _ }
-  ? I
-  : I & { param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>> }
-
-type AddDollar<T extends string> = `$${Lowercase<T>}`
-
-export type MergePath<A extends string, B extends string> = B extends ''
-  ? MergePath<A, '/'>
-  : A extends ''
-  ? B
-  : A extends '/'
-  ? B
-  : A extends `${infer P}/`
-  ? B extends `/${infer Q}`
-    ? `${P}/${Q}`
-    : `${P}/${B}`
-  : B extends `/${infer Q}`
-  ? Q extends ''
-    ? A
-    : `${A}/${Q}`
-  : `${A}/${B}`
-
-////////////////////////////////////////
-//////                            //////
-//////        TypedResponse       //////
-//////                            //////
-////////////////////////////////////////
-
-export type KnownResponseFormat = 'json' | 'text'
-export type ResponseFormat = KnownResponseFormat | string
-
-export type TypedResponse<
-  T = unknown,
-  U extends StatusCode = StatusCode,
-  F extends ResponseFormat = T extends string
-    ? 'text'
-    : T extends JSONValue
-    ? 'json'
-    : ResponseFormat
-> = {
-  data: T
-  status: U
-  format: F
-}
-
-type MergeTypedResponse<T> = T extends Promise<infer T2>
-  ? T2 extends TypedResponse
-    ? T2
-    : TypedResponse
-  : T extends TypedResponse
-  ? T
-  : TypedResponse
-
-////////////////////////////////////////
-//////                             /////
-//////      ValidationTargets      /////
-//////                             /////
-////////////////////////////////////////
-
-export type ValidationTargets = {
-  json: any
-  form: Record<string, string | File>
-  query: Record<string, string | string[]>
-  param: Record<string, string> | Record<string, string | undefined>
-  header: Record<string, string>
-  cookie: Record<string, string>
-}
-
-////////////////////////////////////////
-//////                            //////
-//////      Path parameters       //////
-//////                            //////
-////////////////////////////////////////
-
-type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer Rest}`
-  ? Rest extends `${infer _Pattern}?`
-    ? `${Name}?`
-    : Name
-  : NameWithPattern
-
-type ParamKey<Component> = Component extends `:${infer NameWithPattern}`
-  ? ParamKeyName<NameWithPattern>
-  : never
-
-export type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}`
-  ? ParamKey<Component> | ParamKeys<Rest>
-  : ParamKey<Path>
-
-export type ParamKeyToRecord<T extends string> = T extends `${infer R}?`
-  ? Record<R, string | undefined>
-  : { [K in T]: string }
-
-////////////////////////////////////////
-//////                            //////
-/////       For HonoRequest       //////
-//////                            //////
-////////////////////////////////////////
-
-export type InputToDataByTarget<
-  T extends Input['out'],
-  Target extends keyof ValidationTargets
-> = T extends {
-  [K in Target]: infer R
-}
-  ? R
-  : never
-
-export type RemoveQuestion<T> = T extends `${infer R}?` ? R : T
-
-////////////////////////////////////////
-//////                            //////
-//////         Utilities          //////
-//////                            //////
-////////////////////////////////////////
-
-export type ExtractSchema<T> = UnionToIntersection<
-  T extends Hono<infer _, infer S, any> ? S : never
->
-
-type EnvOrEmpty<T> = T extends Env ? (Env extends T ? {} : T) : T
-type IntersectNonAnyTypes<T extends any[]> = T extends [infer Head, ...infer Rest]
-  ? IfAnyThenEmptyObject<EnvOrEmpty<Head>> & IntersectNonAnyTypes<Rest>
-  : {}
-
-////////////////////////////////////////
-//////                            //////
-//////         FetchEvent         //////
-//////                            //////
-////////////////////////////////////////
-
-export abstract class FetchEventLike {
-  abstract readonly request: Request
-  abstract respondWith(promise: Response | Promise<Response>): void
-  abstract passThroughOnException(): void
-  abstract waitUntil(promise: Promise<void>): void
-}
diff --git a/deno_dist/utils/body.ts b/deno_dist/utils/body.ts
deleted file mode 100644
index c4b7a7287..000000000
--- a/deno_dist/utils/body.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { HonoRequest } from '../request.ts'
-
-type BodyDataValueDot = { [x: string]: string | File | BodyDataValueDot } & {}
-type BodyDataValueDotAll = {
-  [x: string]: string | File | (string | File)[] | BodyDataValueDotAll
-} & {}
-type SimplifyBodyData<T> = {
-  [K in keyof T]: string | File | (string | File)[] | BodyDataValueDotAll extends T[K]
-    ? string | File | (string | File)[] | BodyDataValueDotAll
-    : string | File | BodyDataValueDot extends T[K]
-    ? string | File | BodyDataValueDot
-    : string | File | (string | File)[] extends T[K]
-    ? string | File | (string | File)[]
-    : string | File
-} & {}
-
-type BodyDataValueComponent<T> =
-  | string
-  | File
-  | (T extends { all: false }
-      ? never // explicitly set to false
-      : T extends { all: true } | { all: boolean }
-      ? (string | File)[] // use all option
-      : never) // without options
-type BodyDataValueObject<T> = { [key: string]: BodyDataValueComponent<T> | BodyDataValueObject<T> }
-type BodyDataValue<T> =
-  | BodyDataValueComponent<T>
-  | (T extends { dot: false }
-      ? never // explicitly set to false
-      : T extends { dot: true } | { dot: boolean }
-      ? BodyDataValueObject<T> // use dot option
-      : never) // without options
-export type BodyData<T extends Partial<ParseBodyOptions> = {}> = SimplifyBodyData<
-  Record<string, BodyDataValue<T>>
->
-
-export type ParseBodyOptions = {
-  /**
-   * Determines whether all fields with multiple values should be parsed as arrays.
-   * @default false
-   * @example
-   * const data = new FormData()
-   * data.append('file', 'aaa')
-   * data.append('file', 'bbb')
-   * data.append('message', 'hello')
-   *
-   * If all is false:
-   * parseBody should return { file: 'bbb', message: 'hello' }
-   *
-   * If all is true:
-   * parseBody should return { file: ['aaa', 'bbb'], message: 'hello' }
-   */
-  all: boolean
-  /**
-   * Determines whether all fields with dot notation should be parsed as nested objects.
-   * @default false
-   * @example
-   * const data = new FormData()
-   * data.append('obj.key1', 'value1')
-   * data.append('obj.key2', 'value2')
-   *
-   * If dot is false:
-   * parseBody should return { 'obj.key1': 'value1', 'obj.key2': 'value2' }
-   *
-   * If dot is true:
-   * parseBody should return { obj: { key1: 'value1', key2: 'value2' } }
-   */
-  dot: boolean
-}
-
-/**
- * Parses the body of a request based on the provided options.
- *
- * @template T - The type of the parsed body data.
- * @param {HonoRequest | Request} request - The request object to parse.
- * @param {Partial<ParseBodyOptions>} [options] - Options for parsing the body.
- * @returns {Promise<T>} The parsed body data.
- */
-interface ParseBody {
-  <Options extends Partial<ParseBodyOptions>, T extends BodyData<Options>>(
-    request: HonoRequest | Request,
-    options?: Options
-  ): Promise<T>
-  <T extends BodyData>(
-    request: HonoRequest | Request,
-    options?: Partial<ParseBodyOptions>
-  ): Promise<T>
-}
-export const parseBody: ParseBody = async (
-  request: HonoRequest | Request,
-  options = Object.create(null)
-) => {
-  const { all = false, dot = false } = options
-
-  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers
-  const contentType = headers.get('Content-Type')
-
-  if (
-    (contentType !== null && contentType.startsWith('multipart/form-data')) ||
-    (contentType !== null && contentType.startsWith('application/x-www-form-urlencoded'))
-  ) {
-    return parseFormData(request, { all, dot })
-  }
-
-  return {}
-}
-
-/**
- * Parses form data from a request.
- *
- * @template T - The type of the parsed body data.
- * @param {HonoRequest | Request} request - The request object containing form data.
- * @param {ParseBodyOptions} options - Options for parsing the form data.
- * @returns {Promise<T>} The parsed body data.
- */
-async function parseFormData<T extends BodyData>(
-  request: HonoRequest | Request,
-  options: ParseBodyOptions
-): Promise<T> {
-  const formData = await (request as Request).formData()
-
-  if (formData) {
-    return convertFormDataToBodyData<T>(formData, options)
-  }
-
-  return {} as T
-}
-
-/**
- * Converts form data to body data based on the provided options.
- *
- * @template T - The type of the parsed body data.
- * @param {FormData} formData - The form data to convert.
- * @param {ParseBodyOptions} options - Options for parsing the form data.
- * @returns {T} The converted body data.
- */
-function convertFormDataToBodyData<T extends BodyData>(
-  formData: FormData,
-  options: ParseBodyOptions
-): T {
-  const form: BodyData = Object.create(null)
-
-  formData.forEach((value, key) => {
-    const shouldParseAllValues = options.all || key.endsWith('[]')
-
-    if (shouldParseAllValues) {
-      handleParsingAllValues(form, key, value)
-    } else {
-      form[key] = value
-    }
-  })
-
-  if (options.dot) {
-    const nestedForm: BodyData = Object.create(null)
-
-    Object.entries(form).forEach(([key, value]) => {
-      const shouldParseDotValues = key.includes('.')
-
-      if (shouldParseDotValues) {
-        handleParsingNestedValues(nestedForm, key, value)
-      } else {
-        nestedForm[key] = value
-      }
-    })
-
-    return nestedForm as T
-  }
-
-  return form as T
-}
-
-/**
- * Handles parsing all values for a given key, supporting multiple values as arrays.
- *
- * @param {BodyData} form - The form data object.
- * @param {string} key - The key to parse.
- * @param {FormDataEntryValue} value - The value to assign.
- */
-const handleParsingAllValues = (
-  form: BodyData<{ all: true }>,
-  key: string,
-  value: FormDataEntryValue
-): void => {
-  if (form[key] !== undefined) {
-    if (Array.isArray(form[key])) {
-      ;(form[key] as (string | File)[]).push(value)
-    } else {
-      form[key] = [form[key] as string | File, value]
-    }
-  } else {
-    form[key] = value
-  }
-}
-
-/**
- * Handles parsing nested values using dot notation keys.
- *
- * @param {BodyData} form - The form data object.
- * @param {string} key - The dot notation key.
- * @param {BodyDataValue} value - The value to assign.
- */
-const handleParsingNestedValues = (
-  form: BodyData,
-  key: string,
-  value: BodyDataValue<Partial<ParseBodyOptions>>
-): void => {
-  let nestedForm = form
-  const keys = key.split('.')
-
-  keys.forEach((key, index) => {
-    if (index === keys.length - 1) {
-      nestedForm[key] = value
-    } else {
-      if (
-        !nestedForm[key] ||
-        typeof nestedForm[key] !== 'object' ||
-        Array.isArray(nestedForm[key]) ||
-        nestedForm[key] instanceof File
-      ) {
-        nestedForm[key] = Object.create(null)
-      }
-      nestedForm = nestedForm[key] as unknown as BodyData
-    }
-  })
-}
diff --git a/deno_dist/utils/buffer.ts b/deno_dist/utils/buffer.ts
deleted file mode 100644
index 5ba55a4e0..000000000
--- a/deno_dist/utils/buffer.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { sha256 } from './crypto.ts'
-
-export const equal = (a: ArrayBuffer, b: ArrayBuffer) => {
-  if (a === b) {
-    return true
-  }
-  if (a.byteLength !== b.byteLength) {
-    return false
-  }
-
-  const va = new DataView(a)
-  const vb = new DataView(b)
-
-  let i = va.byteLength
-  while (i--) {
-    if (va.getUint8(i) !== vb.getUint8(i)) {
-      return false
-    }
-  }
-
-  return true
-}
-
-export const timingSafeEqual = async (
-  a: string | object | boolean,
-  b: string | object | boolean,
-  hashFunction?: Function
-) => {
-  if (!hashFunction) {
-    hashFunction = sha256
-  }
-
-  const sa = await hashFunction(a)
-  const sb = await hashFunction(b)
-
-  if (!sa || !sb) {
-    return false
-  }
-
-  return sa === sb && a === b
-}
-
-export const bufferToString = (buffer: ArrayBuffer): string => {
-  if (buffer instanceof ArrayBuffer) {
-    const enc = new TextDecoder('utf-8')
-    return enc.decode(buffer)
-  }
-  return buffer
-}
-
-export const bufferToFormData = (
-  arrayBuffer: ArrayBuffer,
-  contentType: string
-): Promise<FormData> => {
-  const response = new Response(arrayBuffer, {
-    headers: {
-      'Content-Type': contentType,
-    },
-  })
-  return response.formData()
-}
diff --git a/deno_dist/utils/color.ts b/deno_dist/utils/color.ts
deleted file mode 100644
index 7f354e32d..000000000
--- a/deno_dist/utils/color.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export function getColorEnabled(): boolean {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const { process, Deno } = globalThis as any
-
-  const isNoColor =
-    typeof process !== 'undefined'
-      ? // eslint-disable-next-line no-unsafe-optional-chaining
-        'NO_COLOR' in process?.env
-      : typeof Deno?.noColor === 'boolean'
-      ? (Deno.noColor as boolean)
-      : false
-
-  return !isNoColor
-}
diff --git a/deno_dist/utils/concurrent.ts b/deno_dist/utils/concurrent.ts
deleted file mode 100644
index c39859a92..000000000
--- a/deno_dist/utils/concurrent.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-const DEFAULT_CONCURRENCY = 1024
-
-export interface Pool {
-  run<T>(fn: () => T): Promise<T>
-}
-
-export const createPool = ({
-  concurrency,
-  interval,
-}: {
-  concurrency?: number
-  interval?: number
-} = {}): Pool => {
-  concurrency ||= DEFAULT_CONCURRENCY
-
-  if (concurrency === Infinity) {
-    // unlimited
-    return {
-      run: async (fn) => fn(),
-    }
-  }
-
-  const pool: Set<{}> = new Set()
-  const run = async <T>(
-    fn: () => T,
-    promise?: Promise<T>,
-    resolve?: (result: T) => void
-  ): Promise<T> => {
-    if (pool.size >= (concurrency as number)) {
-      promise ||= new Promise<T>((r) => (resolve = r))
-      setTimeout(() => run(fn, promise, resolve))
-      return promise
-    }
-    const marker = {}
-    pool.add(marker)
-    const result = await fn()
-    if (interval) {
-      setTimeout(() => pool.delete(marker), interval)
-    } else {
-      pool.delete(marker)
-    }
-    if (resolve) {
-      resolve(result)
-      return promise as Promise<T>
-    } else {
-      return result
-    }
-  }
-  return { run }
-}
diff --git a/deno_dist/utils/cookie.ts b/deno_dist/utils/cookie.ts
deleted file mode 100644
index 1b3084401..000000000
--- a/deno_dist/utils/cookie.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { decodeURIComponent_ } from './url.ts'
-
-export type Cookie = Record<string, string>
-export type SignedCookie = Record<string, string | false>
-
-type PartitionCookieConstraint =
-  | { partition: true; secure: true }
-  | { partition?: boolean; secure?: boolean } // reset to default
-type SecureCookieConstraint = { secure: true }
-type HostCookieConstraint = { secure: true; path: '/'; domain?: undefined }
-
-export type CookieOptions = {
-  domain?: string
-  expires?: Date
-  httpOnly?: boolean
-  maxAge?: number
-  path?: string
-  secure?: boolean
-  signingSecret?: string
-  sameSite?: 'Strict' | 'Lax' | 'None' | 'strict' | 'lax' | 'none'
-  partitioned?: boolean
-  prefix?: CookiePrefixOptions
-} & PartitionCookieConstraint
-export type CookiePrefixOptions = 'host' | 'secure'
-
-export type CookieConstraint<Name> = Name extends `__Secure-${string}`
-  ? CookieOptions & SecureCookieConstraint
-  : Name extends `__Host-${string}`
-  ? CookieOptions & HostCookieConstraint
-  : CookieOptions
-
-const algorithm = { name: 'HMAC', hash: 'SHA-256' }
-
-const getCryptoKey = async (secret: string | BufferSource): Promise<CryptoKey> => {
-  const secretBuf = typeof secret === 'string' ? new TextEncoder().encode(secret) : secret
-  return await crypto.subtle.importKey('raw', secretBuf, algorithm, false, ['sign', 'verify'])
-}
-
-const makeSignature = async (value: string, secret: string | BufferSource): Promise<string> => {
-  const key = await getCryptoKey(secret)
-  const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value))
-  // the returned base64 encoded signature will always be 44 characters long and end with one or two equal signs
-  return btoa(String.fromCharCode(...new Uint8Array(signature)))
-}
-
-const verifySignature = async (
-  base64Signature: string,
-  value: string,
-  secret: CryptoKey
-): Promise<boolean> => {
-  try {
-    const signatureBinStr = atob(base64Signature)
-    const signature = new Uint8Array(signatureBinStr.length)
-    for (let i = 0, len = signatureBinStr.length; i < len; i++) {
-      signature[i] = signatureBinStr.charCodeAt(i)
-    }
-    return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value))
-  } catch (e) {
-    return false
-  }
-}
-
-// all alphanumeric chars and all of _!#$%&'*.^`|~+-
-// (see: https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1)
-const validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/
-
-// all ASCII chars 32-126 except 34, 59, and 92 (i.e. space to tilde but not double quote, semicolon, or backslash)
-// (see: https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1)
-//
-// note: the spec also prohibits comma and space, but we allow both since they are very common in the real world
-// (see: https://github.com/golang/go/issues/7243)
-const validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/
-
-export const parse = (cookie: string, name?: string): Cookie => {
-  const pairs = cookie.trim().split(';')
-  return pairs.reduce((parsedCookie, pairStr) => {
-    pairStr = pairStr.trim()
-    const valueStartPos = pairStr.indexOf('=')
-    if (valueStartPos === -1) {
-      return parsedCookie
-    }
-
-    const cookieName = pairStr.substring(0, valueStartPos).trim()
-    if ((name && name !== cookieName) || !validCookieNameRegEx.test(cookieName)) {
-      return parsedCookie
-    }
-
-    let cookieValue = pairStr.substring(valueStartPos + 1).trim()
-    if (cookieValue.startsWith('"') && cookieValue.endsWith('"')) {
-      cookieValue = cookieValue.slice(1, -1)
-    }
-    if (validCookieValueRegEx.test(cookieValue)) {
-      parsedCookie[cookieName] = decodeURIComponent_(cookieValue)
-    }
-
-    return parsedCookie
-  }, {} as Cookie)
-}
-
-export const parseSigned = async (
-  cookie: string,
-  secret: string | BufferSource,
-  name?: string
-): Promise<SignedCookie> => {
-  const parsedCookie: SignedCookie = {}
-  const secretKey = await getCryptoKey(secret)
-
-  for (const [key, value] of Object.entries(parse(cookie, name))) {
-    const signatureStartPos = value.lastIndexOf('.')
-    if (signatureStartPos < 1) {
-      continue
-    }
-
-    const signedValue = value.substring(0, signatureStartPos)
-    const signature = value.substring(signatureStartPos + 1)
-    if (signature.length !== 44 || !signature.endsWith('=')) {
-      continue
-    }
-
-    const isVerified = await verifySignature(signature, signedValue, secretKey)
-    parsedCookie[key] = isVerified ? signedValue : false
-  }
-
-  return parsedCookie
-}
-
-const _serialize = (name: string, value: string, opt: CookieOptions = {}): string => {
-  let cookie = `${name}=${value}`
-
-  if (name.startsWith('__Secure-') && !opt.secure) {
-    // FIXME: replace link to RFC
-    // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.3.1
-    throw new Error('__Secure- Cookie must have Secure attributes')
-  }
-
-  if (name.startsWith('__Host-')) {
-    // FIXME: replace link to RFC
-    // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.3.2
-    if (!opt.secure) {
-      throw new Error('__Host- Cookie must have Secure attributes')
-    }
-
-    if (opt.path !== '/') {
-      throw new Error('__Host- Cookie must have Path attributes with "/"')
-    }
-
-    if (opt.domain) {
-      throw new Error('__Host- Cookie must not have Domain attributes')
-    }
-  }
-
-  if (opt && typeof opt.maxAge === 'number' && opt.maxAge >= 0) {
-    if (opt.maxAge > 34560000) {
-      // FIXME: replace link to RFC
-      // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.2.2
-      throw new Error(
-        'Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.'
-      )
-    }
-    cookie += `; Max-Age=${Math.floor(opt.maxAge)}`
-  }
-
-  if (opt.domain && opt.prefix !== 'host') {
-    cookie += `; Domain=${opt.domain}`
-  }
-
-  if (opt.path) {
-    cookie += `; Path=${opt.path}`
-  }
-
-  if (opt.expires) {
-    if (opt.expires.getTime() - Date.now() > 34560000_000) {
-      // FIXME: replace link to RFC
-      // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.2.1
-      throw new Error(
-        'Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.'
-      )
-    }
-    cookie += `; Expires=${opt.expires.toUTCString()}`
-  }
-
-  if (opt.httpOnly) {
-    cookie += '; HttpOnly'
-  }
-
-  if (opt.secure) {
-    cookie += '; Secure'
-  }
-
-  if (opt.sameSite) {
-    cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`
-  }
-
-  if (opt.partitioned) {
-    // FIXME: replace link to RFC
-    // https://www.ietf.org/archive/id/draft-cutler-httpbis-partitioned-cookies-01.html#section-2.3
-    if (!opt.secure) {
-      throw new Error('Partitioned Cookie must have Secure attributes')
-    }
-    cookie += '; Partitioned'
-  }
-
-  return cookie
-}
-
-export const serialize = <Name extends string>(
-  name: Name,
-  value: string,
-  opt?: CookieConstraint<Name>
-): string => {
-  value = encodeURIComponent(value)
-  return _serialize(name, value, opt)
-}
-
-export const serializeSigned = async (
-  name: string,
-  value: string,
-  secret: string | BufferSource,
-  opt: CookieOptions = {}
-): Promise<string> => {
-  const signature = await makeSignature(value, secret)
-  value = `${value}.${signature}`
-  value = encodeURIComponent(value)
-  return _serialize(name, value, opt)
-}
diff --git a/deno_dist/utils/crypto.ts b/deno_dist/utils/crypto.ts
deleted file mode 100644
index b763b507c..000000000
--- a/deno_dist/utils/crypto.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-type Algorithm = {
-  name: string
-  alias: string
-}
-
-type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer | ReadableStream
-
-export const sha256 = async (data: Data) => {
-  const algorithm: Algorithm = { name: 'SHA-256', alias: 'sha256' }
-  const hash = await createHash(data, algorithm)
-  return hash
-}
-
-export const sha1 = async (data: Data) => {
-  const algorithm: Algorithm = { name: 'SHA-1', alias: 'sha1' }
-  const hash = await createHash(data, algorithm)
-  return hash
-}
-
-export const md5 = async (data: Data) => {
-  const algorithm: Algorithm = { name: 'MD5', alias: 'md5' }
-  const hash = await createHash(data, algorithm)
-  return hash
-}
-
-export const createHash = async (data: Data, algorithm: Algorithm): Promise<string | null> => {
-  let sourceBuffer: ArrayBufferView | ArrayBuffer
-
-  if (data instanceof ReadableStream) {
-    let body = ''
-    const reader = data.getReader()
-    await reader?.read().then(async (chuck) => {
-      const value = await createHash(chuck.value || '', algorithm)
-      body += value
-    })
-    return body
-  }
-  if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) {
-    sourceBuffer = data
-  } else {
-    if (typeof data === 'object') {
-      data = JSON.stringify(data)
-    }
-    sourceBuffer = new TextEncoder().encode(String(data))
-  }
-
-  if (crypto && crypto.subtle) {
-    const buffer = await crypto.subtle.digest(
-      {
-        name: algorithm.name,
-      },
-      sourceBuffer as ArrayBuffer
-    )
-    const hash = Array.prototype.map
-      .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
-      .join('')
-    return hash
-  }
-  return null
-}
diff --git a/deno_dist/utils/encode.ts b/deno_dist/utils/encode.ts
deleted file mode 100644
index fe06feec2..000000000
--- a/deno_dist/utils/encode.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export const decodeBase64Url = (str: string): Uint8Array => {
-  return decodeBase64(str.replace(/_|-/g, (m) => ({ _: '/', '-': '+' }[m] ?? m)))
-}
-
-export const encodeBase64Url = (buf: ArrayBufferLike): string =>
-  encodeBase64(buf).replace(/\/|\+/g, (m) => ({ '/': '_', '+': '-' }[m] ?? m))
-
-// This approach is written in MDN.
-// btoa does not support utf-8 characters. So we need a little bit hack.
-export const encodeBase64 = (buf: ArrayBufferLike): string => {
-  let binary = ''
-  const bytes = new Uint8Array(buf)
-  for (let i = 0, len = bytes.length; i < len; i++) {
-    binary += String.fromCharCode(bytes[i])
-  }
-  return btoa(binary)
-}
-
-// atob does not support utf-8 characters. So we need a little bit hack.
-export const decodeBase64 = (str: string): Uint8Array => {
-  const binary = atob(str)
-  const bytes = new Uint8Array(new ArrayBuffer(binary.length))
-  const half = binary.length / 2
-  for (let i = 0, j = binary.length - 1; i <= half; i++, j--) {
-    bytes[i] = binary.charCodeAt(i)
-    bytes[j] = binary.charCodeAt(j)
-  }
-  return bytes
-}
diff --git a/deno_dist/utils/filepath.ts b/deno_dist/utils/filepath.ts
deleted file mode 100644
index 35c6159f7..000000000
--- a/deno_dist/utils/filepath.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-type FilePathOptions = {
-  filename: string
-  root?: string
-  defaultDocument?: string
-}
-
-export const getFilePath = (options: FilePathOptions): string | undefined => {
-  let filename = options.filename
-  const defaultDocument = options.defaultDocument || 'index.html'
-
-  if (filename.endsWith('/')) {
-    // /top/ => /top/index.html
-    filename = filename.concat(defaultDocument)
-  } else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {
-    // /top => /top/index.html
-    filename = filename.concat('/' + defaultDocument)
-  }
-
-  const path = getFilePathWithoutDefaultDocument({
-    root: options.root,
-    filename,
-  })
-
-  return path
-}
-
-export const getFilePathWithoutDefaultDocument = (
-  options: Omit<FilePathOptions, 'defaultDocument'>
-) => {
-  let root = options.root || ''
-  let filename = options.filename
-
-  if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
-    return
-  }
-
-  // /foo.html => foo.html
-  filename = filename.replace(/^\.?[\/\\]/, '')
-
-  // foo\bar.txt => foo/bar.txt
-  filename = filename.replace(/\\/, '/')
-
-  // assets/ => assets
-  root = root.replace(/\/$/, '')
-
-  // ./assets/foo.html => assets/foo.html
-  let path = root ? root + '/' + filename : filename
-  path = path.replace(/^\.?\//, '')
-
-  return path
-}
diff --git a/deno_dist/utils/handler.ts b/deno_dist/utils/handler.ts
deleted file mode 100644
index 29049e64b..000000000
--- a/deno_dist/utils/handler.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { COMPOSED_HANDLER } from '../hono-base.ts'
-
-export const isMiddleware = (handler: Function) => handler.length > 1
-export const findTargetHandler = (handler: Function): Function => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  return (handler as any)[COMPOSED_HANDLER]
-    ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      findTargetHandler((handler as any)[COMPOSED_HANDLER])
-    : handler
-}
diff --git a/deno_dist/utils/html.ts b/deno_dist/utils/html.ts
deleted file mode 100644
index 8b6fdebeb..000000000
--- a/deno_dist/utils/html.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-export const HtmlEscapedCallbackPhase = {
-  Stringify: 1,
-  BeforeStream: 2,
-  Stream: 3,
-} as const
-type HtmlEscapedCallbackOpts = {
-  buffer?: [string]
-  phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase]
-  context: object // An object unique to each JSX tree. This object is used as the WeakMap key.
-}
-export type HtmlEscapedCallback = (opts: HtmlEscapedCallbackOpts) => Promise<string> | undefined
-export type HtmlEscaped = {
-  isEscaped: true
-  callbacks?: HtmlEscapedCallback[]
-}
-export type HtmlEscapedString = string & HtmlEscaped
-
-/**
- * StringBuffer contains string and Promise<string> alternately
- * The length of the array will be odd, the odd numbered element will be a string,
- * and the even numbered element will be a Promise<string>.
- * When concatenating into a single string, it must be processed from the tail.
- * @example
- * [
- *   'framework.',
- *   Promise.resolve('ultra fast'),
- *   'a ',
- *   Promise.resolve('is '),
- *   'Hono',
- * ]
- */
-export type StringBuffer = (string | Promise<string>)[]
-
-export const raw = (value: unknown, callbacks?: HtmlEscapedCallback[]): HtmlEscapedString => {
-  const escapedString = new String(value) as HtmlEscapedString
-  escapedString.isEscaped = true
-  escapedString.callbacks = callbacks
-
-  return escapedString
-}
-
-// The `escapeToBuffer` implementation is based on code from the MIT licensed `react-dom` package.
-// https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/server/escapeTextForBrowser.js
-
-const escapeRe = /[&<>'"]/
-
-export const stringBufferToString = async (buffer: StringBuffer): Promise<HtmlEscapedString> => {
-  let str = ''
-  const callbacks: HtmlEscapedCallback[] = []
-  for (let i = buffer.length - 1; ; i--) {
-    str += buffer[i]
-    i--
-    if (i < 0) {
-      break
-    }
-
-    let r = await buffer[i]
-    if (typeof r === 'object') {
-      callbacks.push(...((r as HtmlEscapedString).callbacks || []))
-    }
-
-    const isEscaped = (r as HtmlEscapedString).isEscaped
-    r = await (typeof r === 'object' ? (r as HtmlEscapedString).toString() : r)
-    if (typeof r === 'object') {
-      callbacks.push(...((r as HtmlEscapedString).callbacks || []))
-    }
-
-    if ((r as HtmlEscapedString).isEscaped ?? isEscaped) {
-      str += r
-    } else {
-      const buf = [str]
-      escapeToBuffer(r, buf)
-      str = buf[0]
-    }
-  }
-
-  return raw(str, callbacks)
-}
-
-export const escapeToBuffer = (str: string, buffer: StringBuffer): void => {
-  const match = str.search(escapeRe)
-  if (match === -1) {
-    buffer[0] += str
-    return
-  }
-
-  let escape
-  let index
-  let lastIndex = 0
-
-  for (index = match; index < str.length; index++) {
-    switch (str.charCodeAt(index)) {
-      case 34: // "
-        escape = '&quot;'
-        break
-      case 39: // '
-        escape = '&#39;'
-        break
-      case 38: // &
-        escape = '&amp;'
-        break
-      case 60: // <
-        escape = '&lt;'
-        break
-      case 62: // >
-        escape = '&gt;'
-        break
-      default:
-        continue
-    }
-
-    buffer[0] += str.substring(lastIndex, index) + escape
-    lastIndex = index + 1
-  }
-
-  buffer[0] += str.substring(lastIndex, index)
-}
-
-export const resolveCallback = async (
-  str: string | HtmlEscapedString,
-  phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase],
-  preserveCallbacks: boolean,
-  context: object,
-  buffer?: [string]
-): Promise<string> => {
-  const callbacks = (str as HtmlEscapedString).callbacks as HtmlEscapedCallback[]
-  if (!callbacks?.length) {
-    return Promise.resolve(str)
-  }
-  if (buffer) {
-    buffer[0] += str
-  } else {
-    buffer = [str]
-  }
-
-  const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then((res) =>
-    Promise.all(
-      res
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
-        .filter<string>(Boolean as any)
-        .map((str) => resolveCallback(str, phase, false, context, buffer))
-    ).then(() => (buffer as [string])[0])
-  )
-
-  if (preserveCallbacks) {
-    return raw(await resStr, callbacks)
-  } else {
-    return resStr
-  }
-}
diff --git a/deno_dist/utils/http-status.ts b/deno_dist/utils/http-status.ts
deleted file mode 100644
index b4d594c1f..000000000
--- a/deno_dist/utils/http-status.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-export type InfoStatusCode = 100 | 101 | 102 | 103
-export type SuccessStatusCode = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226
-export type DeprecatedStatusCode = 305 | 306
-export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | DeprecatedStatusCode | 307 | 308
-export type ClientErrorStatusCode =
-  | 400
-  | 401
-  | 402
-  | 403
-  | 404
-  | 405
-  | 406
-  | 407
-  | 408
-  | 409
-  | 410
-  | 411
-  | 412
-  | 413
-  | 414
-  | 415
-  | 416
-  | 417
-  | 418
-  | 421
-  | 422
-  | 423
-  | 424
-  | 425
-  | 426
-  | 428
-  | 429
-  | 431
-  | 451
-export type ServerErrorStatusCode = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511
-/**
- * `UnOfficalStatusCode` can be used to specify an informal status code.
- * @example
- *
- * ```ts
- * app.get('/', (c) => {
- *   return c.text("hono is cool", 666 as UnOfficalStatusCode)
- * })
- * ```
- */
-export type UnOfficalStatusCode = -1
-
-/**
- * If you want to use an unofficial status, use `UnOfficalStatusCode`.
- */
-export type StatusCode =
-  | InfoStatusCode
-  | SuccessStatusCode
-  | RedirectStatusCode
-  | ClientErrorStatusCode
-  | ServerErrorStatusCode
-  | UnOfficalStatusCode
diff --git a/deno_dist/utils/jwt/index.ts b/deno_dist/utils/jwt/index.ts
deleted file mode 100644
index 53d2eda74..000000000
--- a/deno_dist/utils/jwt/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import { sign, verify, decode } from './jwt.ts'
-export const Jwt = { sign, verify, decode }
diff --git a/deno_dist/utils/jwt/jwa.ts b/deno_dist/utils/jwt/jwa.ts
deleted file mode 100644
index 8512b811c..000000000
--- a/deno_dist/utils/jwt/jwa.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// JSON Web Algorithms (JWA)
-// https://datatracker.ietf.org/doc/html/rfc7518
-
-export enum AlgorithmTypes {
-  HS256 = 'HS256',
-  HS384 = 'HS384',
-  HS512 = 'HS512',
-  RS256 = 'RS256',
-  RS384 = 'RS384',
-  RS512 = 'RS512',
-  PS256 = 'PS256',
-  PS384 = 'PS384',
-  PS512 = 'PS512',
-  ES256 = 'ES256',
-  ES384 = 'ES384',
-  ES512 = 'ES512',
-  EdDSA = 'EdDSA',
-}
-
-export type SignatureAlgorithm = keyof typeof AlgorithmTypes
diff --git a/deno_dist/utils/jwt/jws.ts b/deno_dist/utils/jwt/jws.ts
deleted file mode 100644
index 9578c68e2..000000000
--- a/deno_dist/utils/jwt/jws.ts
+++ /dev/null
@@ -1,224 +0,0 @@
-import { getRuntimeKey } from '../../helper/adapter/index.ts'
-import { decodeBase64 } from '../encode.ts'
-import type { SignatureAlgorithm } from './jwa.ts'
-import { JwtAlgorithmNotImplemented } from './types.ts'
-import { CryptoKeyUsage } from './types.ts'
-import { utf8Encoder } from './utf8.ts'
-
-// JSON Web Signature (JWS)
-// https://datatracker.ietf.org/doc/html/rfc7515
-
-type KeyImporterAlgorithm = Parameters<typeof crypto.subtle.importKey>[2]
-type KeyAlgorithm =
-  | AlgorithmIdentifier
-  | RsaHashedImportParams
-  | (RsaPssParams & RsaHashedImportParams)
-  | (EcdsaParams & EcKeyImportParams)
-  | HmacImportParams
-
-export type SignatureKey = string | JsonWebKey | CryptoKey
-
-export async function signing(
-  privateKey: SignatureKey,
-  alg: SignatureAlgorithm,
-  data: BufferSource
-): Promise<ArrayBuffer> {
-  const algorithm = getKeyAlgorithm(alg)
-  const cryptoKey = await importPrivateKey(privateKey, algorithm)
-  return await crypto.subtle.sign(algorithm, cryptoKey, data)
-}
-
-export async function verifying(
-  publicKey: SignatureKey,
-  alg: SignatureAlgorithm,
-  signature: BufferSource,
-  data: BufferSource
-): Promise<boolean> {
-  const algorithm = getKeyAlgorithm(alg)
-  const cryptoKey = await importPublicKey(publicKey, algorithm)
-  return await crypto.subtle.verify(algorithm, cryptoKey, signature, data)
-}
-
-function pemToBinary(pem: string): Uint8Array {
-  return decodeBase64(pem.replace(/-+(BEGIN|END).*/g, '').replace(/\s/g, ''))
-}
-
-async function importPrivateKey(key: SignatureKey, alg: KeyImporterAlgorithm): Promise<CryptoKey> {
-  if (!crypto.subtle || !crypto.subtle.importKey) {
-    throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')
-  }
-  if (isCryptoKey(key)) {
-    if (key.type !== 'private') {
-      throw new Error(`unexpected non private key: CryptoKey.type is ${key.type}`)
-    }
-    return key
-  }
-  const usages = [CryptoKeyUsage.Sign]
-  if (typeof key === 'object') {
-    // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#json_web_key_import
-    return await crypto.subtle.importKey('jwk', key, alg, false, usages)
-  }
-  if (key.includes('PRIVATE')) {
-    // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#pkcs_8_import
-    return await crypto.subtle.importKey('pkcs8', pemToBinary(key), alg, false, usages)
-  }
-  return await crypto.subtle.importKey('raw', utf8Encoder.encode(key), alg, false, usages)
-}
-
-async function importPublicKey(key: SignatureKey, alg: KeyImporterAlgorithm): Promise<CryptoKey> {
-  if (!crypto.subtle || !crypto.subtle.importKey) {
-    throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')
-  }
-  if (isCryptoKey(key)) {
-    if (key.type === 'public' || key.type === 'secret') {
-      return key
-    }
-    key = await exportPublicJwkFrom(key)
-  }
-  if (typeof key === 'string' && key.includes('PRIVATE')) {
-    // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#pkcs_8_import
-    const privateKey = await crypto.subtle.importKey('pkcs8', pemToBinary(key), alg, true, [
-      CryptoKeyUsage.Sign,
-    ])
-    key = await exportPublicJwkFrom(privateKey)
-  }
-  const usages = [CryptoKeyUsage.Verify]
-  if (typeof key === 'object') {
-    // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#json_web_key_import
-    return await crypto.subtle.importKey('jwk', key, alg, false, usages)
-  }
-  if (key.includes('PUBLIC')) {
-    // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#subjectpublickeyinfo_import
-    return await crypto.subtle.importKey('spki', pemToBinary(key), alg, false, usages)
-  }
-  return await crypto.subtle.importKey('raw', utf8Encoder.encode(key), alg, false, usages)
-}
-
-// https://datatracker.ietf.org/doc/html/rfc7517
-async function exportPublicJwkFrom(privateKey: CryptoKey): Promise<JsonWebKey> {
-  if (privateKey.type !== 'private') {
-    throw new Error(`unexpected key type: ${privateKey.type}`)
-  }
-  if (!privateKey.extractable) {
-    throw new Error('unexpected private key is unextractable')
-  }
-  const jwk = await crypto.subtle.exportKey('jwk', privateKey)
-  const { kty } = jwk // common
-  const { alg, e, n } = jwk // rsa
-  const { crv, x, y } = jwk // elliptic-curve
-  return { kty, alg, e, n, crv, x, y, key_ops: [CryptoKeyUsage.Verify] }
-}
-
-function getKeyAlgorithm(name: SignatureAlgorithm): KeyAlgorithm {
-  switch (name) {
-    case 'HS256':
-      return {
-        name: 'HMAC',
-        hash: {
-          name: 'SHA-256',
-        },
-      } satisfies HmacImportParams
-    case 'HS384':
-      return {
-        name: 'HMAC',
-        hash: {
-          name: 'SHA-384',
-        },
-      } satisfies HmacImportParams
-    case 'HS512':
-      return {
-        name: 'HMAC',
-        hash: {
-          name: 'SHA-512',
-        },
-      } satisfies HmacImportParams
-    case 'RS256':
-      return {
-        name: 'RSASSA-PKCS1-v1_5',
-        hash: {
-          name: 'SHA-256',
-        },
-      } satisfies RsaHashedImportParams
-    case 'RS384':
-      return {
-        name: 'RSASSA-PKCS1-v1_5',
-        hash: {
-          name: 'SHA-384',
-        },
-      } satisfies RsaHashedImportParams
-    case 'RS512':
-      return {
-        name: 'RSASSA-PKCS1-v1_5',
-        hash: {
-          name: 'SHA-512',
-        },
-      } satisfies RsaHashedImportParams
-    case 'PS256':
-      return {
-        name: 'RSA-PSS',
-        hash: {
-          name: 'SHA-256',
-        },
-        saltLength: 32, // 256 >> 3
-      } satisfies RsaPssParams & RsaHashedImportParams
-    case 'PS384':
-      return {
-        name: 'RSA-PSS',
-        hash: {
-          name: 'SHA-384',
-        },
-        saltLength: 48, // 384 >> 3
-      } satisfies RsaPssParams & RsaHashedImportParams
-    case 'PS512':
-      return {
-        name: 'RSA-PSS',
-        hash: {
-          name: 'SHA-512',
-        },
-        saltLength: 64, // 512 >> 3,
-      } satisfies RsaPssParams & RsaHashedImportParams
-    case 'ES256':
-      return {
-        name: 'ECDSA',
-        hash: {
-          name: 'SHA-256',
-        },
-        namedCurve: 'P-256',
-      } satisfies EcdsaParams & EcKeyImportParams
-    case 'ES384':
-      return {
-        name: 'ECDSA',
-        hash: {
-          name: 'SHA-384',
-        },
-        namedCurve: 'P-384',
-      } satisfies EcdsaParams & EcKeyImportParams
-    case 'ES512':
-      return {
-        name: 'ECDSA',
-        hash: {
-          name: 'SHA-512',
-        },
-        namedCurve: 'P-521',
-      } satisfies EcdsaParams & EcKeyImportParams
-    case 'EdDSA':
-      // Currently, supported only Safari and Deno, Node.js.
-      // See: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify
-      return {
-        name: 'Ed25519',
-        namedCurve: 'Ed25519',
-      }
-    default:
-      throw new JwtAlgorithmNotImplemented(name)
-  }
-}
-
-function isCryptoKey(key: SignatureKey): key is CryptoKey {
-  const runtime = getRuntimeKey()
-  // @ts-expect-error CryptoKey hasn't exported to global in node v18
-  if (runtime === 'node' && !!crypto.webcrypto) {
-    // @ts-expect-error CryptoKey hasn't exported to global in node v18
-    return key instanceof crypto.webcrypto.CryptoKey
-  }
-  return key instanceof CryptoKey
-}
diff --git a/deno_dist/utils/jwt/jwt.ts b/deno_dist/utils/jwt/jwt.ts
deleted file mode 100644
index 2efdc4059..000000000
--- a/deno_dist/utils/jwt/jwt.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import { encodeBase64Url, decodeBase64Url } from '../../utils/encode.ts'
-import { AlgorithmTypes, type SignatureAlgorithm } from './jwa.ts'
-import { signing, verifying, type SignatureKey } from './jws.ts'
-import { JwtHeaderInvalid, type JWTPayload } from './types.ts'
-import {
-  JwtTokenInvalid,
-  JwtTokenNotBefore,
-  JwtTokenExpired,
-  JwtTokenSignatureMismatched,
-  JwtTokenIssuedAt,
-} from './types.ts'
-import { utf8Decoder, utf8Encoder } from './utf8.ts'
-
-const encodeJwtPart = (part: unknown): string =>
-  encodeBase64Url(utf8Encoder.encode(JSON.stringify(part))).replace(/=/g, '')
-const encodeSignaturePart = (buf: ArrayBufferLike): string => encodeBase64Url(buf).replace(/=/g, '')
-
-const decodeJwtPart = (part: string): TokenHeader | JWTPayload | undefined =>
-  JSON.parse(utf8Decoder.decode(decodeBase64Url(part)))
-
-export interface TokenHeader {
-  alg: SignatureAlgorithm
-  typ?: 'JWT'
-}
-
-export function isTokenHeader(obj: unknown): obj is TokenHeader {
-  if (typeof obj === 'object' && obj !== null) {
-    const objWithAlg = obj as { [key: string]: unknown }
-    return (
-      'alg' in objWithAlg &&
-      Object.values(AlgorithmTypes).includes(objWithAlg.alg as AlgorithmTypes) &&
-      (!('typ' in objWithAlg) || objWithAlg.typ === 'JWT')
-    )
-  }
-  return false
-}
-
-export const sign = async (
-  payload: JWTPayload,
-  privateKey: SignatureKey,
-  alg: SignatureAlgorithm = 'HS256'
-): Promise<string> => {
-  const encodedPayload = encodeJwtPart(payload)
-  const encodedHeader = encodeJwtPart({ alg, typ: 'JWT' } satisfies TokenHeader)
-
-  const partialToken = `${encodedHeader}.${encodedPayload}`
-
-  const signaturePart = await signing(privateKey, alg, utf8Encoder.encode(partialToken))
-  const signature = encodeSignaturePart(signaturePart)
-
-  return `${partialToken}.${signature}`
-}
-
-export const verify = async (
-  token: string,
-  publicKey: SignatureKey,
-  alg: SignatureAlgorithm = 'HS256'
-): Promise<JWTPayload> => {
-  const tokenParts = token.split('.')
-  if (tokenParts.length !== 3) {
-    throw new JwtTokenInvalid(token)
-  }
-
-  const { header, payload } = decode(token)
-  if (!isTokenHeader(header)) {
-    throw new JwtHeaderInvalid(header)
-  }
-  const now = Math.floor(Date.now() / 1000)
-  if (payload.nbf && payload.nbf > now) {
-    throw new JwtTokenNotBefore(token)
-  }
-  if (payload.exp && payload.exp <= now) {
-    throw new JwtTokenExpired(token)
-  }
-  if (payload.iat && now < payload.iat) {
-    throw new JwtTokenIssuedAt(now, payload.iat)
-  }
-
-  const headerPayload = token.substring(0, token.lastIndexOf('.'))
-  const verified = await verifying(
-    publicKey,
-    alg,
-    decodeBase64Url(tokenParts[2]),
-    utf8Encoder.encode(headerPayload)
-  )
-  if (!verified) {
-    throw new JwtTokenSignatureMismatched(token)
-  }
-
-  return payload
-}
-
-export const decode = (token: string): { header: TokenHeader; payload: JWTPayload } => {
-  try {
-    const [h, p] = token.split('.')
-    const header = decodeJwtPart(h) as TokenHeader
-    const payload = decodeJwtPart(p) as JWTPayload
-    return {
-      header,
-      payload,
-    }
-  } catch (e) {
-    throw new JwtTokenInvalid(token)
-  }
-}
diff --git a/deno_dist/utils/jwt/types.ts b/deno_dist/utils/jwt/types.ts
deleted file mode 100644
index 6278bdf21..000000000
--- a/deno_dist/utils/jwt/types.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-export class JwtAlgorithmNotImplemented extends Error {
-  constructor(alg: string) {
-    super(`${alg} is not an implemented algorithm`)
-    this.name = 'JwtAlgorithmNotImplemented'
-  }
-}
-
-export class JwtTokenInvalid extends Error {
-  constructor(token: string) {
-    super(`invalid JWT token: ${token}`)
-    this.name = 'JwtTokenInvalid'
-  }
-}
-
-export class JwtTokenNotBefore extends Error {
-  constructor(token: string) {
-    super(`token (${token}) is being used before it's valid`)
-    this.name = 'JwtTokenNotBefore'
-  }
-}
-
-export class JwtTokenExpired extends Error {
-  constructor(token: string) {
-    super(`token (${token}) expired`)
-    this.name = 'JwtTokenExpired'
-  }
-}
-
-export class JwtTokenIssuedAt extends Error {
-  constructor(currentTimestamp: number, iat: number) {
-    super(`Incorrect "iat" claim must be a older than "${currentTimestamp}" (iat: "${iat}")`)
-    this.name = 'JwtTokenIssuedAt'
-  }
-}
-
-export class JwtHeaderInvalid extends Error {
-  constructor(header: object) {
-    super(`jwt header is invalid: ${JSON.stringify(header)}`)
-    this.name = 'JwtHeaderInvalid'
-  }
-}
-
-export class JwtTokenSignatureMismatched extends Error {
-  constructor(token: string) {
-    super(`token(${token}) signature mismatched`)
-    this.name = 'JwtTokenSignatureMismatched'
-  }
-}
-
-export enum CryptoKeyUsage {
-  Encrypt = 'encrypt',
-  Decrypt = 'decrypt',
-  Sign = 'sign',
-  Verify = 'verify',
-  DeriveKey = 'deriveKey',
-  DeriveBits = 'deriveBits',
-  WrapKey = 'wrapKey',
-  UnwrapKey = 'unwrapKey',
-}
-
-/**
- * JWT Payload
- */
-export type JWTPayload = {
-  [key: string]: unknown
-  /**
-   * The token is checked to ensure it has not expired.
-   */
-  exp?: number
-  /**
-   * The token is checked to ensure it is not being used before a specified time.
-   */
-  nbf?: number
-  /**
-   * The token is checked to ensure it is not issued in the future.
-   */
-  iat?: number
-}
diff --git a/deno_dist/utils/jwt/utf8.ts b/deno_dist/utils/jwt/utf8.ts
deleted file mode 100644
index 01d1972a1..000000000
--- a/deno_dist/utils/jwt/utf8.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const utf8Encoder: TextEncoder = new TextEncoder()
-export const utf8Decoder: TextDecoder = new TextDecoder()
diff --git a/deno_dist/utils/mime.ts b/deno_dist/utils/mime.ts
deleted file mode 100644
index f0322abc6..000000000
--- a/deno_dist/utils/mime.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-export const getMimeType = (filename: string, mimes = baseMimes): string | undefined => {
-  const regexp = /\.([a-zA-Z0-9]+?)$/
-  const match = filename.match(regexp)
-  if (!match) {
-    return
-  }
-  let mimeType = mimes[match[1]]
-  if ((mimeType && mimeType.startsWith('text')) || mimeType === 'application/json') {
-    mimeType += '; charset=utf-8'
-  }
-  return mimeType
-}
-
-export const getExtension = (mimeType: string): string | undefined => {
-  for (const ext in baseMimes) {
-    if (baseMimes[ext] === mimeType) {
-      return ext
-    }
-  }
-}
-
-export { baseMimes as mimes }
-const baseMimes: Record<string, string> = {
-  aac: 'audio/aac',
-  avi: 'video/x-msvideo',
-  avif: 'image/avif',
-  av1: 'video/av1',
-  bin: 'application/octet-stream',
-  bmp: 'image/bmp',
-  css: 'text/css',
-  csv: 'text/csv',
-  eot: 'application/vnd.ms-fontobject',
-  epub: 'application/epub+zip',
-  gif: 'image/gif',
-  gz: 'application/gzip',
-  htm: 'text/html',
-  html: 'text/html',
-  ico: 'image/x-icon',
-  ics: 'text/calendar',
-  jpeg: 'image/jpeg',
-  jpg: 'image/jpeg',
-  js: 'text/javascript',
-  json: 'application/json',
-  jsonld: 'application/ld+json',
-  map: 'application/json',
-  mid: 'audio/x-midi',
-  midi: 'audio/x-midi',
-  mjs: 'text/javascript',
-  mp3: 'audio/mpeg',
-  mp4: 'video/mp4',
-  mpeg: 'video/mpeg',
-  oga: 'audio/ogg',
-  ogv: 'video/ogg',
-  ogx: 'application/ogg',
-  opus: 'audio/opus',
-  otf: 'font/otf',
-  pdf: 'application/pdf',
-  png: 'image/png',
-  rtf: 'application/rtf',
-  svg: 'image/svg+xml',
-  tif: 'image/tiff',
-  tiff: 'image/tiff',
-  ts: 'video/mp2t',
-  ttf: 'font/ttf',
-  txt: 'text/plain',
-  wasm: 'application/wasm',
-  webm: 'video/webm',
-  weba: 'audio/webm',
-  webp: 'image/webp',
-  woff: 'font/woff',
-  woff2: 'font/woff2',
-  xhtml: 'application/xhtml+xml',
-  xml: 'application/xml',
-  zip: 'application/zip',
-  '3gp': 'video/3gpp',
-  '3g2': 'video/3gpp2',
-  gltf: 'model/gltf+json',
-  glb: 'model/gltf-binary',
-}
diff --git a/deno_dist/utils/stream.ts b/deno_dist/utils/stream.ts
deleted file mode 100644
index b129caf91..000000000
--- a/deno_dist/utils/stream.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-export class StreamingApi {
-  private writer: WritableStreamDefaultWriter<Uint8Array>
-  private encoder: TextEncoder
-  private writable: WritableStream
-  private abortSubscribers: (() => void | Promise<void>)[] = []
-  responseReadable: ReadableStream
-
-  constructor(writable: WritableStream, _readable: ReadableStream) {
-    this.writable = writable
-    this.writer = writable.getWriter()
-    this.encoder = new TextEncoder()
-
-    const reader = _readable.getReader()
-
-    // in case the user disconnects, let the reader know to cancel
-    // this in-turn results in responseReadable being closed
-    // and writeSSE method no longer blocks indefinitely
-    this.abortSubscribers.push(async () => {
-      await reader.cancel()
-    })
-
-    this.responseReadable = new ReadableStream({
-      async pull(controller) {
-        const { done, value } = await reader.read()
-        done ? controller.close() : controller.enqueue(value)
-      },
-      cancel: () => {
-        this.abortSubscribers.forEach((subscriber) => subscriber())
-      },
-    })
-  }
-
-  async write(input: Uint8Array | string): Promise<StreamingApi> {
-    try {
-      if (typeof input === 'string') {
-        input = this.encoder.encode(input)
-      }
-      await this.writer.write(input)
-    } catch (e) {
-      // Do nothing. If you want to handle errors, create a stream by yourself.
-    }
-    return this
-  }
-
-  async writeln(input: string): Promise<StreamingApi> {
-    await this.write(input + '\n')
-    return this
-  }
-
-  sleep(ms: number): Promise<unknown> {
-    return new Promise((res) => setTimeout(res, ms))
-  }
-
-  async close() {
-    try {
-      await this.writer.close()
-    } catch (e) {
-      // Do nothing. If you want to handle errors, create a stream by yourself.
-    }
-  }
-
-  async pipe(body: ReadableStream) {
-    this.writer.releaseLock()
-    await body.pipeTo(this.writable, { preventClose: true })
-    this.writer = this.writable.getWriter()
-  }
-
-  onAbort(listener: () => void | Promise<void>) {
-    this.abortSubscribers.push(listener)
-  }
-}
diff --git a/deno_dist/utils/types.ts b/deno_dist/utils/types.ts
deleted file mode 100644
index cedaa1bc5..000000000
--- a/deno_dist/utils/types.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-export type Expect<T extends true> = T
-export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
-  ? true
-  : false
-export type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true
-
-export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
-  k: infer I
-) => void
-  ? I
-  : never
-
-export type RemoveBlankRecord<T> = T extends Record<infer K, unknown>
-  ? K extends string
-    ? T
-    : never
-  : never
-
-export type IfAnyThenEmptyObject<T> = 0 extends 1 & T ? {} : T
-
-export type JSONPrimitive = string | boolean | number | null | undefined
-export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[]
-export type JSONObject = { [key: string]: JSONPrimitive | JSONArray | JSONObject | object }
-export type JSONValue = JSONObject | JSONArray | JSONPrimitive
-// Non-JSON values such as `Date` implement `.toJSON()`, so they can be transformed to a value assignable to `JSONObject`:
-export type JSONParsed<T> = T extends { toJSON(): infer J }
-  ? (() => J) extends () => JSONObject
-    ? J
-    : JSONParsed<J>
-  : T extends JSONPrimitive
-  ? T
-  : T extends Array<infer U>
-  ? Array<JSONParsed<U>>
-  : T extends object
-  ? { [K in keyof T]: JSONParsed<T[K]> }
-  : never
-
-// from sindresorhus/type-fest
-export type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {}
-
-export type InterfaceToType<T> = T extends Function ? T : { [K in keyof T]: InterfaceToType<T[K]> }
-
-export type RequiredKeysOf<BaseType extends object> = Exclude<
-  {
-    [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never
-  }[keyof BaseType],
-  undefined
->
-
-export type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never
-  ? false
-  : true
-
-export type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false
-
-export type Prettify<T> = {
-  [K in keyof T]: T[K]
-} & {}
diff --git a/deno_dist/utils/url.ts b/deno_dist/utils/url.ts
deleted file mode 100644
index 58349064e..000000000
--- a/deno_dist/utils/url.ts
+++ /dev/null
@@ -1,305 +0,0 @@
-export type Pattern = readonly [string, string, RegExp | true] | '*'
-
-export const splitPath = (path: string): string[] => {
-  const paths = path.split('/')
-  if (paths[0] === '') {
-    paths.shift()
-  }
-  return paths
-}
-
-export const splitRoutingPath = (routePath: string): string[] => {
-  const { groups, path } = extractGroupsFromPath(routePath)
-
-  const paths = splitPath(path)
-  return replaceGroupMarks(paths, groups)
-}
-
-const extractGroupsFromPath = (path: string): { groups: [string, string][]; path: string } => {
-  const groups: [string, string][] = []
-
-  path = path.replace(/\{[^}]+\}/g, (match, index) => {
-    const mark = `@${index}`
-    groups.push([mark, match])
-    return mark
-  })
-
-  return { groups, path }
-}
-
-const replaceGroupMarks = (paths: string[], groups: [string, string][]): string[] => {
-  for (let i = groups.length - 1; i >= 0; i--) {
-    const [mark] = groups[i]
-
-    for (let j = paths.length - 1; j >= 0; j--) {
-      if (paths[j].includes(mark)) {
-        paths[j] = paths[j].replace(mark, groups[i][1])
-        break
-      }
-    }
-  }
-
-  return paths
-}
-
-const patternCache: { [key: string]: Pattern } = {}
-export const getPattern = (label: string): Pattern | null => {
-  // *            => wildcard
-  // :id{[0-9]+}  => ([0-9]+)
-  // :id          => (.+)
-  //const name = ''
-
-  if (label === '*') {
-    return '*'
-  }
-
-  const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/)
-  if (match) {
-    if (!patternCache[label]) {
-      if (match[2]) {
-        patternCache[label] = [label, match[1], new RegExp('^' + match[2] + '$')]
-      } else {
-        patternCache[label] = [label, match[1], true]
-      }
-    }
-
-    return patternCache[label]
-  }
-
-  return null
-}
-
-/**
- * Try to apply decodeURI() to given string.
- * If it fails, skip invalid percent encoding or invalid UTF-8 sequences, and apply decodeURI() to the rest as much as possible.
- * @param str The string to decode.
- * @returns The decoded string that sometimes contains undecodable percent encoding.
- * @example
- * tryDecodeURI('Hello%20World') // 'Hello World'
- * tryDecodeURI('Hello%20World/%A4%A2') // 'Hello World/%A4%A2'
- */
-const tryDecodeURI = (str: string): string => {
-  try {
-    return decodeURI(str)
-  } catch {
-    return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
-      try {
-        return decodeURI(match)
-      } catch {
-        return match
-      }
-    })
-  }
-}
-
-export const getPath = (request: Request): string => {
-  const url = request.url
-  const start = url.indexOf('/', 8)
-  let i = start
-  for (; i < url.length; i++) {
-    const charCode = url.charCodeAt(i)
-    if (charCode === 37) {
-      // '%'
-      // If the path contains percent encoding, use `indexOf()` to find '?' and return the result immediately.
-      // Although this is a performance disadvantage, it is acceptable since we prefer cases that do not include percent encoding.
-      const queryIndex = url.indexOf('?', i)
-      const path = url.slice(start, queryIndex === -1 ? undefined : queryIndex)
-      return tryDecodeURI(path.includes('%25') ? path.replace(/%25/g, '%2525') : path)
-    } else if (charCode === 63) {
-      // '?'
-      break
-    }
-  }
-  return url.slice(start, i)
-}
-
-export const getQueryStrings = (url: string): string => {
-  const queryIndex = url.indexOf('?', 8)
-  return queryIndex === -1 ? '' : '?' + url.slice(queryIndex + 1)
-}
-
-export const getPathNoStrict = (request: Request): string => {
-  const result = getPath(request)
-
-  // if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
-  return result.length > 1 && result[result.length - 1] === '/' ? result.slice(0, -1) : result
-}
-
-export const mergePath = (...paths: string[]): string => {
-  let p: string = ''
-  let endsWithSlash = false
-
-  for (let path of paths) {
-    /* ['/hey/','/say'] => ['/hey', '/say'] */
-    if (p[p.length - 1] === '/') {
-      p = p.slice(0, -1)
-      endsWithSlash = true
-    }
-
-    /* ['/hey','say'] => ['/hey', '/say'] */
-    if (path[0] !== '/') {
-      path = `/${path}`
-    }
-
-    /* ['/hey/', '/'] => `/hey/` */
-    if (path === '/' && endsWithSlash) {
-      p = `${p}/`
-    } else if (path !== '/') {
-      p = `${p}${path}`
-    }
-
-    /* ['/', '/'] => `/` */
-    if (path === '/' && p === '') {
-      p = '/'
-    }
-  }
-
-  return p
-}
-
-export const checkOptionalParameter = (path: string): string[] | null => {
-  /*
-   If path is `/api/animals/:type?` it will return:
-   [`/api/animals`, `/api/animals/:type`]
-   in other cases it will return null
-  */
-
-  if (!path.match(/\:.+\?$/)) {
-    return null
-  }
-
-  const segments = path.split('/')
-  const results: string[] = []
-  let basePath = ''
-
-  segments.forEach((segment) => {
-    if (segment !== '' && !/\:/.test(segment)) {
-      basePath += '/' + segment
-    } else if (/\:/.test(segment)) {
-      if (/\?/.test(segment)) {
-        if (results.length === 0 && basePath === '') {
-          results.push('/')
-        } else {
-          results.push(basePath)
-        }
-        const optionalSegment = segment.replace('?', '')
-        basePath += '/' + optionalSegment
-        results.push(basePath)
-      } else {
-        basePath += '/' + segment
-      }
-    }
-  })
-
-  return results.filter((v, i, a) => a.indexOf(v) === i)
-}
-
-// Optimized
-const _decodeURI = (value: string) => {
-  if (!/[%+]/.test(value)) {
-    return value
-  }
-  if (value.indexOf('+') !== -1) {
-    value = value.replace(/\+/g, ' ')
-  }
-  return /%/.test(value) ? decodeURIComponent_(value) : value
-}
-
-const _getQueryParam = (
-  url: string,
-  key?: string,
-  multiple?: boolean
-): string | undefined | Record<string, string> | string[] | Record<string, string[]> => {
-  let encoded
-
-  if (!multiple && key && !/[%+]/.test(key)) {
-    // optimized for unencoded key
-
-    let keyIndex = url.indexOf(`?${key}`, 8)
-    if (keyIndex === -1) {
-      keyIndex = url.indexOf(`&${key}`, 8)
-    }
-    while (keyIndex !== -1) {
-      const trailingKeyCode = url.charCodeAt(keyIndex + key.length + 1)
-      if (trailingKeyCode === 61) {
-        const valueIndex = keyIndex + key.length + 2
-        const endIndex = url.indexOf('&', valueIndex)
-        return _decodeURI(url.slice(valueIndex, endIndex === -1 ? undefined : endIndex))
-      } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
-        return ''
-      }
-      keyIndex = url.indexOf(`&${key}`, keyIndex + 1)
-    }
-
-    encoded = /[%+]/.test(url)
-    if (!encoded) {
-      return undefined
-    }
-    // fallback to default routine
-  }
-
-  const results: Record<string, string> | Record<string, string[]> = {}
-  encoded ??= /[%+]/.test(url)
-
-  let keyIndex = url.indexOf('?', 8)
-  while (keyIndex !== -1) {
-    const nextKeyIndex = url.indexOf('&', keyIndex + 1)
-    let valueIndex = url.indexOf('=', keyIndex)
-    if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
-      valueIndex = -1
-    }
-    let name = url.slice(
-      keyIndex + 1,
-      valueIndex === -1 ? (nextKeyIndex === -1 ? undefined : nextKeyIndex) : valueIndex
-    )
-    if (encoded) {
-      name = _decodeURI(name)
-    }
-
-    keyIndex = nextKeyIndex
-
-    if (name === '') {
-      continue
-    }
-
-    let value
-    if (valueIndex === -1) {
-      value = ''
-    } else {
-      value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? undefined : nextKeyIndex)
-      if (encoded) {
-        value = _decodeURI(value)
-      }
-    }
-
-    if (multiple) {
-      if (!(results[name] && Array.isArray(results[name]))) {
-        results[name] = []
-      }
-      ;(results[name] as string[]).push(value)
-    } else {
-      results[name] ??= value
-    }
-  }
-
-  return key ? results[key] : results
-}
-
-export const getQueryParam: (
-  url: string,
-  key?: string
-) => string | undefined | Record<string, string> = _getQueryParam as (
-  url: string,
-  key?: string
-) => string | undefined | Record<string, string>
-
-export const getQueryParams = (
-  url: string,
-  key?: string
-): string[] | undefined | Record<string, string[]> => {
-  return _getQueryParam(url, key, true) as string[] | undefined | Record<string, string[]>
-}
-
-// `decodeURIComponent` is a long name.
-// By making it a function, we can use it commonly when minified, reducing the amount of code.
-export const decodeURIComponent_ = decodeURIComponent
diff --git a/deno_dist/validator/index.ts b/deno_dist/validator/index.ts
deleted file mode 100644
index 0e1bcd1d1..000000000
--- a/deno_dist/validator/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { validator } from './validator.ts'
-export type { ValidationFunction } from './validator.ts'
diff --git a/deno_dist/validator/validator.ts b/deno_dist/validator/validator.ts
deleted file mode 100644
index 564375c2f..000000000
--- a/deno_dist/validator/validator.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import type { Context } from '../context.ts'
-import { getCookie } from '../helper/cookie/index.ts'
-import { HTTPException } from '../http-exception.ts'
-import type { Env, ValidationTargets, MiddlewareHandler, TypedResponse } from '../types.ts'
-import type { BodyData } from '../utils/body.ts'
-import { bufferToFormData } from '../utils/buffer.ts'
-
-type ValidationTargetKeysWithBody = 'form' | 'json'
-type ValidationTargetByMethod<M> = M extends 'get' | 'head' // GET and HEAD request must not have a body content.
-  ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody>
-  : keyof ValidationTargets
-
-export type ValidationFunction<
-  InputType,
-  OutputType,
-  E extends Env = {},
-  P extends string = string
-> = (
-  value: InputType,
-  c: Context<E, P>
-) => OutputType | Response | Promise<OutputType> | Promise<Response>
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type ExcludeResponseType<T> = T extends Response & TypedResponse<any> ? never : T
-
-export const validator = <
-  InputType,
-  P extends string,
-  M extends string,
-  U extends ValidationTargetByMethod<M>,
-  OutputType = ValidationTargets[U],
-  OutputTypeExcludeResponseType = ExcludeResponseType<OutputType>,
-  P2 extends string = P,
-  V extends {
-    in: {
-      [K in U]: K extends 'json'
-        ? unknown extends InputType
-          ? OutputTypeExcludeResponseType
-          : InputType
-        : { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
-    }
-    out: { [K in U]: OutputTypeExcludeResponseType }
-  } = {
-    in: {
-      [K in U]: K extends 'json'
-        ? unknown extends InputType
-          ? OutputTypeExcludeResponseType
-          : InputType
-        : { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
-    }
-    out: { [K in U]: OutputTypeExcludeResponseType }
-  },
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  E extends Env = any
->(
-  target: U,
-  validationFunc: ValidationFunction<
-    unknown extends InputType ? ValidationTargets[U] : InputType,
-    OutputType,
-    E,
-    P2
-  >
-): MiddlewareHandler<E, P, V> => {
-  return async (c, next) => {
-    let value = {}
-    const contentType = c.req.header('Content-Type')
-
-    switch (target) {
-      case 'json':
-        if (!contentType || !/^application\/([a-z-]+\+)?json/.test(contentType)) {
-          const message = `Invalid HTTP header: Content-Type=${contentType}`
-          throw new HTTPException(400, { message })
-        }
-        try {
-          value = await c.req.json()
-        } catch {
-          const message = 'Malformed JSON in request body'
-          throw new HTTPException(400, { message })
-        }
-        break
-      case 'form': {
-        if (!contentType) {
-          break
-        }
-
-        if (c.req.bodyCache.formData) {
-          value = await c.req.bodyCache.formData
-          break
-        }
-
-        try {
-          const arrayBuffer = await c.req.arrayBuffer()
-          const formData = await bufferToFormData(arrayBuffer, contentType)
-          const form: BodyData<{ all: true }> = {}
-          formData.forEach((value, key) => {
-            if (key.endsWith('[]')) {
-              if (form[key] === undefined) {
-                form[key] = [value]
-              } else if (Array.isArray(form[key])) {
-                ;(form[key] as unknown[]).push(value)
-              }
-            } else {
-              form[key] = value
-            }
-          })
-          value = form
-          c.req.bodyCache.formData = formData
-        } catch (e) {
-          let message = 'Malformed FormData request.'
-          message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`
-          throw new HTTPException(400, { message })
-        }
-        break
-      }
-      case 'query':
-        value = Object.fromEntries(
-          Object.entries(c.req.queries()).map(([k, v]) => {
-            return v.length === 1 ? [k, v[0]] : [k, v]
-          })
-        )
-        break
-      case 'param':
-        value = c.req.param() as Record<string, string>
-        break
-      case 'header':
-        value = c.req.header()
-        break
-      case 'cookie':
-        value = getCookie(c)
-        break
-    }
-
-    const res = await validationFunc(value as never, c as never)
-
-    if (res instanceof Response) {
-      return res
-    }
-
-    c.req.addValidatedData(target, res as never)
-
-    await next()
-  }
-}
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index b50c6e0b9..fdd3c33d6 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -36,7 +36,7 @@ yarn install --frozen-lockfile
 
 ## PRs
 
-Please ensure your PR passes tests with `bun run test` or `yarn test`. Also please ensure the Deno code is generated with `yarn denoify`.
+Please ensure your PR passes tests with `bun run test` or `yarn test`.
 
 ## Third-party middleware
 
@@ -59,4 +59,4 @@ If you want to do it, create the issue about your middleware.
 git clone git@github.com:honojs/hono.git && cd hono/.devcontainer && yarn install --frozen-lockfile
 docker compose up -d --build
 docker compose exec hono bash
-```
\ No newline at end of file
+```
diff --git a/jsr.json b/jsr.json
new file mode 100644
index 000000000..418ef1a0d
--- /dev/null
+++ b/jsr.json
@@ -0,0 +1,103 @@
+{
+  "name": "@hono/hono",
+  "version": "0.0.0",
+  "compilerOptions": {
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "deno.ns"
+    ]
+  },
+  "unstable": [
+    "sloppy-imports"
+  ],
+  "exports": {
+    ".": "./src/index.ts",
+    "./types": "./src/types.ts",
+    "./hono-base": "./src/hono-base.ts",
+    "./tiny": "./src/preset/tiny.ts",
+    "./quick": "./src/preset/quick.ts",
+    "./http-exception": "./src/http-exception.ts",
+    "./basic-auth": "./src/middleware/basic-auth/index.ts",
+    "./bearer-auth": "./src/middleware/bearer-auth/index.ts",
+    "./body-limit": "./src/middleware/body-limit/index.ts",
+    "./cache": "./src/middleware/cache/index.ts",
+    "./cookie": "./src/helper/cookie/index.ts",
+    "./accepts": "./src/helper/accepts/index.ts",
+    "./compress": "./src/middleware/compress/index.ts",
+    "./cors": "./src/middleware/cors/index.ts",
+    "./csrf": "./src/middleware/csrf/index.ts",
+    "./etag": "./src/middleware/etag/index.ts",
+    "./trailing-slash": "./src/middleware/trailing-slash/index.ts",
+    "./html": "./src/helper/html/index.ts",
+    "./css": "./src/helper/css/index.ts",
+    "./jsx": "./src/jsx/index.ts",
+    "./jsx/jsx-dev-runtime": "./src/jsx/jsx-dev-runtime.ts",
+    "./jsx/jsx-runtime": "./src/jsx/jsx-runtime.ts",
+    "./jsx/streaming": "./src/jsx/streaming.ts",
+    "./jsx-renderer": "./src/middleware/jsx-renderer/index.ts",
+    "./jsx/dom": "./src/jsx/dom/index.ts",
+    "./jsx/dom/jsx-dev-runtime": "./src/jsx/dom/jsx-dev-runtime.ts",
+    "./jsx/dom/jsx-runtime": "./src/jsx/dom/jsx-runtime.ts",
+    "./jsx/dom/css": "./src/jsx/dom/css.ts",
+    "./jwt": "./src/middleware/jwt/jwt.ts",
+    "./timing": "./src/middleware/timing/timing.ts",
+    "./logger": "./src/middleware/logger/index.ts",
+    "./method-override": "./src/middleware/method-override/index.ts",
+    "./powered-by": "./src/middleware/powered-by/index.ts",
+    "./pretty-json": "./src/middleware/pretty-json/index.ts",
+    "./secure-headers": "./src/middleware/secure-headers/secure-headers.ts",
+    "./ssg": "./src/helper/ssg/index.ts",
+    "./streaming": "./src/helper/streaming/index.ts",
+    "./validator": "./src/validator/index.ts",
+    "./router": "./src/router.ts",
+    "./router/reg-exp-router": "./src/router/reg-exp-router/index.ts",
+    "./router/smart-router": "./src/router/smart-router/index.ts",
+    "./router/trie-router": "./src/router/trie-router/index.ts",
+    "./router/pattern-router": "./src/router/pattern-router/index.ts",
+    "./router/linear-router": "./src/router/linear-router/index.ts",
+    "./client": "./src/client/index.ts",
+    "./adapter": "./src/helper/adapter/index.ts",
+    "./factory": "./src/helper/factory/index.ts",
+    "./serve-static": "./src/middleware/serve-static/index.ts",
+    "./cloudflare-workers": "./src/adapter/cloudflare-workers/index.ts",
+    "./cloudflare-pages": "./src/adapter/cloudflare-pages/index.ts",
+    "./deno": "./src/adapter/deno/index.ts",
+    "./bun": "./src/adapter/bun/index.ts",
+    "./aws-lambda": "./src/adapter/aws-lambda/index.ts",
+    "./vercel": "./src/adapter/vercel/index.ts",
+    "./netlify": "./src/adapter/netlify/index.ts",
+    "./lambda-edge": "./src/adapter/lambda-edge/index.ts",
+    "./testing": "./src/helper/testing/index.ts",
+    "./dev": "./src/helper/dev/index.ts",
+    "./ws": "./src/helper/websocket/index.ts",
+    "./utils/body": "./src/utils/body.ts",
+    "./utils/buffer": "./src/utils/buffer.ts",
+    "./utils/color": "./src/utils/color.ts",
+    "./utils/concurrent": "./src/utils/concurrent.ts",
+    "./utils/cookie": "./src/utils/cookie.ts",
+    "./utils/crypto": "./src/utils/crypto.ts",
+    "./utils/encode": "./src/utils/encode.ts",
+    "./utils/filepath": "./src/utils/filepath.ts",
+    "./utils/handler": "./src/utils/handler.ts",
+    "./utils/html": "./src/utils/html.ts",
+    "./utils/http-status": "./src/utils/http-status.ts",
+    "./utils/jwt": "./src/utils/jwt/index.ts",
+    "./utils/mime": "./src/utils/mime.ts",
+    "./utils/stream": "./src/utils/stream.ts",
+    "./utils/types": "./src/utils/types.ts",
+    "./utils/url": "./src/utils/url.ts"
+  },
+  "publish": {
+    "include": [
+      "jsr.json",
+      "LICENSE",
+      "README.md",
+      "src/**/*.ts"
+    ],
+    "exclude": [
+      "src/**/*.test.ts",
+      "src/**/*.test.tsx"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 1b3548855..17a355261 100644
--- a/package.json
+++ b/package.json
@@ -24,13 +24,12 @@
     "lint:fix": "eslint --ext js,ts,tsx src runtime_tests --fix",
     "format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime_tests/**/*.{js,ts,tsx}\"",
     "format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime_tests/**/*.{js,ts,tsx}\"",
-    "denoify": "rimraf deno_dist && denoify && rimraf \"deno_dist/**/*.test.{ts,tsx}\"",
     "copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json ",
     "build": "rimraf dist && tsx ./build.ts && bun run copy:package.cjs.json",
     "postbuild": "publint",
     "watch": "rimraf dist && tsx ./build.ts --watch && bun run copy:package.cjs.json",
     "coverage": "vitest --run --coverage",
-    "prerelease": "bun denoify && bun test:deno && bun run build",
+    "prerelease": "bun test:deno && bun run build",
     "release": "np"
   },
   "exports": {
@@ -572,7 +571,6 @@
     "@vitest/coverage-v8": "^1.1.0",
     "arg": "^5.0.2",
     "crypto-js": "^4.1.1",
-    "denoify": "^1.6.6",
     "esbuild": "^0.15.12",
     "eslint": "^8.55.0",
     "glob": "7.2.3",
@@ -593,4 +591,4 @@
   "engines": {
     "node": ">=16.0.0"
   }
-}
+}
\ No newline at end of file
diff --git a/runtime_tests/deno-jsx/deno.precompile.json b/runtime_tests/deno-jsx/deno.precompile.json
index 0ce541ca9..31f0aec64 100644
--- a/runtime_tests/deno-jsx/deno.precompile.json
+++ b/runtime_tests/deno-jsx/deno.precompile.json
@@ -2,10 +2,16 @@
   "compilerOptions": {
     "jsx": "precompile",
     "jsxImportSource": "hono/jsx",
-    "lib": ["deno.ns", "dom"]
+    "lib": [
+      "deno.ns",
+      "dom"
+    ]
   },
+  "unstable": [
+    "sloppy-imports"
+  ],
   "imports": {
-    "hono/jsx/jsx-runtime": "../../deno_dist/jsx/jsx-runtime.ts",
-    "../../deno_dist/jsx/jsx-runtime": "../../deno_dist/jsx/jsx-runtime.ts"
+    "hono/jsx/jsx-runtime": "../../src/jsx/jsx-runtime.ts",
+    "../../deno_dist/jsx/jsx-runtime": "../../src/jsx/jsx-runtime.ts"
   }
-}
+}
\ No newline at end of file
diff --git a/runtime_tests/deno-jsx/deno.react-jsx.json b/runtime_tests/deno-jsx/deno.react-jsx.json
index 50c4bdf2b..0e1fd1d35 100644
--- a/runtime_tests/deno-jsx/deno.react-jsx.json
+++ b/runtime_tests/deno-jsx/deno.react-jsx.json
@@ -2,10 +2,16 @@
   "compilerOptions": {
     "jsx": "react-jsx",
     "jsxImportSource": "hono/jsx",
-    "lib": ["deno.ns", "dom"]
+    "lib": [
+      "deno.ns",
+      "dom"
+    ]
   },
+  "unstable": [
+    "sloppy-imports"
+  ],
   "imports": {
-    "hono/jsx/jsx-runtime": "../../deno_dist/jsx/jsx-runtime.ts",
-    "../../deno_dist/jsx/jsx-runtime": "../../deno_dist/jsx/jsx-runtime.ts"
+    "hono/jsx/jsx-runtime": "../../src/jsx/jsx-runtime.ts",
+    "../../deno_dist/jsx/jsx-runtime": "../../src/jsx/jsx-runtime.ts"
   }
-}
+}
\ No newline at end of file
diff --git a/runtime_tests/deno-jsx/jsx.test.tsx b/runtime_tests/deno-jsx/jsx.test.tsx
index d54c27170..2bd506e4f 100644
--- a/runtime_tests/deno-jsx/jsx.test.tsx
+++ b/runtime_tests/deno-jsx/jsx.test.tsx
@@ -1,8 +1,8 @@
-/** @jsxImportSource ../../deno_dist/jsx */
-import { Style, css } from '../../deno_dist/helper/css/index.ts'
-import { Suspense, renderToReadableStream } from '../../deno_dist/jsx/streaming.ts'
-import type { HtmlEscapedString } from '../../deno_dist/utils/html.ts'
-import { resolveCallback, HtmlEscapedCallbackPhase } from '../../deno_dist/utils/html.ts'
+/** @jsxImportSource ../../src/jsx */
+import { Style, css } from '../../src/helper/css/index.ts'
+import { Suspense, renderToReadableStream } from '../../src/jsx/streaming.ts'
+import type { HtmlEscapedString } from '../../src/utils/html.ts'
+import { resolveCallback, HtmlEscapedCallbackPhase } from '../../src/utils/html.ts'
 import { assertEquals } from '../deno/deps.ts'
 
 Deno.test('JSX', () => {
diff --git a/runtime_tests/deno/deno.json b/runtime_tests/deno/deno.json
index c6de9c7e2..92e4f7722 100644
--- a/runtime_tests/deno/deno.json
+++ b/runtime_tests/deno/deno.json
@@ -1,5 +1,17 @@
 {
   "compilerOptions": {
-    "lib": ["deno.ns", "dom", "dom.iterable"]
+    "jsx": "react-jsx",
+    "jsxImportSource": "hono/jsx",
+    "lib": [
+      "deno.ns",
+      "dom",
+      "dom.iterable"
+    ]
+  },
+  "unstable": [
+    "sloppy-imports"
+  ],
+  "imports": {
+    "hono/jsx/jsx-runtime": "../../src/jsx/jsx-runtime.ts"
   }
 }
\ No newline at end of file
diff --git a/runtime_tests/deno/hono.test.ts b/runtime_tests/deno/hono.test.ts
index d9f9ffefa..2340de258 100644
--- a/runtime_tests/deno/hono.test.ts
+++ b/runtime_tests/deno/hono.test.ts
@@ -1,7 +1,7 @@
-import { Context } from '../../deno_dist/context.ts'
-import { env, getRuntimeKey } from '../../deno_dist/helper.ts'
-import { Hono } from '../../deno_dist/mod.ts'
-import { HonoRequest } from '../../deno_dist/request.ts'
+import { Context } from '../../src/context.ts'
+import { env, getRuntimeKey } from '../../src/helper/adapter/index.ts'
+import { Hono } from '../../src/hono.ts'
+import { HonoRequest } from '../../src/request.ts'
 import { assertEquals } from './deps.ts'
 
 // Test just only minimal patterns.
diff --git a/runtime_tests/deno/middleware.test.tsx b/runtime_tests/deno/middleware.test.tsx
index 7f05805cd..534160c54 100644
--- a/runtime_tests/deno/middleware.test.tsx
+++ b/runtime_tests/deno/middleware.test.tsx
@@ -1,8 +1,7 @@
-/** @jsx jsx */
-/** @jsxFrag Fragment */
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { basicAuth, jsx, Fragment, serveStatic, jwt } from '../../deno_dist/middleware.ts'
-import { Hono } from '../../deno_dist/mod.ts'
+import { serveStatic } from '../../src/adapter/deno/index.ts'
+import { Hono } from '../../src/hono.ts'
+import { basicAuth } from '../../src/middleware/basic-auth/index.ts'
+import { jwt } from '../../src/middleware/jwt/index.ts'
 import { assertEquals, assertMatch, assertSpyCall, assertSpyCalls, spy } from './deps.ts'
 
 // Test just only minimal patterns.
diff --git a/runtime_tests/deno/ssg.test.tsx b/runtime_tests/deno/ssg.test.tsx
index 6ea155a71..18d257332 100644
--- a/runtime_tests/deno/ssg.test.tsx
+++ b/runtime_tests/deno/ssg.test.tsx
@@ -1,10 +1,5 @@
-/** @jsx jsx */
-/** @jsxFrag Fragment */
-
-import { toSSG } from '../../deno_dist/helper.ts'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx } from '../../deno_dist/middleware.ts'
-import { Hono } from '../../deno_dist/mod.ts'
+import { toSSG } from '../../src/adapter/deno/ssg.ts'
+import { Hono } from '../../src/hono.ts'
 import { assertEquals } from '../deno/deps.ts'
 
 Deno.test('toSSG function', async () => {
diff --git a/src/adapter/aws-lambda/awslambda.d.ts b/src/adapter/aws-lambda/awslambda.d.ts
deleted file mode 100644
index 6ec758a4a..000000000
--- a/src/adapter/aws-lambda/awslambda.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// @denoify-ignore
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
-import type { LambdaContext, Handler } from './types'
-
-declare global {
-  namespace awslambda {
-    // Note: Anticipated logic for AWS
-    // https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/main/src/HttpResponseStream.js
-    export class HttpResponseStream {
-      static from(
-        underlyingStream: NodeJS.WritableStream,
-        prelude: Record<string, unknown>
-      ): NodeJS.WritableStream
-    }
-    function streamifyResponse(
-      f: (
-        event: any,
-        responseStream: NodeJS.WritableStream,
-        context: LambdaContext
-      ) => Promise<void>
-    ): Handler
-  }
-}
diff --git a/src/adapter/aws-lambda/custom-context.ts b/src/adapter/aws-lambda/custom-context.ts
index 789184cbe..b9dd48e26 100644
--- a/src/adapter/aws-lambda/custom-context.ts
+++ b/src/adapter/aws-lambda/custom-context.ts
@@ -1,5 +1,3 @@
-// @denoify-ignore
-
 interface ClientCert {
   clientCertPem: string
   subjectDN: string
diff --git a/src/adapter/aws-lambda/handler.ts b/src/adapter/aws-lambda/handler.ts
index 975956f0f..49cf1918a 100644
--- a/src/adapter/aws-lambda/handler.ts
+++ b/src/adapter/aws-lambda/handler.ts
@@ -1,15 +1,13 @@
-// @denoify-ignore
-import crypto from 'crypto'
+import crypto from 'node:crypto'
 import type { Hono } from '../../hono'
 import type { Env, Schema } from '../../types'
-
-import { encodeBase64 } from '../../utils/encode'
+import { decodeBase64, encodeBase64 } from '../../utils/encode'
 import type {
   ApiGatewayRequestContext,
   ApiGatewayRequestContextV2,
   ALBRequestContext,
 } from './custom-context'
-import type { LambdaContext } from './types'
+import type { Handler, LambdaContext } from './types'
 
 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 // @ts-ignore
@@ -112,7 +110,8 @@ export const streamHandle = <
   BasePath extends string = '/'
 >(
   app: Hono<E, S, BasePath>
-) => {
+): Handler => {
+  // @ts-expect-error awslambda is not a standard API
   return awslambda.streamifyResponse(
     async (event: LambdaEvent, responseStream: NodeJS.WritableStream, context: LambdaContext) => {
       const processor = getProcessor(event)
@@ -133,6 +132,7 @@ export const streamHandle = <
         }
 
         // Update response stream
+        // @ts-expect-error awslambda is not a standard API
         responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata)
 
         if (res.body) {
@@ -155,11 +155,8 @@ export const streamHandle = <
  */
 export const handle = <E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(
   app: Hono<E, S, BasePath>
-) => {
-  return async (
-    event: LambdaEvent,
-    lambdaContext?: LambdaContext
-  ): Promise<APIGatewayProxyResult> => {
+): ((event: LambdaEvent, lambdaContext?: LambdaContext) => Promise<APIGatewayProxyResult>) => {
+  return async (event, lambdaContext?) => {
     const processor = getProcessor(event)
 
     const req = processor.createRequest(event)
@@ -211,7 +208,7 @@ abstract class EventProcessor<E extends LambdaEvent> {
     }
 
     if (event.body) {
-      requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, 'base64') : event.body
+      requestInit.body = event.isBase64Encoded ? decodeBase64(event.body) : event.body
     }
 
     return new Request(url, requestInit)
@@ -258,7 +255,7 @@ abstract class EventProcessor<E extends LambdaEvent> {
   }
 }
 
-const v2Processor = new (class EventV2Processor extends EventProcessor<APIGatewayProxyEventV2> {
+class EventV2Processor extends EventProcessor<APIGatewayProxyEventV2> {
   protected getPath(event: APIGatewayProxyEventV2): string {
     return event.rawPath
   }
@@ -297,11 +294,11 @@ const v2Processor = new (class EventV2Processor extends EventProcessor<APIGatewa
     }
     return headers
   }
-})()
+}
+
+const v2Processor: EventV2Processor = new EventV2Processor()
 
-const v1Processor = new (class EventV1Processor extends EventProcessor<
-  Exclude<LambdaEvent, APIGatewayProxyEventV2>
-> {
+class EventV1Processor extends EventProcessor<Exclude<LambdaEvent, APIGatewayProxyEventV2>> {
   protected getPath(event: Exclude<LambdaEvent, APIGatewayProxyEventV2>): string {
     return event.path
   }
@@ -357,9 +354,11 @@ const v1Processor = new (class EventV1Processor extends EventProcessor<
       'set-cookie': cookies,
     }
   }
-})()
+}
+
+const v1Processor: EventV1Processor = new EventV1Processor()
 
-const albProcessor = new (class ALBProcessor extends EventProcessor<ALBProxyEvent> {
+class ALBProcessor extends EventProcessor<ALBProxyEvent> {
   protected getHeaders(event: ALBProxyEvent): Headers {
     const headers = new Headers()
     // if multiValueHeaders is present the ALB will use it instead of the headers field
@@ -448,7 +447,9 @@ const albProcessor = new (class ALBProcessor extends EventProcessor<ALBProxyEven
       result.headers['set-cookie'] = cookies.join(', ')
     }
   }
-})()
+}
+
+const albProcessor: ALBProcessor = new ALBProcessor()
 
 export const getProcessor = (event: LambdaEvent): EventProcessor<LambdaEvent> => {
   if (isProxyEventALB(event)) {
diff --git a/src/adapter/aws-lambda/index.ts b/src/adapter/aws-lambda/index.ts
index 0c7266714..62c7a2e24 100644
--- a/src/adapter/aws-lambda/index.ts
+++ b/src/adapter/aws-lambda/index.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 export { handle, streamHandle } from './handler'
 export type { APIGatewayProxyResult, LambdaEvent } from './handler'
 export type {
diff --git a/src/adapter/aws-lambda/types.ts b/src/adapter/aws-lambda/types.ts
index 76fbd0a2b..d1054a7e0 100644
--- a/src/adapter/aws-lambda/types.ts
+++ b/src/adapter/aws-lambda/types.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 /* eslint-disable @typescript-eslint/no-explicit-any */
 
 export interface CognitoIdentity {
diff --git a/src/adapter/bun/conninfo.ts b/src/adapter/bun/conninfo.ts
index 23d04c06a..b6c031578 100644
--- a/src/adapter/bun/conninfo.ts
+++ b/src/adapter/bun/conninfo.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import type { Context } from '../..'
 import type { GetConnInfo } from '../../helper/conninfo'
 
diff --git a/src/adapter/bun/index.ts b/src/adapter/bun/index.ts
index a7109ec63..1fc6a1946 100644
--- a/src/adapter/bun/index.ts
+++ b/src/adapter/bun/index.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 export { serveStatic } from './serve-static'
 export { bunFileSystemModule, toSSG } from './ssg'
 export { createBunWebSocket } from './websocket'
diff --git a/src/adapter/bun/serve-static.ts b/src/adapter/bun/serve-static.ts
index 4b95f6fde..768dffef8 100644
--- a/src/adapter/bun/serve-static.ts
+++ b/src/adapter/bun/serve-static.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 /* eslint-disable @typescript-eslint/ban-ts-comment */
 import { serveStatic as baseServeStatic } from '../../middleware/serve-static'
 import type { ServeStaticOptions } from '../../middleware/serve-static'
diff --git a/src/adapter/bun/ssg.ts b/src/adapter/bun/ssg.ts
index 2694cd961..f20f1b0cd 100644
--- a/src/adapter/bun/ssg.ts
+++ b/src/adapter/bun/ssg.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 /* eslint-disable @typescript-eslint/ban-ts-comment */
 import { toSSG as baseToSSG } from '../../helper/ssg'
 import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg'
diff --git a/src/adapter/bun/websocket.ts b/src/adapter/bun/websocket.ts
index 003f06c35..063d995fd 100644
--- a/src/adapter/bun/websocket.ts
+++ b/src/adapter/bun/websocket.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import {
   createWSMessageEvent,
   type UpgradeWebSocket,
@@ -24,7 +23,7 @@ interface BunServer {
 interface BunWebSocketHandler<T> {
   open(ws: BunServerWebSocket<T>): void
   close(ws: BunServerWebSocket<T>, code?: number, reason?: string): void
-  message(ws: BunServerWebSocket<T>, message: string | Buffer): void
+  message(ws: BunServerWebSocket<T>, message: string | Uint8Array): void
 }
 interface CreateWebSocket {
   (): {
diff --git a/src/adapter/cloudflare-pages/handler.ts b/src/adapter/cloudflare-pages/handler.ts
index 3d6fe1124..7e3f25e1e 100644
--- a/src/adapter/cloudflare-pages/handler.ts
+++ b/src/adapter/cloudflare-pages/handler.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import type { Hono } from '../../hono'
 import type { MiddlewareHandler } from '../../types'
 
diff --git a/src/adapter/cloudflare-pages/index.ts b/src/adapter/cloudflare-pages/index.ts
index 8515498f7..72daa24c1 100644
--- a/src/adapter/cloudflare-pages/index.ts
+++ b/src/adapter/cloudflare-pages/index.ts
@@ -1,3 +1,2 @@
-// @denoify-ignore
 export { handle, serveStatic } from './handler'
 export type { EventContext } from './handler'
diff --git a/src/adapter/cloudflare-workers/conninfo.ts b/src/adapter/cloudflare-workers/conninfo.ts
index 7ca7ce5a8..53d234a19 100644
--- a/src/adapter/cloudflare-workers/conninfo.ts
+++ b/src/adapter/cloudflare-workers/conninfo.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import type { GetConnInfo } from '../../helper/conninfo'
 
 export const getConnInfo: GetConnInfo = (c) => ({
diff --git a/src/adapter/cloudflare-workers/index.ts b/src/adapter/cloudflare-workers/index.ts
index 78072f589..fa15c483c 100644
--- a/src/adapter/cloudflare-workers/index.ts
+++ b/src/adapter/cloudflare-workers/index.ts
@@ -1,3 +1,2 @@
-// @denoify-ignore
 export { serveStatic } from './serve-static-module'
 export { upgradeWebSocket } from './websocket'
diff --git a/src/adapter/cloudflare-workers/serve-static-module.ts b/src/adapter/cloudflare-workers/serve-static-module.ts
index 0625909d4..bbd8c01e6 100644
--- a/src/adapter/cloudflare-workers/serve-static-module.ts
+++ b/src/adapter/cloudflare-workers/serve-static-module.ts
@@ -1,10 +1,11 @@
-// @denoify-ignore
 // For ES module mode
-import type { Env } from '../../types'
+import type { Env, MiddlewareHandler } from '../../types'
 import type { ServeStaticOptions } from './serve-static'
 import { serveStatic } from './serve-static'
 
-const module = <E extends Env = Env>(options: Omit<ServeStaticOptions<E>, 'namespace'>) => {
+const module = <E extends Env = Env>(
+  options: Omit<ServeStaticOptions<E>, 'namespace'>
+): MiddlewareHandler => {
   return serveStatic<E>(options)
 }
 
diff --git a/src/adapter/cloudflare-workers/serve-static.ts b/src/adapter/cloudflare-workers/serve-static.ts
index 7e7381d2b..b2f4954e7 100644
--- a/src/adapter/cloudflare-workers/serve-static.ts
+++ b/src/adapter/cloudflare-workers/serve-static.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import { serveStatic as baseServeStatic } from '../../middleware/serve-static'
 import type { ServeStaticOptions as BaseServeStaticOptions } from '../../middleware/serve-static'
 import type { Env, MiddlewareHandler } from '../../types'
diff --git a/src/adapter/cloudflare-workers/utils.ts b/src/adapter/cloudflare-workers/utils.ts
index b7b8c5be0..af7cf92a6 100644
--- a/src/adapter/cloudflare-workers/utils.ts
+++ b/src/adapter/cloudflare-workers/utils.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 // __STATIC_CONTENT is KVNamespace
 declare const __STATIC_CONTENT: unknown
 declare const __STATIC_CONTENT_MANIFEST: string
diff --git a/src/adapter/cloudflare-workers/websocket.ts b/src/adapter/cloudflare-workers/websocket.ts
index 8c0765390..39a14dab7 100644
--- a/src/adapter/cloudflare-workers/websocket.ts
+++ b/src/adapter/cloudflare-workers/websocket.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import type { UpgradeWebSocket, WSContext, WSReadyState } from '../../helper/websocket'
 
 // Based on https://github.com/honojs/hono/issues/1153#issuecomment-1767321332
@@ -53,7 +52,7 @@ export const upgradeWebSocket: UpgradeWebSocket = (createEvents) => async (c, ne
   server.accept()
   return new Response(null, {
     status: 101,
-    // @ts-expect-error Cloudflare Workers API
+    // @ts-expect-error type not typed
     webSocket: client,
   })
 }
diff --git a/src/adapter/lambda-edge/handler.test.ts b/src/adapter/lambda-edge/handler.test.ts
index ace1c0342..aa17c904a 100644
--- a/src/adapter/lambda-edge/handler.test.ts
+++ b/src/adapter/lambda-edge/handler.test.ts
@@ -1,3 +1,4 @@
+import { encodeBase64 } from '../../utils/encode'
 import { createBody, isContentTypeBinary } from './handler'
 
 describe('isContentTypeBinary', () => {
@@ -18,10 +19,11 @@ describe('isContentTypeBinary', () => {
 
 describe('createBody', () => {
   it('Should the request be a GET or HEAD, the Request must not include a Body', () => {
-    const data = Buffer.from('test')
+    const encoder = new TextEncoder()
+    const data = encoder.encode('test')
     const body = {
       action: 'read-only',
-      data: data.toString('base64'),
+      data: encodeBase64(data),
       encoding: 'base64',
       inputTruncated: false,
     }
diff --git a/src/adapter/lambda-edge/handler.ts b/src/adapter/lambda-edge/handler.ts
index dff79c732..12e58ccdf 100644
--- a/src/adapter/lambda-edge/handler.ts
+++ b/src/adapter/lambda-edge/handler.ts
@@ -1,8 +1,7 @@
-// @denoify-ignore
-import crypto from 'crypto'
+import crypto from 'node:crypto'
 import type { Hono } from '../../hono'
 
-import { encodeBase64 } from '../../utils/encode'
+import { decodeBase64, encodeBase64 } from '../../utils/encode'
 
 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 // @ts-ignore
@@ -111,13 +110,15 @@ const convertHeaders = (headers: Headers): CloudFrontHeaders => {
   return cfHeaders
 }
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const handle = (app: Hono<any>) => {
-  return async (
-    event: CloudFrontEdgeEvent,
-    context?: CloudFrontContext,
-    callback?: Callback
-  ): Promise<CloudFrontResult> => {
+export const handle = (
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  app: Hono<any>
+): ((
+  event: CloudFrontEdgeEvent,
+  context?: CloudFrontContext,
+  callback?: Callback
+) => Promise<CloudFrontResult>) => {
+  return async (event, context?, callback?) => {
     const res = await app.fetch(createRequest(event), {
       event,
       context,
@@ -144,7 +145,7 @@ const createResult = async (res: Response): Promise<CloudFrontResult> => {
   }
 }
 
-const createRequest = (event: CloudFrontEdgeEvent) => {
+const createRequest = (event: CloudFrontEdgeEvent): Request => {
   const queryString = event.Records[0].cf.request.querystring
   const urlPath = `https://${event.Records[0].cf.config.distributionDomainName}${event.Records[0].cf.request.uri}`
   const url = queryString ? `${urlPath}?${queryString}` : urlPath
@@ -165,7 +166,10 @@ const createRequest = (event: CloudFrontEdgeEvent) => {
   })
 }
 
-export const createBody = (method: string, requestBody: CloudFrontRequest['body']) => {
+export const createBody = (
+  method: string,
+  requestBody: CloudFrontRequest['body']
+): string | Uint8Array | undefined => {
   if (!requestBody || !requestBody.data) {
     return undefined
   }
@@ -173,12 +177,12 @@ export const createBody = (method: string, requestBody: CloudFrontRequest['body'
     return undefined
   }
   if (requestBody.encoding === 'base64') {
-    return Buffer.from(requestBody.data, 'base64')
+    return decodeBase64(requestBody.data)
   }
   return requestBody.data
 }
 
-export const isContentTypeBinary = (contentType: string) => {
+export const isContentTypeBinary = (contentType: string): boolean => {
   return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml.*)$/.test(
     contentType
   )
diff --git a/src/adapter/lambda-edge/index.ts b/src/adapter/lambda-edge/index.ts
index 1ff371d05..bd0b6943e 100644
--- a/src/adapter/lambda-edge/index.ts
+++ b/src/adapter/lambda-edge/index.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 export { handle } from './handler'
 export type {
   Callback,
diff --git a/src/adapter/netlify/handler.ts b/src/adapter/netlify/handler.ts
index ba9b2b396..a69eb5d37 100644
--- a/src/adapter/netlify/handler.ts
+++ b/src/adapter/netlify/handler.ts
@@ -1,17 +1,10 @@
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import type { Context } from 'https://edge.netlify.com/'
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import type { Hono } from '../../hono'
 
-export type Env = {
-  Bindings: {
-    context: Context
-  }
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const handle = (app: Hono<any, any>) => {
-  return (req: Request, context: Context) => {
+export const handle = (
+  app: Hono<any, any>
+): ((req: Request, context: any) => Response | Promise<Response>) => {
+  return (req: Request, context: any) => {
     return app.fetch(req, { context })
   }
 }
diff --git a/src/adapter/netlify/mod.ts b/src/adapter/netlify/mod.ts
index d171345a9..015118284 100644
--- a/src/adapter/netlify/mod.ts
+++ b/src/adapter/netlify/mod.ts
@@ -1,2 +1 @@
 export { handle } from './handler'
-export type { Env } from './handler'
diff --git a/src/adapter/vercel/handler.ts b/src/adapter/vercel/handler.ts
index 3f931e058..26f70e03f 100644
--- a/src/adapter/vercel/handler.ts
+++ b/src/adapter/vercel/handler.ts
@@ -1,9 +1,9 @@
-// @denoify-ignore
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import type { Hono } from '../../hono'
 import type { FetchEventLike } from '../../types'
 
 export const handle =
-  (app: Hono<any, any, any>) => (req: Request, requestContext: FetchEventLike) => {
+  (app: Hono<any, any, any>) =>
+  (req: Request, requestContext: FetchEventLike): Response | Promise<Response> => {
     return app.fetch(req, {}, requestContext as any)
   }
diff --git a/src/adapter/vercel/index.ts b/src/adapter/vercel/index.ts
index fe303c423..015118284 100644
--- a/src/adapter/vercel/index.ts
+++ b/src/adapter/vercel/index.ts
@@ -1,2 +1 @@
-// @denoify-ignore
 export { handle } from './handler'
diff --git a/src/client/client.test.ts b/src/client/client.test.ts
index bb00264d4..8f0003711 100644
--- a/src/client/client.test.ts
+++ b/src/client/client.test.ts
@@ -4,7 +4,7 @@
 import { rest } from 'msw'
 import { setupServer } from 'msw/node'
 import { expectTypeOf, vi } from 'vitest'
-import { upgradeWebSocket } from '../helper'
+import { upgradeWebSocket } from '../adapter/deno/websocket'
 import { Hono } from '../hono'
 import { parse } from '../utils/cookie'
 import type { Equal, Expect } from '../utils/types'
diff --git a/src/client/types.test.ts b/src/client/types.test.ts
index c1c73d36f..13904f0ae 100644
--- a/src/client/types.test.ts
+++ b/src/client/types.test.ts
@@ -1,6 +1,6 @@
 import { expectTypeOf } from 'vitest'
 import { Hono } from '..'
-import { upgradeWebSocket } from '../helper'
+import { upgradeWebSocket } from '../adapter/deno/websocket'
 import { hc } from '.'
 
 describe('WebSockets', () => {
diff --git a/src/context.test.ts b/src/context.test.ts
index 827247f5c..7f8619121 100644
--- a/src/context.test.ts
+++ b/src/context.test.ts
@@ -1,5 +1,5 @@
 import { Context } from './context'
-import { setCookie } from './helper'
+import { setCookie } from './helper/cookie'
 import { HonoRequest } from './request'
 
 describe('Context', () => {
diff --git a/src/helper.ts b/src/helper.ts
deleted file mode 100644
index a65b57e77..000000000
--- a/src/helper.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file is for Deno to import helpers from `hono/helper.ts`.
-export * from './helper/accepts'
-export * from './helper/adapter'
-export * from './helper/cookie'
-export * from './helper/css'
-export * from './helper/factory'
-export * from './helper/html'
-export * from './helper/streaming'
-export * from './helper/testing'
-export * from './helper/dev'
-export * from './adapter/deno/ssg'
-export * from './adapter/deno/websocket'
-export { decode as jwtDecode, sign as jwtSign, verify as jwtVerify } from './middleware/jwt'
diff --git a/src/helper/css/common.case.test.tsx b/src/helper/css/common.case.test.tsx
index 85b8a09ce..2a9046e7e 100644
--- a/src/helper/css/common.case.test.tsx
+++ b/src/helper/css/common.case.test.tsx
@@ -1,6 +1,5 @@
 /* eslint-disable quotes */
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment } from '../../jsx'
+/** @jsxImportSource ../../jsx */
 import type {
   css as cssHelper,
   keyframes as keyframesHelper,
diff --git a/src/helper/css/index.test.tsx b/src/helper/css/index.test.tsx
index 6cacdbbe1..abb9c0554 100644
--- a/src/helper/css/index.test.tsx
+++ b/src/helper/css/index.test.tsx
@@ -1,8 +1,8 @@
 /* eslint-disable quotes */
+/** @jsxImportSource ../../jsx */
 import { Hono } from '../../'
 import { html } from '../../helper/html'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment, isValidElement } from '../../jsx'
+import { isValidElement } from '../../jsx'
 import type { JSXNode } from '../../jsx'
 import { Suspense, renderToReadableStream } from '../../jsx/streaming'
 import type { HtmlEscapedString } from '../../utils/html'
diff --git a/src/helper/ssg/ssg.test.tsx b/src/helper/ssg/ssg.test.tsx
index cceeacc86..501d2f9c2 100644
--- a/src/helper/ssg/ssg.test.tsx
+++ b/src/helper/ssg/ssg.test.tsx
@@ -1,8 +1,7 @@
 /* eslint-disable @typescript-eslint/unbound-method */
+/** @jsxImportSource ../../jsx */
 import { beforeEach, describe, expect, it } from 'vitest'
 import { Hono } from '../../hono'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx } from '../../jsx'
 import { poweredBy } from '../../middleware/powered-by'
 import {
   X_HONO_DISABLE_SSG_HEADER_KEY,
diff --git a/src/helper/ssg/ssg.ts b/src/helper/ssg/ssg.ts
index 4d1b622c6..aa98d9c82 100644
--- a/src/helper/ssg/ssg.ts
+++ b/src/helper/ssg/ssg.ts
@@ -43,7 +43,7 @@ const generateFilePath = (
   outDir: string,
   mimeType: string,
   extensionMap?: Record<string, string>
-) => {
+): string => {
   const extension = determineExtension(mimeType, extensionMap)
 
   if (routePath.endsWith(`.${extension}`)) {
diff --git a/src/helper/ssg/utils.ts b/src/helper/ssg/utils.ts
index 39da9bd35..227204b26 100644
--- a/src/helper/ssg/utils.ts
+++ b/src/helper/ssg/utils.ts
@@ -8,16 +8,16 @@ import { findTargetHandler, isMiddleware } from '../../utils/handler'
  * @param path File Path
  * @returns Parent dir path
  */
-export const dirname = (path: string) => {
+export const dirname = (path: string): string => {
   const splittedPath = path.split(/[\/\\]/)
   return splittedPath.slice(0, -1).join('/') // Windows supports slash path
 }
 
-const normalizePath = (path: string) => {
+const normalizePath = (path: string): string => {
   return path.replace(/(\\)/g, '/').replace(/\/$/g, '')
 }
 
-const handleDotDot = (resultPaths: string[]) => {
+const handleDotDot = (resultPaths: string[]): void => {
   if (resultPaths.length === 0) {
     resultPaths.push('..')
   } else {
@@ -25,14 +25,14 @@ const handleDotDot = (resultPaths: string[]) => {
   }
 }
 
-const handleNonDot = (path: string, resultPaths: string[]) => {
+const handleNonDot = (path: string, resultPaths: string[]): void => {
   path = path.replace(/^\.(?!.)/, '')
   if (path !== '') {
     resultPaths.push(path)
   }
 }
 
-const handleSegments = (paths: string[], resultPaths: string[]) => {
+const handleSegments = (paths: string[], resultPaths: string[]): void => {
   for (const path of paths) {
     // Handle `..` or `../`
     if (path === '..') {
@@ -44,7 +44,7 @@ const handleSegments = (paths: string[], resultPaths: string[]) => {
   }
 }
 
-export const joinPaths = (...paths: string[]) => {
+export const joinPaths = (...paths: string[]): string => {
   paths = paths.map(normalizePath)
   const resultPaths: string[] = []
   handleSegments(paths.join('/').split('/'), resultPaths)
diff --git a/src/helper/streaming/text.ts b/src/helper/streaming/text.ts
index 8ff8e3df1..fe707cc67 100644
--- a/src/helper/streaming/text.ts
+++ b/src/helper/streaming/text.ts
@@ -1,7 +1,7 @@
 import type { Context } from '../../context'
 import { TEXT_PLAIN } from '../../context'
 import type { StreamingApi } from '../../utils/stream'
-import { stream } from '.'
+import { stream } from './'
 
 export const streamText = (
   c: Context,
diff --git a/src/hono-base.ts b/src/hono-base.ts
index 293d3874f..1b81d1ec4 100644
--- a/src/hono-base.ts
+++ b/src/hono-base.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import { compose } from './compose'
 import { Context } from './context'
 import type { ExecutionContext } from './context'
@@ -25,20 +26,6 @@ import { getPath, getPathNoStrict, getQueryStrings, mergePath } from './utils/ur
 
 export const COMPOSED_HANDLER = Symbol('composedHandler')
 
-type Methods = (typeof METHODS)[number] | typeof METHOD_NAME_ALL_LOWERCASE
-
-function defineDynamicClass(): {
-  new <E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(): {
-    [M in Methods]: HandlerInterface<E, M, S, BasePath>
-  } & {
-    on: OnHandlerInterface<E, S, BasePath>
-  } & {
-    use: MiddlewareHandlerInterface<E, S, BasePath>
-  }
-} {
-  return class {} as never
-}
-
 const notFoundHandler = (c: Context) => {
   return c.text('404 Not Found', 404)
 }
@@ -89,11 +76,18 @@ export type HonoOptions<E extends Env> = {
   getPath?: GetPath<E>
 }
 
-class Hono<
-  E extends Env = Env,
-  S extends Schema = {},
-  BasePath extends string = '/'
-> extends defineDynamicClass()<E, S, BasePath> {
+class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
+  // Theses methods are dynamically initialized in the constructor.
+  get!: HandlerInterface<E, 'get', S, BasePath>
+  post!: HandlerInterface<E, 'post', S, BasePath>
+  put!: HandlerInterface<E, 'put', S, BasePath>
+  delete!: HandlerInterface<E, 'delete', S, BasePath>
+  options!: HandlerInterface<E, 'options', S, BasePath>
+  patch!: HandlerInterface<E, 'patch', S, BasePath>
+  all!: HandlerInterface<E, 'all', S, BasePath>
+  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.
@@ -107,8 +101,6 @@ class Hono<
   routes: RouterRoute[] = []
 
   constructor(options: HonoOptions<E> = {}) {
-    super()
-
     // Implementation of app.get(...handlers[]) or app.get(path, ...handlers[])
     const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]
     allMethods.forEach((method) => {
@@ -123,7 +115,6 @@ class Hono<
             this.addRoute(method, this.#path, handler)
           }
         })
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         return this as any
       }
     })
@@ -141,12 +132,10 @@ class Hono<
           })
         }
       }
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
       return this as any
     }
 
     // Implementation of app.use(...handlers[]) or app.use(path, ...handlers[])
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     this.use = (arg1: string | MiddlewareHandler<any>, ...handlers: MiddlewareHandler<any>[]) => {
       if (typeof arg1 === 'string') {
         this.#path = arg1
@@ -157,7 +146,6 @@ class Hono<
       handlers.forEach((handler) => {
         this.addRoute(METHOD_NAME_ALL, this.#path, handler)
       })
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
       return this as any
     }
 
@@ -201,7 +189,6 @@ class Hono<
       } else {
         handler = async (c: Context, next: Next) =>
           (await compose<Context>([], app.errorHandler)(c, () => r.handler(c, next))).res
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         ;(handler as any)[COMPOSED_HANDLER] = r.handler
       }
 
@@ -254,7 +241,6 @@ class Hono<
 
   mount(
     path: string,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>,
     optionHandler?: (c: Context) => unknown
   ): Hono<E, S, BasePath> {
@@ -417,7 +403,8 @@ class Hono<
    * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
    */
   fire = () => {
-    // @ts-expect-error `event` is not the type expected by addEventListener
+    // 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))
     })
diff --git a/src/hono.test.ts b/src/hono.test.ts
index 89607d2aa..ca7ff7513 100644
--- a/src/hono.test.ts
+++ b/src/hono.test.ts
@@ -2,13 +2,13 @@
 /* eslint-disable @typescript-eslint/ban-ts-comment */
 import { expectTypeOf } from 'vitest'
 import { hc } from './client'
-import type { Context } from './context'
+import type { Context, ExecutionContext } from './context'
 import { Hono } from './hono'
 import { HTTPException } from './http-exception'
 import { logger } from './middleware/logger'
 import { poweredBy } from './middleware/powered-by'
-import { SmartRouter } from './mod'
 import { RegExpRouter } from './router/reg-exp-router'
+import { SmartRouter } from './router/smart-router'
 import { TrieRouter } from './router/trie-router'
 import type { Handler, MiddlewareHandler, Next } from './types'
 import type { Expect, Equal } from './utils/types'
diff --git a/src/index.ts b/src/index.ts
index 6f1e124d3..848fb3b01 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,3 @@
-// @denoify-ignore
-
 import { Hono } from './hono'
 export type {
   Env,
diff --git a/src/jsx/base.ts b/src/jsx/base.ts
index 15e1477d0..02ec4387e 100644
--- a/src/jsx/base.ts
+++ b/src/jsx/base.ts
@@ -4,6 +4,7 @@ import type { StringBuffer, HtmlEscaped, HtmlEscapedString } from '../utils/html
 import type { Context } from './context'
 import { globalContexts } from './context'
 import type { IntrinsicElements as IntrinsicElementsDefined } from './intrinsic-elements'
+import type { Hono } from './intrinsic-elements'
 import { normalizeIntrinsicElementProps, styleObjectForEach } from './utils'
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -15,16 +16,14 @@ export type FC<P = Props> = {
 }
 export type DOMAttributes = Hono.HTMLAttributes
 
-declare global {
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace JSX {
-    type Element = HtmlEscapedString | Promise<HtmlEscapedString>
-    interface ElementChildrenAttribute {
-      children: Child
-    }
-    interface IntrinsicElements extends IntrinsicElementsDefined {
-      [tagName: string]: Props
-    }
+// eslint-disable-next-line @typescript-eslint/no-namespace
+export namespace JSX {
+  export type Element = HtmlEscapedString | Promise<HtmlEscapedString>
+  export interface ElementChildrenAttribute {
+    children: Child
+  }
+  export interface IntrinsicElements extends IntrinsicElementsDefined {
+    [tagName: string]: Props
   }
 }
 
diff --git a/src/jsx/components.test.tsx b/src/jsx/components.test.tsx
index f15e68e43..43696d599 100644
--- a/src/jsx/components.test.tsx
+++ b/src/jsx/components.test.tsx
@@ -1,11 +1,10 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
+/** @jsxImportSource ./ */
 import { JSDOM } from 'jsdom'
 import type { HtmlEscapedString } from '../utils/html'
 import { HtmlEscapedCallbackPhase, resolveCallback as rawResolveCallback } from '../utils/html'
 import { ErrorBoundary } from './components'
 import { Suspense, renderToReadableStream } from './streaming'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx } from '.'
 
 function resolveCallback(template: string | HtmlEscapedString) {
   return rawResolveCallback(template, HtmlEscapedCallbackPhase.Stream, false, {})
diff --git a/src/jsx/components.ts b/src/jsx/components.ts
index df6755762..4ed7b8f87 100644
--- a/src/jsx/components.ts
+++ b/src/jsx/components.ts
@@ -4,7 +4,7 @@ import { HtmlEscapedCallbackPhase, resolveCallback } from '../utils/html'
 import { DOM_RENDERER } from './constants'
 import { ErrorBoundary as ErrorBoundaryDomRenderer } from './dom/components'
 import type { HasRenderToDom } from './dom/render'
-import type { FC, PropsWithChildren, Child } from '.'
+import type { FC, PropsWithChildren, Child } from './'
 
 let errorBoundaryCounter = 0
 
diff --git a/src/jsx/context.ts b/src/jsx/context.ts
index 04afe16a4..22e46f75a 100644
--- a/src/jsx/context.ts
+++ b/src/jsx/context.ts
@@ -3,7 +3,7 @@ import type { HtmlEscapedString } from '../utils/html'
 import { JSXFragmentNode } from './base'
 import { DOM_RENDERER } from './constants'
 import { createContextProviderFunction } from './dom/context'
-import type { FC, PropsWithChildren } from '.'
+import type { FC, PropsWithChildren } from './'
 
 export interface Context<T> {
   values: T[]
diff --git a/src/jsx/dom/components.test.tsx b/src/jsx/dom/components.test.tsx
index b1852f234..de86cc10d 100644
--- a/src/jsx/dom/components.test.tsx
+++ b/src/jsx/dom/components.test.tsx
@@ -1,9 +1,8 @@
+/** @jsxImportSource ../ */
 import { JSDOM } from 'jsdom'
 import { Suspense as SuspenseCommon, ErrorBoundary as ErrorBoundaryCommon } from '..' // for common
 // run tests by old style jsx default
 // hono/jsx/jsx-runtime and hono/jsx/dom/jsx-runtime are tested in their respective settings
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx } from '..'
 import { use, useState } from '../hooks'
 import { Suspense as SuspenseDom, ErrorBoundary as ErrorBoundaryDom } from '.' // for dom
 import { render } from '.'
diff --git a/src/jsx/dom/components.ts b/src/jsx/dom/components.ts
index c7bf31827..57e4ba603 100644
--- a/src/jsx/dom/components.ts
+++ b/src/jsx/dom/components.ts
@@ -1,4 +1,4 @@
-import type { FC, PropsWithChildren, Child } from '..'
+import type { FC, PropsWithChildren, Child } from '../'
 import type { FallbackRender, ErrorHandler } from '../components'
 import { DOM_ERROR_HANDLER } from '../constants'
 import { Fragment } from './jsx-runtime'
diff --git a/src/jsx/dom/context.test.tsx b/src/jsx/dom/context.test.tsx
index 8ab887389..60ccaf24b 100644
--- a/src/jsx/dom/context.test.tsx
+++ b/src/jsx/dom/context.test.tsx
@@ -1,10 +1,9 @@
+/** @jsxImportSource ../ */
 import { JSDOM } from 'jsdom'
 import { createContext as createContextCommon, useContext as useContextCommon } from '..' // for common
 import { use, Suspense } from '..'
 // run tests by old style jsx default
 // hono/jsx/jsx-runtime and hono/jsx/dom/jsx-runtime are tested in their respective settings
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment } from '..'
 import { createContext as createContextDom, useContext as useContextDom } from '.' // for dom
 import { render, useState } from '.'
 
diff --git a/src/jsx/dom/css.test.tsx b/src/jsx/dom/css.test.tsx
index 82430174c..c254ca486 100644
--- a/src/jsx/dom/css.test.tsx
+++ b/src/jsx/dom/css.test.tsx
@@ -1,8 +1,8 @@
+/** @jsxImportSource ../ */
 import { JSDOM } from 'jsdom'
 // run tests by old style jsx default
 // hono/jsx/jsx-runtime and hono/jsx/dom/jsx-runtime are tested in their respective settings
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx } from '..'
 import type { JSXNode } from '..'
 import { Style, css, rawCssString, createCssContext } from '../../helper/css'
 import { minify } from '../../helper/css/common'
diff --git a/src/jsx/dom/css.ts b/src/jsx/dom/css.ts
index 5a145ad7f..6e5ab84d8 100644
--- a/src/jsx/dom/css.ts
+++ b/src/jsx/dom/css.ts
@@ -1,4 +1,4 @@
-import type { FC, PropsWithChildren } from '..'
+import type { FC, PropsWithChildren } from '../'
 import type { CssClassName, CssVariableType } from '../../helper/css/common'
 import {
   SELECTOR,
@@ -133,12 +133,38 @@ export const createCssJsxDomObjects: CreateCssJsxDomObjectsType = ({ id }) => {
   return [cssObject, Style] as const
 }
 
+interface CssType {
+  (strings: TemplateStringsArray, ...values: CssVariableType[]): string
+}
+
+interface CxType {
+  (...args: (string | boolean | null | undefined)[]): string
+}
+
+interface KeyframesType {
+  (strings: TemplateStringsArray, ...values: CssVariableType[]): CssClassName
+}
+
+interface ViewTransitionType {
+  (strings: TemplateStringsArray, ...values: CssVariableType[]): string
+  (content: string): string
+  (): string
+}
+
+interface DefaultContextType {
+  css: CssType
+  cx: CxType
+  keyframes: KeyframesType
+  viewTransition: ViewTransitionType
+  Style: FC<PropsWithChildren<void>>
+}
+
 /**
  * @experimental
  * `createCssContext` is an experimental feature.
  * The API might be changed.
  */
-export const createCssContext = ({ id }: { id: Readonly<string> }) => {
+export const createCssContext = ({ id }: { id: Readonly<string> }): DefaultContextType => {
   const [cssObject, Style] = createCssJsxDomObjects({ id })
 
   const newCssClassNameObject = (cssClassName: CssClassName): string => {
@@ -147,24 +173,19 @@ export const createCssContext = ({ id }: { id: Readonly<string> }) => {
     return cssClassName as unknown as string
   }
 
-  const css = (strings: TemplateStringsArray, ...values: CssVariableType[]): string => {
+  const css: CssType = (strings, ...values) => {
     return newCssClassNameObject(cssCommon(strings, values))
   }
 
-  const cx = (...args: (string | boolean | null | undefined)[]): string => {
+  const cx: CxType = (...args) => {
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     args = cxCommon(args as any) as any
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     return css(Array(args.length).fill('') as any, ...args)
   }
 
-  const keyframes = keyframesCommon
+  const keyframes: KeyframesType = keyframesCommon
 
-  type ViewTransitionType = {
-    (strings: TemplateStringsArray, ...values: CssVariableType[]): string
-    (content: string): string
-    (): string
-  }
   const viewTransition: ViewTransitionType = ((
     strings: TemplateStringsArray | string | undefined,
     ...values: CssVariableType[]
@@ -182,7 +203,7 @@ export const createCssContext = ({ id }: { id: Readonly<string> }) => {
   }
 }
 
-const defaultContext = createCssContext({ id: DEFAULT_STYLE_ID })
+const defaultContext: DefaultContextType = createCssContext({ id: DEFAULT_STYLE_ID })
 
 /**
  * @experimental
diff --git a/src/jsx/dom/index.test.tsx b/src/jsx/dom/index.test.tsx
index c9d4d6014..979dc35fa 100644
--- a/src/jsx/dom/index.test.tsx
+++ b/src/jsx/dom/index.test.tsx
@@ -1,9 +1,9 @@
+/** @jsxImportSource ../ */
 import { JSDOM } from 'jsdom'
 import type { FC, Child } from '..'
 // run tests by old style jsx default
 // hono/jsx/jsx-runtime and hono/jsx/dom/jsx-runtime are tested in their respective settings
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment, createElement } from '..'
+import { createElement, jsx } from '..'
 import type { RefObject } from '../hooks'
 import {
   useState,
diff --git a/src/jsx/dom/index.ts b/src/jsx/dom/index.ts
index a308d6557..8c4d287cb 100644
--- a/src/jsx/dom/index.ts
+++ b/src/jsx/dom/index.ts
@@ -1,5 +1,6 @@
-import type { Props, Child, DOMAttributes, JSXNode } from '../base'
 import { memo, isValidElement } from '../base'
+import type { Props, Child, DOMAttributes, JSXNode } from '../base'
+import type { JSX } from '../base'
 import { Children } from '../children'
 import { useContext } from '../context'
 import {
@@ -140,6 +141,4 @@ export default {
 
 export type { Context } from '../context'
 
-// TODO: change to `export type *` after denoify bug is fixed
-// https://github.com/garronej/denoify/issues/124
-export * from '../types'
+export type * from '../types'
diff --git a/src/jsx/dom/render.ts b/src/jsx/dom/render.ts
index ba3fffe15..556867a83 100644
--- a/src/jsx/dom/render.ts
+++ b/src/jsx/dom/render.ts
@@ -22,7 +22,7 @@ const nameSpaceMap: Record<string, string> = {
   math: 'http://www.w3.org/1998/Math/MathML',
 } as const
 
-const skipProps = new Set(['children'])
+const skipProps: Set<string> = new Set(['children'])
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
 export type HasRenderToDom = FC<any> & { [DOM_RENDERER]: FC<any> }
@@ -152,15 +152,15 @@ const applyProps = (container: SupportedElement, attributes: Props, oldAttribute
         const nodeName = container.nodeName
         if (key === 'value') {
           if (nodeName === 'INPUT' || nodeName === 'TEXTAREA' || nodeName === 'SELECT') {
-            ;(container as HTMLInputElement).value =
+            ;(container as unknown as HTMLInputElement).value =
               value === null || value === undefined || value === false ? null : value
 
             if (nodeName === 'TEXTAREA') {
               container.textContent = value
               continue
             } else if (nodeName === 'SELECT') {
-              if ((container as HTMLSelectElement).selectedIndex === -1) {
-                ;(container as HTMLSelectElement).selectedIndex = 0
+              if ((container as unknown as HTMLSelectElement).selectedIndex === -1) {
+                ;(container as unknown as HTMLSelectElement).selectedIndex = 0
               }
               continue
             }
@@ -256,7 +256,7 @@ const getNextChildren = (
   })
 }
 
-const findInsertBefore = (node: Node | undefined): ChildNode | null => {
+const findInsertBefore = (node: Node | undefined): SupportedElement | Text | null => {
   if (!node) {
     return null
   } else if (node.tag === HONO_PORTAL_ELEMENT) {
@@ -372,10 +372,10 @@ const applyNodeObject = (node: NodeObject, container: Container) => {
   })
 }
 
-const fallbackUpdateFnArrayMap = new WeakMap<
+const fallbackUpdateFnArrayMap: WeakMap<
   NodeObject,
   Array<() => Promise<NodeObject | undefined>>
->()
+> = new WeakMap<NodeObject, Array<() => Promise<NodeObject | undefined>>>()
 export const build = (
   context: Context,
   node: NodeObject,
@@ -545,7 +545,10 @@ const updateSync = (context: Context, node: NodeObject) => {
 }
 
 type UpdateMapResolve = (node: NodeObject | undefined) => void
-const updateMap = new WeakMap<NodeObject, [UpdateMapResolve, Function]>()
+const updateMap: WeakMap<NodeObject, [UpdateMapResolve, Function]> = new WeakMap<
+  NodeObject,
+  [UpdateMapResolve, Function]
+>()
 const currentUpdateSets: Set<NodeObject>[] = []
 export const update = async (
   context: Context,
diff --git a/src/jsx/hooks/dom.test.tsx b/src/jsx/hooks/dom.test.tsx
index f4a470a34..93e278313 100644
--- a/src/jsx/hooks/dom.test.tsx
+++ b/src/jsx/hooks/dom.test.tsx
@@ -1,8 +1,7 @@
+/** @jsxImportSource ../ */
 import { JSDOM } from 'jsdom'
 // run tests by old style jsx default
 // hono/jsx/jsx-runtime and hono/jsx/dom/jsx-runtime are tested in their respective settings
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment } from '..'
 import { Suspense } from '../dom'
 import { render } from '../dom'
 import {
diff --git a/src/jsx/hooks/index.ts b/src/jsx/hooks/index.ts
index 2138ec5a7..aea3512d2 100644
--- a/src/jsx/hooks/index.ts
+++ b/src/jsx/hooks/index.ts
@@ -1,3 +1,4 @@
+import type { JSX } from '../base'
 import { DOM_STASH } from '../constants'
 import { buildDataStack, update, build } from '../dom/render'
 import type { Node, NodeObject, Context, PendingType, UpdateHook } from '../dom/render'
diff --git a/src/jsx/hooks/string.test.tsx b/src/jsx/hooks/string.test.tsx
index 8167965f6..ae91177b0 100644
--- a/src/jsx/hooks/string.test.tsx
+++ b/src/jsx/hooks/string.test.tsx
@@ -1,5 +1,5 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { jsx, useState, useSyncExternalStore } from '..'
+/** @jsxImportSource ../ */
+import { useState, useSyncExternalStore } from '..'
 
 describe('useState', () => {
   it('should be rendered with initial state', () => {
diff --git a/src/jsx/index.test.tsx b/src/jsx/index.test.tsx
index b9f752519..d871695f0 100644
--- a/src/jsx/index.test.tsx
+++ b/src/jsx/index.test.tsx
@@ -1,10 +1,9 @@
-// @denoify-ignore
+/** @jsxImportSource ./ */
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import { html } from '../helper/html'
 import { Hono } from '../hono'
 import { Suspense, renderToReadableStream } from './streaming'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import DefaultExport, { jsx, memo, Fragment, createContext, useContext } from '.'
+import DefaultExport, { memo, Fragment, createContext, useContext } from '.'
 import type { Context, FC, PropsWithChildren } from '.'
 
 interface SiteData {
diff --git a/src/jsx/index.ts b/src/jsx/index.ts
index 0999392e1..682740129 100644
--- a/src/jsx/index.ts
+++ b/src/jsx/index.ts
@@ -95,6 +95,4 @@ export default {
   Children,
 }
 
-// TODO: change to `export type *` after denoify bug is fixed
-// https://github.com/garronej/denoify/issues/124
-export * from './types'
+export type * from './types'
diff --git a/src/jsx/intrinsic-elements.ts b/src/jsx/intrinsic-elements.ts
index 0d3b01525..67caba334 100644
--- a/src/jsx/intrinsic-elements.ts
+++ b/src/jsx/intrinsic-elements.ts
@@ -7,724 +7,722 @@
  * Copyright (c) Meta Platforms, Inc. and affiliates.
  */
 
-declare global {
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace Hono {
-    type CrossOrigin = 'anonymous' | 'use-credentials' | '' | undefined
-    type CSSProperties = {}
-    type AnyAttributes = { [attributeName: string]: any }
-
-    interface JSXAttributes {
-      dangerouslySetInnerHTML?: {
-        __html: string
-      }
-    }
+// eslint-disable-next-line @typescript-eslint/no-namespace
+export namespace Hono {
+  export type CrossOrigin = 'anonymous' | 'use-credentials' | '' | undefined
+  export type CSSProperties = {}
+  type AnyAttributes = { [attributeName: string]: any }
 
-    interface EventAttributes {
-      onScroll?: (event: Event) => void
-      onScrollCapture?: (event: Event) => void
-      onScrollEnd?: (event: Event) => void
-      onScrollEndCapture?: (event: Event) => void
-      onWheel?: (event: WheelEvent) => void
-      onWheelCapture?: (event: WheelEvent) => void
-      onAnimationCancel?: (event: AnimationEvent) => void
-      onAnimationCancelCapture?: (event: AnimationEvent) => void
-      onAnimationEnd?: (event: AnimationEvent) => void
-      onAnimationEndCapture?: (event: AnimationEvent) => void
-      onAnimationIteration?: (event: AnimationEvent) => void
-      onAnimationIterationCapture?: (event: AnimationEvent) => void
-      onAnimationStart?: (event: AnimationEvent) => void
-      onAnimationStartCapture?: (event: AnimationEvent) => void
-      onCopy?: (event: ClipboardEvent) => void
-      onCopyCapture?: (event: ClipboardEvent) => void
-      onCut?: (event: ClipboardEvent) => void
-      onCutCapture?: (event: ClipboardEvent) => void
-      onPaste?: (event: ClipboardEvent) => void
-      onPasteCapture?: (event: ClipboardEvent) => void
-      onCompositionEnd?: (event: CompositionEvent) => void
-      onCompositionEndCapture?: (event: CompositionEvent) => void
-      onCompositionStart?: (event: CompositionEvent) => void
-      onCompositionStartCapture?: (event: CompositionEvent) => void
-      onCompositionUpdate?: (event: CompositionEvent) => void
-      onCompositionUpdateCapture?: (event: CompositionEvent) => void
-      onBlur?: (event: FocusEvent) => void
-      onBlurCapture?: (event: FocusEvent) => void
-      onFocus?: (event: FocusEvent) => void
-      onFocusCapture?: (event: FocusEvent) => void
-      onFocusIn?: (event: FocusEvent) => void
-      onFocusInCapture?: (event: FocusEvent) => void
-      onFocusOut?: (event: FocusEvent) => void
-      onFocusOutCapture?: (event: FocusEvent) => void
-      onFullscreenChange?: (event: Event) => void
-      onFullscreenChangeCapture?: (event: Event) => void
-      onFullscreenError?: (event: Event) => void
-      onFullscreenErrorCapture?: (event: Event) => void
-      onKeyDown?: (event: KeyboardEvent) => void
-      onKeyDownCapture?: (event: KeyboardEvent) => void
-      onKeyPress?: (event: KeyboardEvent) => void
-      onKeyPressCapture?: (event: KeyboardEvent) => void
-      onKeyUp?: (event: KeyboardEvent) => void
-      onKeyUpCapture?: (event: KeyboardEvent) => void
-      onAuxClick?: (event: MouseEvent) => void
-      onAuxClickCapture?: (event: MouseEvent) => void
-      onClick?: (event: MouseEvent) => void
-      onClickCapture?: (event: MouseEvent) => void
-      onContextMenu?: (event: MouseEvent) => void
-      onContextMenuCapture?: (event: MouseEvent) => void
-      onDoubleClick?: (event: MouseEvent) => void
-      onDoubleClickCapture?: (event: MouseEvent) => void
-      onMouseDown?: (event: MouseEvent) => void
-      onMouseDownCapture?: (event: MouseEvent) => void
-      onMouseEnter?: (event: MouseEvent) => void
-      onMouseEnterCapture?: (event: MouseEvent) => void
-      onMouseLeave?: (event: MouseEvent) => void
-      onMouseLeaveCapture?: (event: MouseEvent) => void
-      onMouseMove?: (event: MouseEvent) => void
-      onMouseMoveCapture?: (event: MouseEvent) => void
-      onMouseOut?: (event: MouseEvent) => void
-      onMouseOutCapture?: (event: MouseEvent) => void
-      onMouseOver?: (event: MouseEvent) => void
-      onMouseOverCapture?: (event: MouseEvent) => void
-      onMouseUp?: (event: MouseEvent) => void
-      onMouseUpCapture?: (event: MouseEvent) => void
-      onMouseWheel?: (event: WheelEvent) => void
-      onMouseWheelCapture?: (event: WheelEvent) => void
-      onGotPointerCapture?: (event: PointerEvent) => void
-      onGotPointerCaptureCapture?: (event: PointerEvent) => void
-      onLostPointerCapture?: (event: PointerEvent) => void
-      onLostPointerCaptureCapture?: (event: PointerEvent) => void
-      onPointerCancel?: (event: PointerEvent) => void
-      onPointerCancelCapture?: (event: PointerEvent) => void
-      onPointerDown?: (event: PointerEvent) => void
-      onPointerDownCapture?: (event: PointerEvent) => void
-      onPointerEnter?: (event: PointerEvent) => void
-      onPointerEnterCapture?: (event: PointerEvent) => void
-      onPointerLeave?: (event: PointerEvent) => void
-      onPointerLeaveCapture?: (event: PointerEvent) => void
-      onPointerMove?: (event: PointerEvent) => void
-      onPointerMoveCapture?: (event: PointerEvent) => void
-      onPointerOut?: (event: PointerEvent) => void
-      onPointerOutCapture?: (event: PointerEvent) => void
-      onPointerOver?: (event: PointerEvent) => void
-      onPointerOverCapture?: (event: PointerEvent) => void
-      onPointerUp?: (event: PointerEvent) => void
-      onPointerUpCapture?: (event: PointerEvent) => void
-      onTouchCancel?: (event: TouchEvent) => void
-      onTouchCancelCapture?: (event: TouchEvent) => void
-      onTouchEnd?: (event: TouchEvent) => void
-      onTouchEndCapture?: (event: TouchEvent) => void
-      onTouchMove?: (event: TouchEvent) => void
-      onTouchMoveCapture?: (event: TouchEvent) => void
-      onTouchStart?: (event: TouchEvent) => void
-      onTouchStartCapture?: (event: TouchEvent) => void
-      onTransitionCancel?: (event: TransitionEvent) => void
-      onTransitionCancelCapture?: (event: TransitionEvent) => void
-      onTransitionEnd?: (event: TransitionEvent) => void
-      onTransitionEndCapture?: (event: TransitionEvent) => void
-      onTransitionRun?: (event: TransitionEvent) => void
-      onTransitionRunCapture?: (event: TransitionEvent) => void
-      onTransitionStart?: (event: TransitionEvent) => void
-      onTransitionStartCapture?: (event: TransitionEvent) => void
-      onFormData?: (event: FormDataEvent) => void
-      onFormDataCapture?: (event: FormDataEvent) => void
-      onReset?: (event: Event) => void
-      onResetCapture?: (event: Event) => void
-      onSubmit?: (event: Event) => void
-      onSubmitCapture?: (event: Event) => void
-      onInvalid?: (event: Event) => void
-      onInvalidCapture?: (event: Event) => void
-      onSelect?: (event: Event) => void
-      onSelectCapture?: (event: Event) => void
-      onSelectChange?: (event: Event) => void
-      onSelectChangeCapture?: (event: Event) => void
-      onInput?: (event: InputEvent) => void
-      onInputCapture?: (event: InputEvent) => void
-      onBeforeInput?: (event: InputEvent) => void
-      onBeforeInputCapture?: (event: InputEvent) => void
-      onChange?: (event: Event) => void
-      onChangeCapture?: (event: Event) => void
+  interface JSXAttributes {
+    dangerouslySetInnerHTML?: {
+      __html: string
     }
+  }
 
-    interface HTMLAttributes extends JSXAttributes, EventAttributes, AnyAttributes {
-      accesskey?: string | undefined
-      autofocus?: boolean | undefined
-      class?: string | Promise<string> | undefined
-      contenteditable?: boolean | 'inherit' | undefined
-      contextmenu?: string | undefined
-      dir?: string | undefined
-      draggable?: boolean | undefined
-      hidden?: boolean | undefined
-      id?: string | undefined
-      lang?: string | undefined
-      nonce?: string | undefined
-      placeholder?: string | undefined
-      slot?: string | undefined
-      spellcheck?: boolean | undefined
-      style?: CSSProperties | undefined
-      tabindex?: number | undefined
-      title?: string | undefined
-      translate?: 'yes' | 'no' | undefined
-    }
+  interface EventAttributes {
+    onScroll?: (event: Event) => void
+    onScrollCapture?: (event: Event) => void
+    onScrollEnd?: (event: Event) => void
+    onScrollEndCapture?: (event: Event) => void
+    onWheel?: (event: WheelEvent) => void
+    onWheelCapture?: (event: WheelEvent) => void
+    onAnimationCancel?: (event: AnimationEvent) => void
+    onAnimationCancelCapture?: (event: AnimationEvent) => void
+    onAnimationEnd?: (event: AnimationEvent) => void
+    onAnimationEndCapture?: (event: AnimationEvent) => void
+    onAnimationIteration?: (event: AnimationEvent) => void
+    onAnimationIterationCapture?: (event: AnimationEvent) => void
+    onAnimationStart?: (event: AnimationEvent) => void
+    onAnimationStartCapture?: (event: AnimationEvent) => void
+    onCopy?: (event: ClipboardEvent) => void
+    onCopyCapture?: (event: ClipboardEvent) => void
+    onCut?: (event: ClipboardEvent) => void
+    onCutCapture?: (event: ClipboardEvent) => void
+    onPaste?: (event: ClipboardEvent) => void
+    onPasteCapture?: (event: ClipboardEvent) => void
+    onCompositionEnd?: (event: CompositionEvent) => void
+    onCompositionEndCapture?: (event: CompositionEvent) => void
+    onCompositionStart?: (event: CompositionEvent) => void
+    onCompositionStartCapture?: (event: CompositionEvent) => void
+    onCompositionUpdate?: (event: CompositionEvent) => void
+    onCompositionUpdateCapture?: (event: CompositionEvent) => void
+    onBlur?: (event: FocusEvent) => void
+    onBlurCapture?: (event: FocusEvent) => void
+    onFocus?: (event: FocusEvent) => void
+    onFocusCapture?: (event: FocusEvent) => void
+    onFocusIn?: (event: FocusEvent) => void
+    onFocusInCapture?: (event: FocusEvent) => void
+    onFocusOut?: (event: FocusEvent) => void
+    onFocusOutCapture?: (event: FocusEvent) => void
+    onFullscreenChange?: (event: Event) => void
+    onFullscreenChangeCapture?: (event: Event) => void
+    onFullscreenError?: (event: Event) => void
+    onFullscreenErrorCapture?: (event: Event) => void
+    onKeyDown?: (event: KeyboardEvent) => void
+    onKeyDownCapture?: (event: KeyboardEvent) => void
+    onKeyPress?: (event: KeyboardEvent) => void
+    onKeyPressCapture?: (event: KeyboardEvent) => void
+    onKeyUp?: (event: KeyboardEvent) => void
+    onKeyUpCapture?: (event: KeyboardEvent) => void
+    onAuxClick?: (event: MouseEvent) => void
+    onAuxClickCapture?: (event: MouseEvent) => void
+    onClick?: (event: MouseEvent) => void
+    onClickCapture?: (event: MouseEvent) => void
+    onContextMenu?: (event: MouseEvent) => void
+    onContextMenuCapture?: (event: MouseEvent) => void
+    onDoubleClick?: (event: MouseEvent) => void
+    onDoubleClickCapture?: (event: MouseEvent) => void
+    onMouseDown?: (event: MouseEvent) => void
+    onMouseDownCapture?: (event: MouseEvent) => void
+    onMouseEnter?: (event: MouseEvent) => void
+    onMouseEnterCapture?: (event: MouseEvent) => void
+    onMouseLeave?: (event: MouseEvent) => void
+    onMouseLeaveCapture?: (event: MouseEvent) => void
+    onMouseMove?: (event: MouseEvent) => void
+    onMouseMoveCapture?: (event: MouseEvent) => void
+    onMouseOut?: (event: MouseEvent) => void
+    onMouseOutCapture?: (event: MouseEvent) => void
+    onMouseOver?: (event: MouseEvent) => void
+    onMouseOverCapture?: (event: MouseEvent) => void
+    onMouseUp?: (event: MouseEvent) => void
+    onMouseUpCapture?: (event: MouseEvent) => void
+    onMouseWheel?: (event: WheelEvent) => void
+    onMouseWheelCapture?: (event: WheelEvent) => void
+    onGotPointerCapture?: (event: PointerEvent) => void
+    onGotPointerCaptureCapture?: (event: PointerEvent) => void
+    onLostPointerCapture?: (event: PointerEvent) => void
+    onLostPointerCaptureCapture?: (event: PointerEvent) => void
+    onPointerCancel?: (event: PointerEvent) => void
+    onPointerCancelCapture?: (event: PointerEvent) => void
+    onPointerDown?: (event: PointerEvent) => void
+    onPointerDownCapture?: (event: PointerEvent) => void
+    onPointerEnter?: (event: PointerEvent) => void
+    onPointerEnterCapture?: (event: PointerEvent) => void
+    onPointerLeave?: (event: PointerEvent) => void
+    onPointerLeaveCapture?: (event: PointerEvent) => void
+    onPointerMove?: (event: PointerEvent) => void
+    onPointerMoveCapture?: (event: PointerEvent) => void
+    onPointerOut?: (event: PointerEvent) => void
+    onPointerOutCapture?: (event: PointerEvent) => void
+    onPointerOver?: (event: PointerEvent) => void
+    onPointerOverCapture?: (event: PointerEvent) => void
+    onPointerUp?: (event: PointerEvent) => void
+    onPointerUpCapture?: (event: PointerEvent) => void
+    onTouchCancel?: (event: TouchEvent) => void
+    onTouchCancelCapture?: (event: TouchEvent) => void
+    onTouchEnd?: (event: TouchEvent) => void
+    onTouchEndCapture?: (event: TouchEvent) => void
+    onTouchMove?: (event: TouchEvent) => void
+    onTouchMoveCapture?: (event: TouchEvent) => void
+    onTouchStart?: (event: TouchEvent) => void
+    onTouchStartCapture?: (event: TouchEvent) => void
+    onTransitionCancel?: (event: TransitionEvent) => void
+    onTransitionCancelCapture?: (event: TransitionEvent) => void
+    onTransitionEnd?: (event: TransitionEvent) => void
+    onTransitionEndCapture?: (event: TransitionEvent) => void
+    onTransitionRun?: (event: TransitionEvent) => void
+    onTransitionRunCapture?: (event: TransitionEvent) => void
+    onTransitionStart?: (event: TransitionEvent) => void
+    onTransitionStartCapture?: (event: TransitionEvent) => void
+    onFormData?: (event: FormDataEvent) => void
+    onFormDataCapture?: (event: FormDataEvent) => void
+    onReset?: (event: Event) => void
+    onResetCapture?: (event: Event) => void
+    onSubmit?: (event: Event) => void
+    onSubmitCapture?: (event: Event) => void
+    onInvalid?: (event: Event) => void
+    onInvalidCapture?: (event: Event) => void
+    onSelect?: (event: Event) => void
+    onSelectCapture?: (event: Event) => void
+    onSelectChange?: (event: Event) => void
+    onSelectChangeCapture?: (event: Event) => void
+    onInput?: (event: InputEvent) => void
+    onInputCapture?: (event: InputEvent) => void
+    onBeforeInput?: (event: InputEvent) => void
+    onBeforeInputCapture?: (event: InputEvent) => void
+    onChange?: (event: Event) => void
+    onChangeCapture?: (event: Event) => void
+  }
 
-    type HTMLAttributeReferrerPolicy =
-      | ''
-      | 'no-referrer'
-      | 'no-referrer-when-downgrade'
-      | 'origin'
-      | 'origin-when-cross-origin'
-      | 'same-origin'
-      | 'strict-origin'
-      | 'strict-origin-when-cross-origin'
-      | 'unsafe-url'
-
-    type HTMLAttributeAnchorTarget = '_self' | '_blank' | '_parent' | '_top' | string
-
-    interface AnchorHTMLAttributes extends HTMLAttributes {
-      download?: any
-      href?: string | undefined
-      hreflang?: string | undefined
-      media?: string | undefined
-      ping?: string | undefined
-      target?: HTMLAttributeAnchorTarget | undefined
-      type?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-    }
+  export interface HTMLAttributes extends JSXAttributes, EventAttributes, AnyAttributes {
+    accesskey?: string | undefined
+    autofocus?: boolean | undefined
+    class?: string | Promise<string> | undefined
+    contenteditable?: boolean | 'inherit' | undefined
+    contextmenu?: string | undefined
+    dir?: string | undefined
+    draggable?: boolean | undefined
+    hidden?: boolean | undefined
+    id?: string | undefined
+    lang?: string | undefined
+    nonce?: string | undefined
+    placeholder?: string | undefined
+    slot?: string | undefined
+    spellcheck?: boolean | undefined
+    style?: CSSProperties | undefined
+    tabindex?: number | undefined
+    title?: string | undefined
+    translate?: 'yes' | 'no' | undefined
+  }
 
-    interface AudioHTMLAttributes extends MediaHTMLAttributes {}
-
-    interface AreaHTMLAttributes extends HTMLAttributes {
-      alt?: string | undefined
-      coords?: string | undefined
-      download?: any
-      href?: string | undefined
-      hreflang?: string | undefined
-      media?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      shape?: string | undefined
-      target?: string | undefined
-    }
+  type HTMLAttributeReferrerPolicy =
+    | ''
+    | 'no-referrer'
+    | 'no-referrer-when-downgrade'
+    | 'origin'
+    | 'origin-when-cross-origin'
+    | 'same-origin'
+    | 'strict-origin'
+    | 'strict-origin-when-cross-origin'
+    | 'unsafe-url'
+
+  type HTMLAttributeAnchorTarget = '_self' | '_blank' | '_parent' | '_top' | string
+
+  interface AnchorHTMLAttributes extends HTMLAttributes {
+    download?: any
+    href?: string | undefined
+    hreflang?: string | undefined
+    media?: string | undefined
+    ping?: string | undefined
+    target?: HTMLAttributeAnchorTarget | undefined
+    type?: string | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+  }
 
-    interface BaseHTMLAttributes extends HTMLAttributes {
-      href?: string | undefined
-      target?: string | undefined
-    }
+  interface AudioHTMLAttributes extends MediaHTMLAttributes {}
+
+  interface AreaHTMLAttributes extends HTMLAttributes {
+    alt?: string | undefined
+    coords?: string | undefined
+    download?: any
+    href?: string | undefined
+    hreflang?: string | undefined
+    media?: string | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+    shape?: string | undefined
+    target?: string | undefined
+  }
 
-    interface BlockquoteHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-    }
+  interface BaseHTMLAttributes extends HTMLAttributes {
+    href?: string | undefined
+    target?: string | undefined
+  }
 
-    interface ButtonHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      form?: string | undefined
-      formenctype?: string | undefined
-      formmethod?: string | undefined
-      formnovalidate?: boolean | undefined
-      formtarget?: string | undefined
-      name?: string | undefined
-      type?: 'submit' | 'reset' | 'button' | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface BlockquoteHTMLAttributes extends HTMLAttributes {
+    cite?: string | undefined
+  }
 
-    interface CanvasHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      width?: number | string | undefined
-    }
+  interface ButtonHTMLAttributes extends HTMLAttributes {
+    disabled?: boolean | undefined
+    form?: string | undefined
+    formenctype?: string | undefined
+    formmethod?: string | undefined
+    formnovalidate?: boolean | undefined
+    formtarget?: string | undefined
+    name?: string | undefined
+    type?: 'submit' | 'reset' | 'button' | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface ColHTMLAttributes extends HTMLAttributes {
-      span?: number | undefined
-      width?: number | string | undefined
-    }
+  interface CanvasHTMLAttributes extends HTMLAttributes {
+    height?: number | string | undefined
+    width?: number | string | undefined
+  }
 
-    interface ColgroupHTMLAttributes extends HTMLAttributes {
-      span?: number | undefined
-    }
+  interface ColHTMLAttributes extends HTMLAttributes {
+    span?: number | undefined
+    width?: number | string | undefined
+  }
 
-    interface DataHTMLAttributes extends HTMLAttributes {
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface ColgroupHTMLAttributes extends HTMLAttributes {
+    span?: number | undefined
+  }
 
-    interface DetailsHTMLAttributes extends HTMLAttributes {
-      open?: boolean | undefined
-    }
+  interface DataHTMLAttributes extends HTMLAttributes {
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface DelHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-      dateTime?: string | undefined
-    }
+  interface DetailsHTMLAttributes extends HTMLAttributes {
+    open?: boolean | undefined
+  }
 
-    interface DialogHTMLAttributes extends HTMLAttributes {
-      open?: boolean | undefined
-    }
+  interface DelHTMLAttributes extends HTMLAttributes {
+    cite?: string | undefined
+    dateTime?: string | undefined
+  }
 
-    interface EmbedHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      src?: string | undefined
-      type?: string | undefined
-      width?: number | string | undefined
-    }
+  interface DialogHTMLAttributes extends HTMLAttributes {
+    open?: boolean | undefined
+  }
 
-    interface FieldsetHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      form?: string | undefined
-      name?: string | undefined
-    }
+  interface EmbedHTMLAttributes extends HTMLAttributes {
+    height?: number | string | undefined
+    src?: string | undefined
+    type?: string | undefined
+    width?: number | string | undefined
+  }
 
-    interface FormHTMLAttributes extends HTMLAttributes {
-      'accept-charset'?: string | undefined
-      autocomplete?: string | undefined
-      enctype?: string | undefined
-      method?: string | undefined
-      name?: string | undefined
-      novalidate?: boolean | undefined
-      target?: string | undefined
-    }
+  interface FieldsetHTMLAttributes extends HTMLAttributes {
+    disabled?: boolean | undefined
+    form?: string | undefined
+    name?: string | undefined
+  }
 
-    interface HtmlHTMLAttributes extends HTMLAttributes {
-      manifest?: string | undefined
-    }
+  interface FormHTMLAttributes extends HTMLAttributes {
+    'accept-charset'?: string | undefined
+    autocomplete?: string | undefined
+    enctype?: string | undefined
+    method?: string | undefined
+    name?: string | undefined
+    novalidate?: boolean | undefined
+    target?: string | undefined
+  }
 
-    interface IframeHTMLAttributes extends HTMLAttributes {
-      allow?: string | undefined
-      allowfullscreen?: boolean | undefined
-      height?: number | string | undefined
-      loading?: 'eager' | 'lazy' | undefined
-      name?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sandbox?: string | undefined
-      seamless?: boolean | undefined
-      src?: string | undefined
-      srcdoc?: string | undefined
-      width?: number | string | undefined
-    }
+  interface HtmlHTMLAttributes extends HTMLAttributes {
+    manifest?: string | undefined
+  }
 
-    interface ImgHTMLAttributes extends HTMLAttributes {
-      alt?: string | undefined
-      crossorigin?: CrossOrigin
-      decoding?: 'async' | 'auto' | 'sync' | undefined
-      height?: number | string | undefined
-      loading?: 'eager' | 'lazy' | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sizes?: string | undefined
-      src?: string | undefined
-      srcset?: string | undefined
-      usemap?: string | undefined
-      width?: number | string | undefined
-    }
+  interface IframeHTMLAttributes extends HTMLAttributes {
+    allow?: string | undefined
+    allowfullscreen?: boolean | undefined
+    height?: number | string | undefined
+    loading?: 'eager' | 'lazy' | undefined
+    name?: string | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+    sandbox?: string | undefined
+    seamless?: boolean | undefined
+    src?: string | undefined
+    srcdoc?: string | undefined
+    width?: number | string | undefined
+  }
 
-    interface InsHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-      datetime?: string | undefined
-    }
+  interface ImgHTMLAttributes extends HTMLAttributes {
+    alt?: string | undefined
+    crossorigin?: CrossOrigin
+    decoding?: 'async' | 'auto' | 'sync' | undefined
+    height?: number | string | undefined
+    loading?: 'eager' | 'lazy' | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+    sizes?: string | undefined
+    src?: string | undefined
+    srcset?: string | undefined
+    usemap?: string | undefined
+    width?: number | string | undefined
+  }
 
-    type HTMLInputTypeAttribute =
-      | 'button'
-      | 'checkbox'
-      | 'color'
-      | 'date'
-      | 'datetime-local'
-      | 'email'
-      | 'file'
-      | 'hidden'
-      | 'image'
-      | 'month'
-      | 'number'
-      | 'password'
-      | 'radio'
-      | 'range'
-      | 'reset'
-      | 'search'
-      | 'submit'
-      | 'tel'
-      | 'text'
-      | 'time'
-      | 'url'
-      | 'week'
-      | string
-
-    interface InputHTMLAttributes extends HTMLAttributes {
-      accept?: string | undefined
-      alt?: string | undefined
-      autocomplete?: string | undefined
-      capture?: boolean | 'user' | 'environment' | undefined // https://www.w3.org/TR/html-media-capture/#the-capture-attribute
-      checked?: boolean | undefined
-      disabled?: boolean | undefined
-      enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined
-      form?: string | undefined
-      formenctype?: string | undefined
-      formmethod?: string | undefined
-      formnovalidate?: boolean | undefined
-      formtarget?: string | undefined
-      height?: number | string | undefined
-      list?: string | undefined
-      max?: number | string | undefined
-      maxlength?: number | undefined
-      min?: number | string | undefined
-      minlength?: number | undefined
-      multiple?: boolean | undefined
-      name?: string | undefined
-      pattern?: string | undefined
-      placeholder?: string | undefined
-      readonly?: boolean | undefined
-      required?: boolean | undefined
-      size?: number | undefined
-      src?: string | undefined
-      step?: number | string | undefined
-      type?: HTMLInputTypeAttribute | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-      width?: number | string | undefined
-    }
+  interface InsHTMLAttributes extends HTMLAttributes {
+    cite?: string | undefined
+    datetime?: string | undefined
+  }
 
-    interface KeygenHTMLAttributes extends HTMLAttributes {
-      challenge?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      keytype?: string | undefined
-      name?: string | undefined
-    }
+  type HTMLInputTypeAttribute =
+    | 'button'
+    | 'checkbox'
+    | 'color'
+    | 'date'
+    | 'datetime-local'
+    | 'email'
+    | 'file'
+    | 'hidden'
+    | 'image'
+    | 'month'
+    | 'number'
+    | 'password'
+    | 'radio'
+    | 'range'
+    | 'reset'
+    | 'search'
+    | 'submit'
+    | 'tel'
+    | 'text'
+    | 'time'
+    | 'url'
+    | 'week'
+    | string
+
+  interface InputHTMLAttributes extends HTMLAttributes {
+    accept?: string | undefined
+    alt?: string | undefined
+    autocomplete?: string | undefined
+    capture?: boolean | 'user' | 'environment' | undefined // https://www.w3.org/TR/html-media-capture/#the-capture-attribute
+    checked?: boolean | undefined
+    disabled?: boolean | undefined
+    enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined
+    form?: string | undefined
+    formenctype?: string | undefined
+    formmethod?: string | undefined
+    formnovalidate?: boolean | undefined
+    formtarget?: string | undefined
+    height?: number | string | undefined
+    list?: string | undefined
+    max?: number | string | undefined
+    maxlength?: number | undefined
+    min?: number | string | undefined
+    minlength?: number | undefined
+    multiple?: boolean | undefined
+    name?: string | undefined
+    pattern?: string | undefined
+    placeholder?: string | undefined
+    readonly?: boolean | undefined
+    required?: boolean | undefined
+    size?: number | undefined
+    src?: string | undefined
+    step?: number | string | undefined
+    type?: HTMLInputTypeAttribute | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+    width?: number | string | undefined
+  }
 
-    interface LabelHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      for?: string | undefined
-    }
+  interface KeygenHTMLAttributes extends HTMLAttributes {
+    challenge?: string | undefined
+    disabled?: boolean | undefined
+    form?: string | undefined
+    keytype?: string | undefined
+    name?: string | undefined
+  }
 
-    interface LiHTMLAttributes extends HTMLAttributes {
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface LabelHTMLAttributes extends HTMLAttributes {
+    form?: string | undefined
+    for?: string | undefined
+  }
 
-    interface LinkHTMLAttributes extends HTMLAttributes {
-      as?: string | undefined
-      crossorigin?: CrossOrigin
-      href?: string | undefined
-      hreflang?: string | undefined
-      integrity?: string | undefined
-      media?: string | undefined
-      imagesrcset?: string | undefined
-      imagesizes?: string | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      sizes?: string | undefined
-      type?: string | undefined
-      charSet?: string | undefined
-    }
+  interface LiHTMLAttributes extends HTMLAttributes {
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface MapHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-    }
+  interface LinkHTMLAttributes extends HTMLAttributes {
+    as?: string | undefined
+    crossorigin?: CrossOrigin
+    href?: string | undefined
+    hreflang?: string | undefined
+    integrity?: string | undefined
+    media?: string | undefined
+    imagesrcset?: string | undefined
+    imagesizes?: string | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+    sizes?: string | undefined
+    type?: string | undefined
+    charSet?: string | undefined
+  }
 
-    interface MenuHTMLAttributes extends HTMLAttributes {
-      type?: string | undefined
-    }
+  interface MapHTMLAttributes extends HTMLAttributes {
+    name?: string | undefined
+  }
 
-    interface MediaHTMLAttributes extends HTMLAttributes {
-      autoplay?: boolean | undefined
-      controls?: boolean | undefined
-      controlslist?: string | undefined
-      crossorigin?: CrossOrigin
-      loop?: boolean | undefined
-      mediagroup?: string | undefined
-      muted?: boolean | undefined
-      playsinline?: boolean | undefined
-      preload?: string | undefined
-      src?: string | undefined
-    }
+  interface MenuHTMLAttributes extends HTMLAttributes {
+    type?: string | undefined
+  }
 
-    interface MetaHTMLAttributes extends HTMLAttributes {
-      charset?: string | undefined
-      'http-equiv'?: string | undefined
-      name?: string | undefined
-      media?: string | undefined
-      content?: string | undefined
-    }
+  interface MediaHTMLAttributes extends HTMLAttributes {
+    autoplay?: boolean | undefined
+    controls?: boolean | undefined
+    controlslist?: string | undefined
+    crossorigin?: CrossOrigin
+    loop?: boolean | undefined
+    mediagroup?: string | undefined
+    muted?: boolean | undefined
+    playsinline?: boolean | undefined
+    preload?: string | undefined
+    src?: string | undefined
+  }
 
-    interface MeterHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      high?: number | undefined
-      low?: number | undefined
-      max?: number | string | undefined
-      min?: number | string | undefined
-      optimum?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface MetaHTMLAttributes extends HTMLAttributes {
+    charset?: string | undefined
+    'http-equiv'?: string | undefined
+    name?: string | undefined
+    media?: string | undefined
+    content?: string | undefined
+  }
 
-    interface QuoteHTMLAttributes extends HTMLAttributes {
-      cite?: string | undefined
-    }
+  interface MeterHTMLAttributes extends HTMLAttributes {
+    form?: string | undefined
+    high?: number | undefined
+    low?: number | undefined
+    max?: number | string | undefined
+    min?: number | string | undefined
+    optimum?: number | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface ObjectHTMLAttributes extends HTMLAttributes {
-      data?: string | undefined
-      form?: string | undefined
-      height?: number | string | undefined
-      name?: string | undefined
-      type?: string | undefined
-      usemap?: string | undefined
-      width?: number | string | undefined
-    }
+  interface QuoteHTMLAttributes extends HTMLAttributes {
+    cite?: string | undefined
+  }
 
-    interface OlHTMLAttributes extends HTMLAttributes {
-      reversed?: boolean | undefined
-      start?: number | undefined
-      type?: '1' | 'a' | 'A' | 'i' | 'I' | undefined
-    }
+  interface ObjectHTMLAttributes extends HTMLAttributes {
+    data?: string | undefined
+    form?: string | undefined
+    height?: number | string | undefined
+    name?: string | undefined
+    type?: string | undefined
+    usemap?: string | undefined
+    width?: number | string | undefined
+  }
 
-    interface OptgroupHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      label?: string | undefined
-    }
+  interface OlHTMLAttributes extends HTMLAttributes {
+    reversed?: boolean | undefined
+    start?: number | undefined
+    type?: '1' | 'a' | 'A' | 'i' | 'I' | undefined
+  }
 
-    interface OptionHTMLAttributes extends HTMLAttributes {
-      disabled?: boolean | undefined
-      label?: string | undefined
-      selected?: boolean | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface OptgroupHTMLAttributes extends HTMLAttributes {
+    disabled?: boolean | undefined
+    label?: string | undefined
+  }
 
-    interface OutputHTMLAttributes extends HTMLAttributes {
-      form?: string | undefined
-      for?: string | undefined
-      name?: string | undefined
-    }
+  interface OptionHTMLAttributes extends HTMLAttributes {
+    disabled?: boolean | undefined
+    label?: string | undefined
+    selected?: boolean | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface ParamHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface OutputHTMLAttributes extends HTMLAttributes {
+    form?: string | undefined
+    for?: string | undefined
+    name?: string | undefined
+  }
 
-    interface ProgressHTMLAttributes extends HTMLAttributes {
-      max?: number | string | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface ParamHTMLAttributes extends HTMLAttributes {
+    name?: string | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface SlotHTMLAttributes extends HTMLAttributes {
-      name?: string | undefined
-    }
+  interface ProgressHTMLAttributes extends HTMLAttributes {
+    max?: number | string | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface ScriptHTMLAttributes extends HTMLAttributes {
-      async?: boolean | undefined
-      crossorigin?: CrossOrigin
-      defer?: boolean | undefined
-      integrity?: string | undefined
-      nomodule?: boolean | undefined
-      referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
-      src?: string | undefined
-      type?: string | undefined
-    }
+  interface SlotHTMLAttributes extends HTMLAttributes {
+    name?: string | undefined
+  }
 
-    interface SelectHTMLAttributes extends HTMLAttributes {
-      autocomplete?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      multiple?: boolean | undefined
-      name?: string | undefined
-      required?: boolean | undefined
-      size?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-    }
+  interface ScriptHTMLAttributes extends HTMLAttributes {
+    async?: boolean | undefined
+    crossorigin?: CrossOrigin
+    defer?: boolean | undefined
+    integrity?: string | undefined
+    nomodule?: boolean | undefined
+    referrerpolicy?: HTMLAttributeReferrerPolicy | undefined
+    src?: string | undefined
+    type?: string | undefined
+  }
 
-    interface SourceHTMLAttributes extends HTMLAttributes {
-      height?: number | string | undefined
-      media?: string | undefined
-      sizes?: string | undefined
-      src?: string | undefined
-      srcset?: string | undefined
-      type?: string | undefined
-      width?: number | string | undefined
-    }
+  interface SelectHTMLAttributes extends HTMLAttributes {
+    autocomplete?: string | undefined
+    disabled?: boolean | undefined
+    form?: string | undefined
+    multiple?: boolean | undefined
+    name?: string | undefined
+    required?: boolean | undefined
+    size?: number | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+  }
 
-    interface StyleHTMLAttributes extends HTMLAttributes {
-      media?: string | undefined
-      scoped?: boolean | undefined
-      type?: string | undefined
-    }
+  interface SourceHTMLAttributes extends HTMLAttributes {
+    height?: number | string | undefined
+    media?: string | undefined
+    sizes?: string | undefined
+    src?: string | undefined
+    srcset?: string | undefined
+    type?: string | undefined
+    width?: number | string | undefined
+  }
 
-    interface TableHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | undefined
-      bgcolor?: string | undefined
-      border?: number | undefined
-      cellpadding?: number | string | undefined
-      cellspacing?: number | string | undefined
-      frame?: boolean | undefined
-      rules?: 'none' | 'groups' | 'rows' | 'columns' | 'all' | undefined
-      summary?: string | undefined
-      width?: number | string | undefined
-    }
+  interface StyleHTMLAttributes extends HTMLAttributes {
+    media?: string | undefined
+    scoped?: boolean | undefined
+    type?: string | undefined
+  }
 
-    interface TextareaHTMLAttributes extends HTMLAttributes {
-      autocomplete?: string | undefined
-      cols?: number | undefined
-      dirname?: string | undefined
-      disabled?: boolean | undefined
-      form?: string | undefined
-      maxlength?: number | undefined
-      minlength?: number | undefined
-      name?: string | undefined
-      placeholder?: string | undefined
-      readonly?: boolean | undefined
-      required?: boolean | undefined
-      rows?: number | undefined
-      value?: string | ReadonlyArray<string> | number | undefined
-      wrap?: string | undefined
-    }
+  interface TableHTMLAttributes extends HTMLAttributes {
+    align?: 'left' | 'center' | 'right' | undefined
+    bgcolor?: string | undefined
+    border?: number | undefined
+    cellpadding?: number | string | undefined
+    cellspacing?: number | string | undefined
+    frame?: boolean | undefined
+    rules?: 'none' | 'groups' | 'rows' | 'columns' | 'all' | undefined
+    summary?: string | undefined
+    width?: number | string | undefined
+  }
 
-    interface TdHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
-      colspan?: number | undefined
-      headers?: string | undefined
-      rowspan?: number | undefined
-      scope?: string | undefined
-      abbr?: string | undefined
-      height?: number | string | undefined
-      width?: number | string | undefined
-      valign?: 'top' | 'middle' | 'bottom' | 'baseline' | undefined
-    }
+  interface TextareaHTMLAttributes extends HTMLAttributes {
+    autocomplete?: string | undefined
+    cols?: number | undefined
+    dirname?: string | undefined
+    disabled?: boolean | undefined
+    form?: string | undefined
+    maxlength?: number | undefined
+    minlength?: number | undefined
+    name?: string | undefined
+    placeholder?: string | undefined
+    readonly?: boolean | undefined
+    required?: boolean | undefined
+    rows?: number | undefined
+    value?: string | ReadonlyArray<string> | number | undefined
+    wrap?: string | undefined
+  }
 
-    interface ThHTMLAttributes extends HTMLAttributes {
-      align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
-      colspan?: number | undefined
-      headers?: string | undefined
-      rowspan?: number | undefined
-      scope?: string | undefined
-      abbr?: string | undefined
-    }
+  interface TdHTMLAttributes extends HTMLAttributes {
+    align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
+    colspan?: number | undefined
+    headers?: string | undefined
+    rowspan?: number | undefined
+    scope?: string | undefined
+    abbr?: string | undefined
+    height?: number | string | undefined
+    width?: number | string | undefined
+    valign?: 'top' | 'middle' | 'bottom' | 'baseline' | undefined
+  }
 
-    interface TimeHTMLAttributes extends HTMLAttributes {
-      datetime?: string | undefined
-    }
+  interface ThHTMLAttributes extends HTMLAttributes {
+    align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined
+    colspan?: number | undefined
+    headers?: string | undefined
+    rowspan?: number | undefined
+    scope?: string | undefined
+    abbr?: string | undefined
+  }
 
-    interface TrackHTMLAttributes extends HTMLAttributes {
-      default?: boolean | undefined
-      kind?: string | undefined
-      label?: string | undefined
-      src?: string | undefined
-      srclang?: string | undefined
-    }
+  interface TimeHTMLAttributes extends HTMLAttributes {
+    datetime?: string | undefined
+  }
 
-    interface VideoHTMLAttributes extends MediaHTMLAttributes {
-      height?: number | string | undefined
-      playsinline?: boolean | undefined
-      poster?: string | undefined
-      width?: number | string | undefined
-      disablePictureInPicture?: boolean | undefined
-      disableRemotePlayback?: boolean | undefined
-    }
+  interface TrackHTMLAttributes extends HTMLAttributes {
+    default?: boolean | undefined
+    kind?: string | undefined
+    label?: string | undefined
+    src?: string | undefined
+    srclang?: string | undefined
+  }
 
-    interface IntrinsicElements {
-      a: AnchorHTMLAttributes
-      abbr: HTMLAttributes
-      address: HTMLAttributes
-      area: AreaHTMLAttributes
-      article: HTMLAttributes
-      aside: HTMLAttributes
-      audio: AudioHTMLAttributes
-      b: HTMLAttributes
-      base: BaseHTMLAttributes
-      bdi: HTMLAttributes
-      bdo: HTMLAttributes
-      big: HTMLAttributes
-      blockquote: BlockquoteHTMLAttributes
-      body: HTMLAttributes
-      br: HTMLAttributes
-      button: ButtonHTMLAttributes
-      canvas: CanvasHTMLAttributes
-      caption: HTMLAttributes
-      center: HTMLAttributes
-      cite: HTMLAttributes
-      code: HTMLAttributes
-      col: ColHTMLAttributes
-      colgroup: ColgroupHTMLAttributes
-      data: DataHTMLAttributes
-      datalist: HTMLAttributes
-      dd: HTMLAttributes
-      del: DelHTMLAttributes
-      details: DetailsHTMLAttributes
-      dfn: HTMLAttributes
-      dialog: DialogHTMLAttributes
-      div: HTMLAttributes
-      dl: HTMLAttributes
-      dt: HTMLAttributes
-      em: HTMLAttributes
-      embed: EmbedHTMLAttributes
-      fieldset: FieldsetHTMLAttributes
-      figcaption: HTMLAttributes
-      figure: HTMLAttributes
-      footer: HTMLAttributes
-      form: FormHTMLAttributes
-      h1: HTMLAttributes
-      h2: HTMLAttributes
-      h3: HTMLAttributes
-      h4: HTMLAttributes
-      h5: HTMLAttributes
-      h6: HTMLAttributes
-      head: HTMLAttributes
-      header: HTMLAttributes
-      hgroup: HTMLAttributes
-      hr: HTMLAttributes
-      html: HtmlHTMLAttributes
-      i: HTMLAttributes
-      iframe: IframeHTMLAttributes
-      img: ImgHTMLAttributes
-      input: InputHTMLAttributes
-      ins: InsHTMLAttributes
-      kbd: HTMLAttributes
-      keygen: KeygenHTMLAttributes
-      label: LabelHTMLAttributes
-      legend: HTMLAttributes
-      li: LiHTMLAttributes
-      link: LinkHTMLAttributes
-      main: HTMLAttributes
-      map: MapHTMLAttributes
-      mark: HTMLAttributes
-      menu: MenuHTMLAttributes
-      menuitem: HTMLAttributes
-      meta: MetaHTMLAttributes
-      meter: MeterHTMLAttributes
-      nav: HTMLAttributes
-      noscript: HTMLAttributes
-      object: ObjectHTMLAttributes
-      ol: OlHTMLAttributes
-      optgroup: OptgroupHTMLAttributes
-      option: OptionHTMLAttributes
-      output: OutputHTMLAttributes
-      p: HTMLAttributes
-      param: ParamHTMLAttributes
-      picture: HTMLAttributes
-      pre: HTMLAttributes
-      progress: ProgressHTMLAttributes
-      q: QuoteHTMLAttributes
-      rp: HTMLAttributes
-      rt: HTMLAttributes
-      ruby: HTMLAttributes
-      s: HTMLAttributes
-      samp: HTMLAttributes
-      search: HTMLAttributes
-      slot: SlotHTMLAttributes
-      script: ScriptHTMLAttributes
-      section: HTMLAttributes
-      select: SelectHTMLAttributes
-      small: HTMLAttributes
-      source: SourceHTMLAttributes
-      span: HTMLAttributes
-      strong: HTMLAttributes
-      style: StyleHTMLAttributes
-      sub: HTMLAttributes
-      summary: HTMLAttributes
-      sup: HTMLAttributes
-      table: TableHTMLAttributes
-      template: HTMLAttributes
-      tbody: HTMLAttributes
-      td: TdHTMLAttributes
-      textarea: TextareaHTMLAttributes
-      tfoot: HTMLAttributes
-      th: ThHTMLAttributes
-      thead: HTMLAttributes
-      time: TimeHTMLAttributes
-      title: HTMLAttributes
-      tr: HTMLAttributes
-      track: TrackHTMLAttributes
-      u: HTMLAttributes
-      ul: HTMLAttributes
-      var: HTMLAttributes
-      video: VideoHTMLAttributes
-      wbr: HTMLAttributes
-    }
+  interface VideoHTMLAttributes extends MediaHTMLAttributes {
+    height?: number | string | undefined
+    playsinline?: boolean | undefined
+    poster?: string | undefined
+    width?: number | string | undefined
+    disablePictureInPicture?: boolean | undefined
+    disableRemotePlayback?: boolean | undefined
+  }
+
+  export interface IntrinsicElements {
+    a: AnchorHTMLAttributes
+    abbr: HTMLAttributes
+    address: HTMLAttributes
+    area: AreaHTMLAttributes
+    article: HTMLAttributes
+    aside: HTMLAttributes
+    audio: AudioHTMLAttributes
+    b: HTMLAttributes
+    base: BaseHTMLAttributes
+    bdi: HTMLAttributes
+    bdo: HTMLAttributes
+    big: HTMLAttributes
+    blockquote: BlockquoteHTMLAttributes
+    body: HTMLAttributes
+    br: HTMLAttributes
+    button: ButtonHTMLAttributes
+    canvas: CanvasHTMLAttributes
+    caption: HTMLAttributes
+    center: HTMLAttributes
+    cite: HTMLAttributes
+    code: HTMLAttributes
+    col: ColHTMLAttributes
+    colgroup: ColgroupHTMLAttributes
+    data: DataHTMLAttributes
+    datalist: HTMLAttributes
+    dd: HTMLAttributes
+    del: DelHTMLAttributes
+    details: DetailsHTMLAttributes
+    dfn: HTMLAttributes
+    dialog: DialogHTMLAttributes
+    div: HTMLAttributes
+    dl: HTMLAttributes
+    dt: HTMLAttributes
+    em: HTMLAttributes
+    embed: EmbedHTMLAttributes
+    fieldset: FieldsetHTMLAttributes
+    figcaption: HTMLAttributes
+    figure: HTMLAttributes
+    footer: HTMLAttributes
+    form: FormHTMLAttributes
+    h1: HTMLAttributes
+    h2: HTMLAttributes
+    h3: HTMLAttributes
+    h4: HTMLAttributes
+    h5: HTMLAttributes
+    h6: HTMLAttributes
+    head: HTMLAttributes
+    header: HTMLAttributes
+    hgroup: HTMLAttributes
+    hr: HTMLAttributes
+    html: HtmlHTMLAttributes
+    i: HTMLAttributes
+    iframe: IframeHTMLAttributes
+    img: ImgHTMLAttributes
+    input: InputHTMLAttributes
+    ins: InsHTMLAttributes
+    kbd: HTMLAttributes
+    keygen: KeygenHTMLAttributes
+    label: LabelHTMLAttributes
+    legend: HTMLAttributes
+    li: LiHTMLAttributes
+    link: LinkHTMLAttributes
+    main: HTMLAttributes
+    map: MapHTMLAttributes
+    mark: HTMLAttributes
+    menu: MenuHTMLAttributes
+    menuitem: HTMLAttributes
+    meta: MetaHTMLAttributes
+    meter: MeterHTMLAttributes
+    nav: HTMLAttributes
+    noscript: HTMLAttributes
+    object: ObjectHTMLAttributes
+    ol: OlHTMLAttributes
+    optgroup: OptgroupHTMLAttributes
+    option: OptionHTMLAttributes
+    output: OutputHTMLAttributes
+    p: HTMLAttributes
+    param: ParamHTMLAttributes
+    picture: HTMLAttributes
+    pre: HTMLAttributes
+    progress: ProgressHTMLAttributes
+    q: QuoteHTMLAttributes
+    rp: HTMLAttributes
+    rt: HTMLAttributes
+    ruby: HTMLAttributes
+    s: HTMLAttributes
+    samp: HTMLAttributes
+    search: HTMLAttributes
+    slot: SlotHTMLAttributes
+    script: ScriptHTMLAttributes
+    section: HTMLAttributes
+    select: SelectHTMLAttributes
+    small: HTMLAttributes
+    source: SourceHTMLAttributes
+    span: HTMLAttributes
+    strong: HTMLAttributes
+    style: StyleHTMLAttributes
+    sub: HTMLAttributes
+    summary: HTMLAttributes
+    sup: HTMLAttributes
+    table: TableHTMLAttributes
+    template: HTMLAttributes
+    tbody: HTMLAttributes
+    td: TdHTMLAttributes
+    textarea: TextareaHTMLAttributes
+    tfoot: HTMLAttributes
+    th: ThHTMLAttributes
+    thead: HTMLAttributes
+    time: TimeHTMLAttributes
+    title: HTMLAttributes
+    tr: HTMLAttributes
+    track: TrackHTMLAttributes
+    u: HTMLAttributes
+    ul: HTMLAttributes
+    var: HTMLAttributes
+    video: VideoHTMLAttributes
+    wbr: HTMLAttributes
   }
 }
 
diff --git a/src/jsx/jsx-dev-runtime.ts b/src/jsx/jsx-dev-runtime.ts
index 7692ca7e0..7ff2bc846 100644
--- a/src/jsx/jsx-dev-runtime.ts
+++ b/src/jsx/jsx-dev-runtime.ts
@@ -2,6 +2,7 @@ import type { HtmlEscapedString } from '../utils/html'
 import { jsxFn } from './base'
 import type { JSXNode } from './base'
 export { Fragment } from './base'
+export type { JSX } from './base'
 
 export function jsxDEV(
   tag: string | Function,
diff --git a/src/jsx/jsx-runtime.test.tsx b/src/jsx/jsx-runtime.test.tsx
index 33cb28f9d..a7ba4af46 100644
--- a/src/jsx/jsx-runtime.test.tsx
+++ b/src/jsx/jsx-runtime.test.tsx
@@ -1,6 +1,5 @@
 /** @jsxRuntime automatic **/
 /** @jsxImportSource . **/
-// @denoify-ignore
 import { Hono } from '../hono'
 
 describe('jsx-runtime', () => {
diff --git a/src/jsx/jsx-runtime.ts b/src/jsx/jsx-runtime.ts
index d75da1697..4633334e6 100644
--- a/src/jsx/jsx-runtime.ts
+++ b/src/jsx/jsx-runtime.ts
@@ -1,5 +1,6 @@
 export { jsxDEV as jsx, Fragment } from './jsx-dev-runtime'
 export { jsxDEV as jsxs } from './jsx-dev-runtime'
+export type { JSX } from './jsx-dev-runtime'
 
 import { raw, html } from '../helper/html'
 import type { HtmlEscapedString } from '../utils/html'
diff --git a/src/jsx/streaming.test.tsx b/src/jsx/streaming.test.tsx
index c5cd55792..f63c5c810 100644
--- a/src/jsx/streaming.test.tsx
+++ b/src/jsx/streaming.test.tsx
@@ -1,10 +1,9 @@
+/** @jsxImportSource ./ */
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import { JSDOM } from 'jsdom'
 import { raw } from '../helper/html'
 import { HtmlEscapedCallbackPhase, resolveCallback } from '../utils/html'
 import type { HtmlEscapedString } from '../utils/html'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment } from './base'
 import { use } from './hooks'
 import { Suspense, renderToReadableStream } from './streaming'
 
diff --git a/src/jsx/streaming.ts b/src/jsx/streaming.ts
index 5df7a3e4e..6a037bb6b 100644
--- a/src/jsx/streaming.ts
+++ b/src/jsx/streaming.ts
@@ -6,7 +6,7 @@ import { DOM_RENDERER, DOM_STASH } from './constants'
 import { Suspense as SuspenseDomRenderer } from './dom/components'
 import { buildDataStack } from './dom/render'
 import type { HasRenderToDom, NodeObject } from './dom/render'
-import type { FC, PropsWithChildren, Child } from '.'
+import type { FC, PropsWithChildren, Child } from './'
 
 let suspenseCounter = 0
 
diff --git a/src/jsx/types.ts b/src/jsx/types.ts
index 85d2c2b9d..552ae6ad6 100644
--- a/src/jsx/types.ts
+++ b/src/jsx/types.ts
@@ -2,6 +2,7 @@
  * All types exported from "hono/jsx" are in this file.
  */
 import type { Child, JSXNode } from './base'
+import type { Hono } from './intrinsic-elements'
 
 export type { Child, JSXNode, FC } from './base'
 export type { RefObject } from './hooks'
diff --git a/src/middleware.ts b/src/middleware.ts
deleted file mode 100644
index c6c7a4c72..000000000
--- a/src/middleware.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// This file is for Deno to import middleware from `hono/middleware.ts`.
-export * from './middleware/basic-auth'
-export * from './middleware/bearer-auth'
-export * from './middleware/body-limit'
-export * from './middleware/cache'
-export * from './middleware/compress'
-export * from './middleware/cors'
-export * from './middleware/csrf'
-export * from './middleware/etag'
-export * from './jsx'
-export * from './middleware/jsx-renderer'
-export { jwt } from './middleware/jwt'
-export * from './middleware/logger'
-export * from './middleware/method-override'
-export * from './middleware/powered-by'
-export * from './middleware/timeout'
-export * from './middleware/timing'
-export * from './middleware/pretty-json'
-export * from './middleware/secure-headers'
-export * from './middleware/trailing-slash'
-export * from './adapter/deno/serve-static'
diff --git a/src/middleware/cache/index.test.ts b/src/middleware/cache/index.test.ts
index a6b065f24..fef482e48 100644
--- a/src/middleware/cache/index.test.ts
+++ b/src/middleware/cache/index.test.ts
@@ -1,3 +1,4 @@
+import type { ExecutionContext } from '../../context'
 import { Hono } from '../../hono'
 import { cache } from '.'
 
diff --git a/src/middleware/jsx-renderer/index.test.tsx b/src/middleware/jsx-renderer/index.test.tsx
index 486676171..17f979999 100644
--- a/src/middleware/jsx-renderer/index.test.tsx
+++ b/src/middleware/jsx-renderer/index.test.tsx
@@ -1,8 +1,7 @@
+/** @jsxImportSource ../../jsx */
 import { expectTypeOf } from 'vitest'
 import { html } from '../../helper/html'
 import { Hono } from '../../hono'
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { jsx, Fragment } from '../../jsx'
 import type { FC } from '../../jsx'
 import { Suspense } from '../../jsx/streaming'
 import { jsxRenderer, useRequestContext } from '.'
diff --git a/src/middleware/jwt/index.ts b/src/middleware/jwt/index.ts
index a18db64ff..ad064d891 100644
--- a/src/middleware/jwt/index.ts
+++ b/src/middleware/jwt/index.ts
@@ -1,133 +1,7 @@
-import type { Context } from '../../context'
-import { getCookie } from '../../helper/cookie'
-import { HTTPException } from '../../http-exception'
-import type { MiddlewareHandler } from '../../types'
-import { Jwt } from '../../utils/jwt'
-import '../../context'
-import type { SignatureAlgorithm } from '../../utils/jwt/jwa'
+import type { JwtVariables } from './jwt'
+export { jwt, verify, decode, sign } from './jwt'
+import type {} from '../..'
 
-declare module '../../context' {
-  interface ContextVariableMap {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    jwtPayload: any
-  }
+declare module '../..' {
+  interface ContextVariableMap extends JwtVariables {}
 }
-
-/**
- * JWT Auth middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/jwt}
- *
- * @param {object} options - The options for the JWT middleware.
- * @param {string} [options.secret] - A value of your secret key.
- * @param {string} [options.cookie] - If this value is set, then the value is retrieved from the cookie header using that value as a key, which is then validated as a token.
- * @param {SignatureAlgorithm} [options.alg=HS256] - An algorithm type that is used for verifying. Available types are `HS256` | `HS384` | `HS512` | `RS256` | `RS384` | `RS512` | `PS256` | `PS384` | `PS512` | `ES256` | `ES384` | `ES512` | `EdDSA`.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * app.use(
- *   '/auth/*',
- *   jwt({
- *     secret: 'it-is-very-secret',
- *   })
- * )
- *
- * app.get('/auth/page', (c) => {
- *   return c.text('You are authorized')
- * })
- * ```
- */
-export const jwt = (options: {
-  secret: string
-  cookie?: string
-  alg?: SignatureAlgorithm
-}): MiddlewareHandler => {
-  if (!options || !options.secret) {
-    throw new Error('JWT auth middleware requires options for "secret')
-  }
-
-  if (!crypto.subtle || !crypto.subtle.importKey) {
-    throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')
-  }
-
-  return async function jwt(ctx, next) {
-    const credentials = ctx.req.raw.headers.get('Authorization')
-    let token
-    if (credentials) {
-      const parts = credentials.split(/\s+/)
-      if (parts.length !== 2) {
-        const errDescription = 'invalid credentials structure'
-        throw new HTTPException(401, {
-          message: errDescription,
-          res: unauthorizedResponse({
-            ctx,
-            error: 'invalid_request',
-            errDescription,
-          }),
-        })
-      } else {
-        token = parts[1]
-      }
-    } else if (options.cookie) {
-      token = getCookie(ctx)[options.cookie]
-    }
-
-    if (!token) {
-      const errDescription = 'no authorization included in request'
-      throw new HTTPException(401, {
-        message: errDescription,
-        res: unauthorizedResponse({
-          ctx,
-          error: 'invalid_request',
-          errDescription,
-        }),
-      })
-    }
-
-    let payload
-    let cause
-    try {
-      payload = await Jwt.verify(token, options.secret, options.alg)
-    } catch (e) {
-      cause = e
-    }
-    if (!payload) {
-      throw new HTTPException(401, {
-        message: 'Unauthorized',
-        res: unauthorizedResponse({
-          ctx,
-          error: 'invalid_token',
-          statusText: 'Unauthorized',
-          errDescription: 'token verification failure',
-        }),
-        cause,
-      })
-    }
-
-    ctx.set('jwtPayload', payload)
-
-    await next()
-  }
-}
-
-function unauthorizedResponse(opts: {
-  ctx: Context
-  error: string
-  errDescription: string
-  statusText?: string
-}) {
-  return new Response('Unauthorized', {
-    status: 401,
-    statusText: opts.statusText,
-    headers: {
-      'WWW-Authenticate': `Bearer realm="${opts.ctx.req.url}",error="${opts.error}",error_description="${opts.errDescription}"`,
-    },
-  })
-}
-
-export const verify = Jwt.verify
-export const decode = Jwt.decode
-export const sign = Jwt.sign
diff --git a/deno_dist/middleware/jwt/index.ts b/src/middleware/jwt/jwt.ts
similarity index 86%
rename from deno_dist/middleware/jwt/index.ts
rename to src/middleware/jwt/jwt.ts
index 9d2fde64a..b303c6d34 100644
--- a/deno_dist/middleware/jwt/index.ts
+++ b/src/middleware/jwt/jwt.ts
@@ -1,16 +1,14 @@
-import type { Context } from '../../context.ts'
-import { getCookie } from '../../helper/cookie/index.ts'
-import { HTTPException } from '../../http-exception.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import { Jwt } from '../../utils/jwt/index.ts'
-import '../../context.ts'
-import type { SignatureAlgorithm } from '../../utils/jwt/jwa.ts'
+import type { Context } from '../../context'
+import { getCookie } from '../../helper/cookie'
+import { HTTPException } from '../../http-exception'
+import type { MiddlewareHandler } from '../../types'
+import { Jwt } from '../../utils/jwt'
+import '../../context'
+import type { SignatureAlgorithm } from '../../utils/jwt/jwa'
 
-declare module '../../context.ts' {
-  interface ContextVariableMap {
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    jwtPayload: any
-  }
+export type JwtVariables = {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  jwtPayload: any
 }
 
 /**
diff --git a/src/middleware/method-override/index.ts b/src/middleware/method-override/index.ts
index 69a0f87c5..eca086504 100644
--- a/src/middleware/method-override/index.ts
+++ b/src/middleware/method-override/index.ts
@@ -1,4 +1,4 @@
-import type { Context } from '../../context'
+import type { Context, ExecutionContext } from '../../context'
 import type { Hono } from '../../hono'
 import type { MiddlewareHandler } from '../../types'
 import { parseBody } from '../../utils/body'
diff --git a/src/middleware/secure-headers/index.test.ts b/src/middleware/secure-headers/index.test.ts
index 195d5282f..3e3e89f9c 100644
--- a/src/middleware/secure-headers/index.test.ts
+++ b/src/middleware/secure-headers/index.test.ts
@@ -4,7 +4,7 @@ import { poweredBy } from '../powered-by'
 import { secureHeaders, NONCE } from '.'
 import type { ContentSecurityPolicyOptionHandler } from '.'
 
-declare module '../../context' {
+declare module '../..' {
   interface ContextVariableMap {
     ['test-scriptSrc-nonce']?: string
     ['test-styleSrc-nonce']?: string
diff --git a/src/middleware/secure-headers/index.ts b/src/middleware/secure-headers/index.ts
index 7a107e6a8..8a2629164 100644
--- a/src/middleware/secure-headers/index.ts
+++ b/src/middleware/secure-headers/index.ts
@@ -1,263 +1,7 @@
-import type { Context } from '../../context'
-import type { MiddlewareHandler } from '../../types'
-import { encodeBase64 } from '../../utils/encode'
+export type { ContentSecurityPolicyOptionHandler } from './secure-headers'
+export { NONCE, secureHeaders } from './secure-headers'
+import type { SecureHeadersVariables } from './secure-headers'
 
-declare module '../../context' {
-  interface ContextVariableMap {
-    secureHeadersNonce?: string
-  }
-}
-
-export type ContentSecurityPolicyOptionHandler = (ctx: Context, directive: string) => string
-type ContentSecurityPolicyOptionValue = (string | ContentSecurityPolicyOptionHandler)[]
-
-interface ContentSecurityPolicyOptions {
-  defaultSrc?: ContentSecurityPolicyOptionValue
-  baseUri?: ContentSecurityPolicyOptionValue
-  childSrc?: ContentSecurityPolicyOptionValue
-  connectSrc?: ContentSecurityPolicyOptionValue
-  fontSrc?: ContentSecurityPolicyOptionValue
-  formAction?: ContentSecurityPolicyOptionValue
-  frameAncestors?: ContentSecurityPolicyOptionValue
-  frameSrc?: ContentSecurityPolicyOptionValue
-  imgSrc?: ContentSecurityPolicyOptionValue
-  manifestSrc?: ContentSecurityPolicyOptionValue
-  mediaSrc?: ContentSecurityPolicyOptionValue
-  objectSrc?: ContentSecurityPolicyOptionValue
-  reportTo?: string
-  sandbox?: ContentSecurityPolicyOptionValue
-  scriptSrc?: ContentSecurityPolicyOptionValue
-  scriptSrcAttr?: ContentSecurityPolicyOptionValue
-  scriptSrcElem?: ContentSecurityPolicyOptionValue
-  styleSrc?: ContentSecurityPolicyOptionValue
-  styleSrcAttr?: ContentSecurityPolicyOptionValue
-  styleSrcElem?: ContentSecurityPolicyOptionValue
-  upgradeInsecureRequests?: ContentSecurityPolicyOptionValue
-  workerSrc?: ContentSecurityPolicyOptionValue
-}
-
-interface ReportToOptions {
-  group: string
-  max_age: number
-  endpoints: ReportToEndpoint[]
-}
-
-interface ReportToEndpoint {
-  url: string
-}
-
-interface ReportingEndpointOptions {
-  name: string
-  url: string
-}
-
-type overridableHeader = boolean | string
-
-interface SecureHeadersOptions {
-  contentSecurityPolicy?: ContentSecurityPolicyOptions
-  crossOriginEmbedderPolicy?: overridableHeader
-  crossOriginResourcePolicy?: overridableHeader
-  crossOriginOpenerPolicy?: overridableHeader
-  originAgentCluster?: overridableHeader
-  referrerPolicy?: overridableHeader
-  reportingEndpoints?: ReportingEndpointOptions[]
-  reportTo?: ReportToOptions[]
-  strictTransportSecurity?: overridableHeader
-  xContentTypeOptions?: overridableHeader
-  xDnsPrefetchControl?: overridableHeader
-  xDownloadOptions?: overridableHeader
-  xFrameOptions?: overridableHeader
-  xPermittedCrossDomainPolicies?: overridableHeader
-  xXssProtection?: overridableHeader
-}
-
-type HeadersMap = {
-  [key in keyof SecureHeadersOptions]: [string, string]
-}
-
-const HEADERS_MAP: HeadersMap = {
-  crossOriginEmbedderPolicy: ['Cross-Origin-Embedder-Policy', 'require-corp'],
-  crossOriginResourcePolicy: ['Cross-Origin-Resource-Policy', 'same-origin'],
-  crossOriginOpenerPolicy: ['Cross-Origin-Opener-Policy', 'same-origin'],
-  originAgentCluster: ['Origin-Agent-Cluster', '?1'],
-  referrerPolicy: ['Referrer-Policy', 'no-referrer'],
-  strictTransportSecurity: ['Strict-Transport-Security', 'max-age=15552000; includeSubDomains'],
-  xContentTypeOptions: ['X-Content-Type-Options', 'nosniff'],
-  xDnsPrefetchControl: ['X-DNS-Prefetch-Control', 'off'],
-  xDownloadOptions: ['X-Download-Options', 'noopen'],
-  xFrameOptions: ['X-Frame-Options', 'SAMEORIGIN'],
-  xPermittedCrossDomainPolicies: ['X-Permitted-Cross-Domain-Policies', 'none'],
-  xXssProtection: ['X-XSS-Protection', '0'],
-}
-
-const DEFAULT_OPTIONS: SecureHeadersOptions = {
-  crossOriginEmbedderPolicy: false,
-  crossOriginResourcePolicy: true,
-  crossOriginOpenerPolicy: true,
-  originAgentCluster: true,
-  referrerPolicy: true,
-  strictTransportSecurity: true,
-  xContentTypeOptions: true,
-  xDnsPrefetchControl: true,
-  xDownloadOptions: true,
-  xFrameOptions: true,
-  xPermittedCrossDomainPolicies: true,
-  xXssProtection: true,
-}
-
-type SecureHeadersCallback = (
-  ctx: Context,
-  headersToSet: [string, string | string[]][]
-) => [string, string][]
-
-const generateNonce = () => {
-  const buffer = new Uint8Array(16)
-  crypto.getRandomValues(buffer)
-  return encodeBase64(buffer)
-}
-
-export const NONCE: ContentSecurityPolicyOptionHandler = (ctx) => {
-  const nonce =
-    ctx.get('secureHeadersNonce') ||
-    (() => {
-      const newNonce = generateNonce()
-      ctx.set('secureHeadersNonce', newNonce)
-      return newNonce
-    })()
-  return `'nonce-${nonce}'`
-}
-
-/**
- * Secure Headers Middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/secure-headers}
- *
- * @param {Partial<SecureHeadersOptions>} [customOptions] - The options for the secure headers middleware.
- * @param {ContentSecurityPolicyOptions} [customOptions.contentSecurityPolicy] - Settings for the Content-Security-Policy header.
- * @param {overridableHeader} [customOptions.crossOriginEmbedderPolicy=false] - Settings for the Cross-Origin-Embedder-Policy header.
- * @param {overridableHeader} [customOptions.crossOriginResourcePolicy=true] - Settings for the Cross-Origin-Resource-Policy header.
- * @param {overridableHeader} [customOptions.crossOriginOpenerPolicy=true] - Settings for the Cross-Origin-Opener-Policy header.
- * @param {overridableHeader} [customOptions.originAgentCluster=true] - Settings for the Origin-Agent-Cluster header.
- * @param {overridableHeader} [customOptions.referrerPolicy=true] - Settings for the Referrer-Policy header.
- * @param {ReportingEndpointOptions[]} [customOptions.reportingEndpoints] - Settings for the Reporting-Endpoints header.
- * @param {ReportToOptions[]} [customOptions.reportTo] - Settings for the Report-To header.
- * @param {overridableHeader} [customOptions.strictTransportSecurity=true] - Settings for the Strict-Transport-Security header.
- * @param {overridableHeader} [customOptions.xContentTypeOptions=true] - Settings for the X-Content-Type-Options header.
- * @param {overridableHeader} [customOptions.xDnsPrefetchControl=true] - Settings for the X-DNS-Prefetch-Control header.
- * @param {overridableHeader} [customOptions.xDownloadOptions=true] - Settings for the X-Download-Options header.
- * @param {overridableHeader} [customOptions.xFrameOptions=true] - Settings for the X-Frame-Options header.
- * @param {overridableHeader} [customOptions.xPermittedCrossDomainPolicies=true] - Settings for the X-Permitted-Cross-Domain-Policies header.
- * @param {overridableHeader} [customOptions.xXssProtection=true] - Settings for the X-XSS-Protection header.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- * app.use(secureHeaders())
- * ```
- */
-export const secureHeaders = (customOptions?: SecureHeadersOptions): MiddlewareHandler => {
-  const options = { ...DEFAULT_OPTIONS, ...customOptions }
-  const headersToSet = getFilteredHeaders(options)
-  const callbacks: SecureHeadersCallback[] = []
-
-  if (options.contentSecurityPolicy) {
-    const [callback, value] = getCSPDirectives(options.contentSecurityPolicy)
-    if (callback) {
-      callbacks.push(callback)
-    }
-    headersToSet.push(['Content-Security-Policy', value as string])
-  }
-
-  if (options.reportingEndpoints) {
-    headersToSet.push(['Reporting-Endpoints', getReportingEndpoints(options.reportingEndpoints)])
-  }
-
-  if (options.reportTo) {
-    headersToSet.push(['Report-To', getReportToOptions(options.reportTo)])
-  }
-
-  return async function secureHeaders(ctx, next) {
-    // should evaluate callbacks before next()
-    // some callback calls ctx.set() for embedding nonce to the page
-    const headersToSetForReq =
-      callbacks.length === 0
-        ? headersToSet
-        : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet)
-    await next()
-    setHeaders(ctx, headersToSetForReq)
-    ctx.res.headers.delete('X-Powered-By')
-  }
-}
-
-function getFilteredHeaders(options: SecureHeadersOptions): [string, string][] {
-  return Object.entries(HEADERS_MAP)
-    .filter(([key]) => options[key as keyof SecureHeadersOptions])
-    .map(([key, defaultValue]) => {
-      const overrideValue = options[key as keyof SecureHeadersOptions]
-      return typeof overrideValue === 'string' ? [defaultValue[0], overrideValue] : defaultValue
-    })
-}
-
-function getCSPDirectives(
-  contentSecurityPolicy: ContentSecurityPolicyOptions
-): [SecureHeadersCallback | undefined, string | string[]] {
-  const callbacks: ((ctx: Context, values: string[]) => void)[] = []
-  const resultValues: string[] = []
-
-  for (const [directive, value] of Object.entries(contentSecurityPolicy)) {
-    const valueArray = Array.isArray(value) ? value : [value]
-
-    valueArray.forEach((value, i) => {
-      if (typeof value === 'function') {
-        const index = i * 2 + 2 + resultValues.length
-        callbacks.push((ctx, values) => {
-          values[index] = value(ctx, directive)
-        })
-      }
-    })
-
-    resultValues.push(
-      directive.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (match, offset) =>
-        offset ? '-' + match.toLowerCase() : match.toLowerCase()
-      ),
-      ...valueArray.flatMap((value) => [' ', value]),
-      '; '
-    )
-  }
-  resultValues.pop()
-
-  return callbacks.length === 0
-    ? [undefined, resultValues.join('')]
-    : [
-        (ctx, headersToSet) =>
-          headersToSet.map((values) => {
-            if (values[0] === 'Content-Security-Policy') {
-              const clone = values[1].slice() as unknown as string[]
-              callbacks.forEach((cb) => {
-                cb(ctx, clone)
-              })
-              return [values[0], clone.join('')]
-            } else {
-              return values as [string, string]
-            }
-          }),
-        resultValues,
-      ]
-}
-
-function getReportingEndpoints(
-  reportingEndpoints: SecureHeadersOptions['reportingEndpoints'] = []
-): string {
-  return reportingEndpoints.map((endpoint) => `${endpoint.name}="${endpoint.url}"`).join(', ')
-}
-
-function getReportToOptions(reportTo: SecureHeadersOptions['reportTo'] = []): string {
-  return reportTo.map((option) => JSON.stringify(option)).join(', ')
-}
-
-function setHeaders(ctx: Context, headersToSet: [string, string][]) {
-  headersToSet.forEach(([header, value]) => {
-    ctx.res.headers.set(header, value)
-  })
+declare module '../..' {
+  interface ContextVariableMap extends SecureHeadersVariables {}
 }
diff --git a/deno_dist/middleware/secure-headers/index.ts b/src/middleware/secure-headers/secure-headers.ts
similarity index 97%
rename from deno_dist/middleware/secure-headers/index.ts
rename to src/middleware/secure-headers/secure-headers.ts
index 367e741df..a701efaac 100644
--- a/deno_dist/middleware/secure-headers/index.ts
+++ b/src/middleware/secure-headers/secure-headers.ts
@@ -1,11 +1,9 @@
-import type { Context } from '../../context.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import { encodeBase64 } from '../../utils/encode.ts'
+import type { Context } from '../../context'
+import type { MiddlewareHandler } from '../../types'
+import { encodeBase64 } from '../../utils/encode'
 
-declare module '../../context.ts' {
-  interface ContextVariableMap {
-    secureHeadersNonce?: string
-  }
+export type SecureHeadersVariables = {
+  secureHeadersNonce?: string
 }
 
 export type ContentSecurityPolicyOptionHandler = (ctx: Context, directive: string) => string
diff --git a/src/middleware/timing/index.ts b/src/middleware/timing/index.ts
index fa76647d3..db3e323e5 100644
--- a/src/middleware/timing/index.ts
+++ b/src/middleware/timing/index.ts
@@ -1,217 +1,6 @@
-import type { Context } from '../../context'
-import type { MiddlewareHandler } from '../../types'
-import '../../context'
+import type { TimingVariables } from './timing'
+export { timing, setMetric, startTime, endTime } from './timing'
 
-declare module '../../context' {
-  interface ContextVariableMap {
-    metric?: {
-      headers: string[]
-      timers: Map<string, Timer>
-    }
-  }
-}
-
-interface Timer {
-  description?: string
-  start: number
-}
-
-interface TimingOptions {
-  total?: boolean
-  enabled?: boolean | ((c: Context) => boolean)
-  totalDescription?: string
-  autoEnd?: boolean
-  crossOrigin?: boolean | string | ((c: Context) => boolean | string)
-}
-
-const getTime = (): number => {
-  try {
-    return performance.now()
-  } catch {}
-  return Date.now()
-}
-
-/**
- * Server-Timing Middleware middleware for Hono.
- *
- * @see {@link https://hono.dev/middleware/builtin/timing}
- *
- * @param {TimingOptions} [config] - The options for the timing middleware.
- * @param {boolean} [config.total=true] - Show the total response time.
- * @param {boolean | ((c: Context) => boolean)} [config.enabled=true] - Whether timings should be added to the headers or not.
- * @param {string} [config.totalDescription=Total Response Time] - Description for the total response time.
- * @param {boolean} [config.autoEnd=true] - If `startTime()` should end automatically at the end of the request.
- * @param {boolean | string | ((c: Context) => boolean | string)} [config.crossOrigin=false] - The origin this timings header should be readable.
- * @returns {MiddlewareHandler} The middleware handler function.
- *
- * @example
- * ```ts
- * const app = new Hono()
- *
- * // add the middleware to your router
- * app.use(timing());
- *
- * app.get('/', async (c) => {
- *   // add custom metrics
- *   setMetric(c, 'region', 'europe-west3')
- *
- *   // add custom metrics with timing, must be in milliseconds
- *   setMetric(c, 'custom', 23.8, 'My custom Metric')
- *
- *   // start a new timer
- *   startTime(c, 'db');
- *
- *   const data = await db.findMany(...);
- *
- *   // end the timer
- *   endTime(c, 'db');
- *
- *   return c.json({ response: data });
- * });
- * ```
- */
-export const timing = (config?: TimingOptions): MiddlewareHandler => {
-  const options: TimingOptions = {
-    ...{
-      total: true,
-      enabled: true,
-      totalDescription: 'Total Response Time',
-      autoEnd: true,
-      crossOrigin: false,
-    },
-    ...config,
-  }
-  return async function timing(c, next) {
-    const headers: string[] = []
-    const timers = new Map<string, Timer>()
-    c.set('metric', { headers, timers })
-
-    if (options.total) {
-      startTime(c, 'total', options.totalDescription)
-    }
-    await next()
-
-    if (options.total) {
-      endTime(c, 'total')
-    }
-
-    if (options.autoEnd) {
-      timers.forEach((_, key) => endTime(c, key))
-    }
-
-    const enabled = typeof options.enabled === 'function' ? options.enabled(c) : options.enabled
-
-    if (enabled) {
-      c.res.headers.append('Server-Timing', headers.join(','))
-
-      const crossOrigin =
-        typeof options.crossOrigin === 'function' ? options.crossOrigin(c) : options.crossOrigin
-
-      if (crossOrigin) {
-        c.res.headers.append(
-          'Timing-Allow-Origin',
-          typeof crossOrigin === 'string' ? crossOrigin : '*'
-        )
-      }
-    }
-  }
-}
-
-interface SetMetric {
-  (c: Context, name: string, value: number, description?: string, precision?: number): void
-
-  (c: Context, name: string, description?: string): void
-}
-
-/**
- * Set a metric for the timing middleware.
- *
- * @param {Context} c - The context of the request.
- * @param {string} name - The name of the metric.
- * @param {number | string} [valueDescription] - The value or description of the metric.
- * @param {string} [description] - The description of the metric.
- * @param {number} [precision] - The precision of the metric value.
- *
- * @example
- * ```ts
- * setMetric(c, 'region', 'europe-west3')
- * setMetric(c, 'custom', 23.8, 'My custom Metric')
- * ```
- */
-export const setMetric: SetMetric = (
-  c: Context,
-  name: string,
-  valueDescription: number | string | undefined,
-  description?: string,
-  precision?: number
-) => {
-  const metrics = c.get('metric')
-  if (!metrics) {
-    console.warn('Metrics not initialized! Please add the `timing()` middleware to this route!')
-    return
-  }
-  if (typeof valueDescription === 'number') {
-    const dur = valueDescription.toFixed(precision || 1)
-
-    const metric = description ? `${name};dur=${dur};desc="${description}"` : `${name};dur=${dur}`
-
-    metrics.headers.push(metric)
-  } else {
-    // Value-less metric
-    const metric = valueDescription ? `${name};desc="${valueDescription}"` : `${name}`
-
-    metrics.headers.push(metric)
-  }
-}
-
-/**
- * Start a timer for the timing middleware.
- *
- * @param {Context} c - The context of the request.
- * @param {string} name - The name of the timer.
- * @param {string} [description] - The description of the timer.
- *
- * @example
- * ```ts
- * startTime(c, 'db')
- * ```
- */
-export const startTime = (c: Context, name: string, description?: string) => {
-  const metrics = c.get('metric')
-  if (!metrics) {
-    console.warn('Metrics not initialized! Please add the `timing()` middleware to this route!')
-    return
-  }
-  metrics.timers.set(name, { description, start: getTime() })
-}
-
-/**
- * End a timer for the timing middleware.
- *
- * @param {Context} c - The context of the request.
- * @param {string} name - The name of the timer.
- * @param {number} [precision] - The precision of the timer value.
- *
- * @example
- * ```ts
- * endTime(c, 'db')
- * ```
- */
-export const endTime = (c: Context, name: string, precision?: number) => {
-  const metrics = c.get('metric')
-  if (!metrics) {
-    console.warn('Metrics not initialized! Please add the `timing()` middleware to this route!')
-    return
-  }
-  const timer = metrics.timers.get(name)
-  if (!timer) {
-    console.warn(`Timer "${name}" does not exist!`)
-    return
-  }
-  const { description, start } = timer
-
-  const duration = getTime() - start
-
-  setMetric(c, name, duration, description, precision)
-  metrics.timers.delete(name)
+declare module '../..' {
+  interface ContextVariableMap extends TimingVariables {}
 }
diff --git a/deno_dist/middleware/timing/index.ts b/src/middleware/timing/timing.ts
similarity index 95%
rename from deno_dist/middleware/timing/index.ts
rename to src/middleware/timing/timing.ts
index 96ddbb7ca..6449bd102 100644
--- a/deno_dist/middleware/timing/index.ts
+++ b/src/middleware/timing/timing.ts
@@ -1,13 +1,11 @@
-import type { Context } from '../../context.ts'
-import type { MiddlewareHandler } from '../../types.ts'
-import '../../context.ts'
-
-declare module '../../context.ts' {
-  interface ContextVariableMap {
-    metric?: {
-      headers: string[]
-      timers: Map<string, Timer>
-    }
+import type { Context } from '../../context'
+import type { MiddlewareHandler } from '../../types'
+import '../../context'
+
+export type TimingVariables = {
+  metric?: {
+    headers: string[]
+    timers: Map<string, Timer>
   }
 }
 
diff --git a/src/mod.ts b/src/mod.ts
deleted file mode 100644
index 23be60d8c..000000000
--- a/src/mod.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Hono } from './hono'
-
-declare global {
-  interface ExecutionContext {
-    waitUntil(promise: Promise<void>): void
-    passThroughOnException(): void
-  }
-}
-
-export type {
-  Env,
-  ErrorHandler,
-  Handler,
-  MiddlewareHandler,
-  Next,
-  NotFoundHandler,
-  ValidationTargets,
-  Input,
-  Schema,
-  ToSchema,
-  TypedResponse,
-} from './types'
-export type { Context, ContextVariableMap, ContextRenderer, ExecutionContext } from './context'
-export type { HonoRequest } from './request'
-export { Hono }
-export { HTTPException } from './http-exception'
-
-// Router
-export { RegExpRouter } from './router/reg-exp-router'
-export { TrieRouter } from './router/trie-router'
-export { SmartRouter } from './router/smart-router'
-export { PatternRouter } from './router/pattern-router'
-export { LinearRouter } from './router/linear-router'
-
-// Validator
-export { validator } from './validator'
-
-// Client
-export { hc } from './client'
-export type { InferRequestType, InferResponseType, ClientRequestOptions } from './client'
diff --git a/src/test-utils/setup-vitest.ts b/src/test-utils/setup-vitest.ts
index b2d2deb5e..d81a61692 100644
--- a/src/test-utils/setup-vitest.ts
+++ b/src/test-utils/setup-vitest.ts
@@ -1,4 +1,3 @@
-// @denoify-ignore
 import * as nodeCrypto from 'node:crypto'
 import { vi } from 'vitest'
 
diff --git a/src/types.test.ts b/src/types.test.ts
index f0c23ecbf..e8856c15f 100644
--- a/src/types.test.ts
+++ b/src/types.test.ts
@@ -2,7 +2,7 @@
 /* eslint-disable @typescript-eslint/no-unused-vars */
 import { expectTypeOf } from 'vitest'
 import type { Context } from './context'
-import { createMiddleware } from './helper'
+import { createMiddleware } from './helper/factory'
 import { Hono } from './hono'
 import { poweredBy } from './middleware/powered-by'
 import type {
diff --git a/src/utils/buffer.ts b/src/utils/buffer.ts
index 6d24f692f..18f039620 100644
--- a/src/utils/buffer.ts
+++ b/src/utils/buffer.ts
@@ -1,6 +1,6 @@
 import { sha256 } from './crypto'
 
-export const equal = (a: ArrayBuffer, b: ArrayBuffer) => {
+export const equal = (a: ArrayBuffer, b: ArrayBuffer): boolean => {
   if (a === b) {
     return true
   }
@@ -25,7 +25,7 @@ export const timingSafeEqual = async (
   a: string | object | boolean,
   b: string | object | boolean,
   hashFunction?: Function
-) => {
+): Promise<boolean> => {
   if (!hashFunction) {
     hashFunction = sha256
   }
diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts
index b763b507c..8fe865cc7 100644
--- a/src/utils/crypto.ts
+++ b/src/utils/crypto.ts
@@ -5,19 +5,19 @@ type Algorithm = {
 
 type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer | ReadableStream
 
-export const sha256 = async (data: Data) => {
+export const sha256 = async (data: Data): Promise<string | null> => {
   const algorithm: Algorithm = { name: 'SHA-256', alias: 'sha256' }
   const hash = await createHash(data, algorithm)
   return hash
 }
 
-export const sha1 = async (data: Data) => {
+export const sha1 = async (data: Data): Promise<string | null> => {
   const algorithm: Algorithm = { name: 'SHA-1', alias: 'sha1' }
   const hash = await createHash(data, algorithm)
   return hash
 }
 
-export const md5 = async (data: Data) => {
+export const md5 = async (data: Data): Promise<string | null> => {
   const algorithm: Algorithm = { name: 'MD5', alias: 'md5' }
   const hash = await createHash(data, algorithm)
   return hash
diff --git a/src/utils/filepath.ts b/src/utils/filepath.ts
index 35c6159f7..85ce9962c 100644
--- a/src/utils/filepath.ts
+++ b/src/utils/filepath.ts
@@ -26,7 +26,7 @@ export const getFilePath = (options: FilePathOptions): string | undefined => {
 
 export const getFilePathWithoutDefaultDocument = (
   options: Omit<FilePathOptions, 'defaultDocument'>
-) => {
+): string | undefined => {
   let root = options.root || ''
   let filename = options.filename
 
diff --git a/vitest.config.ts b/vitest.config.ts
index bb9f07a08..90470c8b3 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -2,6 +2,10 @@
 import { configDefaults, defineConfig } from 'vitest/config'
 
 export default defineConfig({
+  esbuild: {
+    jsx: 'automatic',
+    jsxImportSource: __dirname + '/../src/jsx',
+  },
   test: {
     globals: true,
     include: ['**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
diff --git a/yarn.lock b/yarn.lock
index 29f244bfc..17b7cfcec 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1,6 +1,6 @@
 # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
 # yarn lockfile v1
-# bun ./bun.lockb --hash: B415720B4387FBBC-dbeb2a7922252ada-0D12CCEFAA865A1E-cd52ff612e3f385f
+# bun ./bun.lockb --hash: 5CA1136C3F2F5DB7-1b68ff373acdefeb-7DBBBCD34BFD0EF1-d2b230862a4c1954
 
 
 "@aashutoshrathi/word-wrap@^1.2.3":
@@ -589,107 +589,6 @@
     "@nodelib/fs.scandir" "2.1.5"
     fastq "^1.6.0"
 
-"@octokit/auth-token@^2.4.4":
-  version "2.5.0"
-  resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz"
-  integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==
-  dependencies:
-    "@octokit/types" "^6.0.3"
-
-"@octokit/core@>=2", "@octokit/core@>=3", "@octokit/core@^3.5.1":
-  version "3.6.0"
-  resolved "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz"
-  integrity sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==
-  dependencies:
-    "@octokit/auth-token" "^2.4.4"
-    "@octokit/graphql" "^4.5.8"
-    "@octokit/request" "^5.6.3"
-    "@octokit/request-error" "^2.0.5"
-    "@octokit/types" "^6.0.3"
-    before-after-hook "^2.2.0"
-    universal-user-agent "^6.0.0"
-
-"@octokit/endpoint@^6.0.1":
-  version "6.0.12"
-  resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz"
-  integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==
-  dependencies:
-    "@octokit/types" "^6.0.3"
-    is-plain-object "^5.0.0"
-    universal-user-agent "^6.0.0"
-
-"@octokit/graphql@^4.5.8":
-  version "4.8.0"
-  resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz"
-  integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==
-  dependencies:
-    "@octokit/request" "^5.6.0"
-    "@octokit/types" "^6.0.3"
-    universal-user-agent "^6.0.0"
-
-"@octokit/openapi-types@^12.11.0":
-  version "12.11.0"
-  resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz"
-  integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==
-
-"@octokit/plugin-paginate-rest@^2.16.8":
-  version "2.21.3"
-  resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz"
-  integrity sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==
-  dependencies:
-    "@octokit/types" "^6.40.0"
-
-"@octokit/plugin-request-log@^1.0.4":
-  version "1.0.4"
-  resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz"
-  integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
-
-"@octokit/plugin-rest-endpoint-methods@^5.12.0":
-  version "5.16.2"
-  resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz"
-  integrity sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==
-  dependencies:
-    "@octokit/types" "^6.39.0"
-    deprecation "^2.3.1"
-
-"@octokit/request@^5.6.0", "@octokit/request@^5.6.3":
-  version "5.6.3"
-  resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz"
-  integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==
-  dependencies:
-    "@octokit/endpoint" "^6.0.1"
-    "@octokit/request-error" "^2.1.0"
-    "@octokit/types" "^6.16.1"
-    is-plain-object "^5.0.0"
-    node-fetch "^2.6.7"
-    universal-user-agent "^6.0.0"
-
-"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0":
-  version "2.1.0"
-  resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz"
-  integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==
-  dependencies:
-    "@octokit/types" "^6.0.3"
-    deprecation "^2.0.0"
-    once "^1.4.0"
-
-"@octokit/rest@^18.0.0":
-  version "18.12.0"
-  resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz"
-  integrity sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==
-  dependencies:
-    "@octokit/core" "^3.5.1"
-    "@octokit/plugin-paginate-rest" "^2.16.8"
-    "@octokit/plugin-request-log" "^1.0.4"
-    "@octokit/plugin-rest-endpoint-methods" "^5.12.0"
-
-"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.39.0", "@octokit/types@^6.40.0":
-  version "6.41.0"
-  resolved "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz"
-  integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==
-  dependencies:
-    "@octokit/openapi-types" "^12.11.0"
-
 "@open-draft/until@^1.0.3":
   version "1.0.3"
   resolved "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz"
@@ -816,11 +715,6 @@
     "@types/node" "*"
     "@types/responselike" "^1.0.0"
 
-"@types/comment-json@^1.1.1":
-  version "1.1.1"
-  resolved "https://registry.npmjs.org/@types/comment-json/-/comment-json-1.1.1.tgz"
-  integrity sha512-U70oEqvnkeSSp8BIJwJclERtT13rd9ejK7XkIzMCQQePZe3VW1b7iQggXyW4ZvfGtGeXD0pZw24q5iWNe++HqQ==
-
 "@types/cookie@^0.4.1":
   version "0.4.1"
   resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz"
@@ -1408,11 +1302,6 @@ base64-js@^1.3.1:
   resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
 
-before-after-hook@^2.2.0:
-  version "2.2.3"
-  resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz"
-  integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==
-
 binary-extensions@^2.0.0:
   version "2.2.0"
   resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
@@ -1789,26 +1678,11 @@ commander@^2.20.0:
   resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
-commander@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz"
-  integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
-
 commander@^9.4.1:
   version "9.5.0"
   resolved "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz"
   integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
 
-comment-json@^3.0.2:
-  version "3.0.3"
-  resolved "https://registry.npmjs.org/comment-json/-/comment-json-3.0.3.tgz"
-  integrity sha512-P7XwYkC3qjIK45EAa9c5Y3lR7SMXhJqwFdWg3niAIAcbk3zlpKDdajV8Hyz/Y3sGNn3l+YNMl8A2N/OubSArHg==
-  dependencies:
-    core-util-is "^1.0.2"
-    esprima "^4.0.1"
-    has-own-prop "^2.0.0"
-    repeat-string "^1.6.1"
-
 component-emitter@^1.3.0:
   version "1.3.1"
   resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz"
@@ -1851,12 +1725,7 @@ cookiejar@^2.1.4:
   resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz"
   integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==
 
-core-util-is@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
-  integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
-
-cosmiconfig@^7.0.0, cosmiconfig@^7.0.1:
+cosmiconfig@^7.0.0:
   version "7.1.0"
   resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz"
   integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
@@ -2034,32 +1903,6 @@ delayed-stream@~1.0.0:
   resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
   integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
 
-denoify@^1.6.6:
-  version "1.6.9"
-  resolved "https://registry.npmjs.org/denoify/-/denoify-1.6.9.tgz"
-  integrity sha512-/X5rewN7sCNRNx46b8JDnbohTPT+KK2TBQBlnsOktPyny5Zy70iwLvFNToPJ183vVFNBe91NeF9aCRTLZDiqsQ==
-  dependencies:
-    "@octokit/rest" "^18.0.0"
-    "@types/comment-json" "^1.1.1"
-    commander "^4.1.1"
-    comment-json "^3.0.2"
-    cosmiconfig "^7.0.1"
-    evt "2.5.7"
-    get-github-default-branch-name "^1.0.0"
-    gitignore-parser "0.0.2"
-    glob "^7.1.6"
-    minimal-polyfills "^2.2.3"
-    node-fetch "^2.6.7"
-    path-depth "^1.0.0"
-    scripting-tools "^0.19.14"
-    tsafe "^1.6.6"
-    url-join "^4.0.1"
-
-deprecation@^2.0.0, deprecation@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz"
-  integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
-
 dezalgo@^1.0.4:
   version "1.0.4"
   resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz"
@@ -2597,11 +2440,6 @@ espree@^9.6.0, espree@^9.6.1:
     acorn-jsx "^5.3.2"
     eslint-visitor-keys "^3.4.1"
 
-esprima@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
-  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-
 esquery@^1.4.2:
   version "1.5.0"
   resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz"
@@ -2643,15 +2481,6 @@ events@^3.3.0:
   resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
   integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
 
-evt@2.5.7:
-  version "2.5.7"
-  resolved "https://registry.npmjs.org/evt/-/evt-2.5.7.tgz"
-  integrity sha512-dr7Wd16ry5F8WNU1xXLKpFpO3HsoAGg8zC48e08vDdzMzGWCP9/QFGt1PQptEEDh8SwYP3EL8M+d/Gb0kgUp6g==
-  dependencies:
-    minimal-polyfills "^2.2.3"
-    run-exclusive "^2.2.19"
-    tsafe "^1.6.6"
-
 execa@^5.0.0:
   version "5.1.1"
   resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
@@ -2881,14 +2710,6 @@ get-func-name@^2.0.1, get-func-name@^2.0.2:
   resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz"
   integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
 
-get-github-default-branch-name@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/get-github-default-branch-name/-/get-github-default-branch-name-1.0.0.tgz"
-  integrity sha512-BqOokYoLjPIgkehneFPUZW9nNtU0LCXVMJ87YKaHGMWgCSZkTBHWGa76xsyVeXg+nQzRJBi9KDwQbTH3HLntwQ==
-  dependencies:
-    "@octokit/rest" "^18.0.0"
-    scripting-tools "^0.19.12"
-
 get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2:
   version "1.2.2"
   resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz"
@@ -2951,12 +2772,7 @@ github-url-from-git@^1.5.0:
   resolved "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz"
   integrity sha512-WWOec4aRI7YAykQ9+BHmzjyNlkfJFG8QLXnDTsLz/kZefq7qkzdfo4p6fkYYMIq1aj+gZcQs/1HQhQh3DPPxlQ==
 
-gitignore-parser@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.npmjs.org/gitignore-parser/-/gitignore-parser-0.0.2.tgz"
-  integrity sha512-X6mpqUv59uWLGD4n3hZ8Cu8KbF2PMWPSFYmxZjdkpm3yOU7hSUYnzTkZI1mcWqchphvqyuz3/BhgBR4E/JtkCg==
-
-glob@7.2.3, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@7.2.3, glob@^7.1.3, glob@^7.1.4:
   version "7.2.3"
   resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
   integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -3125,11 +2941,6 @@ has-flag@^4.0.0:
   resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-has-own-prop@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz"
-  integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==
-
 has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz"
@@ -3604,11 +3415,6 @@ is-plain-obj@^1.1.0:
   resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz"
   integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
 
-is-plain-object@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz"
-  integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
-
 is-potential-custom-element-name@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz"
@@ -4210,11 +4016,6 @@ miniflare@3.20231030.1:
     youch "^3.2.2"
     zod "^3.20.6"
 
-minimal-polyfills@^2.2.3:
-  version "2.2.3"
-  resolved "https://registry.npmjs.org/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz"
-  integrity sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==
-
 minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
   version "3.1.2"
   resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
@@ -4811,11 +4612,6 @@ parse5@^7.0.0, parse5@^7.1.2:
   dependencies:
     entities "^4.4.0"
 
-path-depth@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/path-depth/-/path-depth-1.0.0.tgz"
-  integrity sha512-dEiwdXAQyLvOi6ktLqhFhjVelJiVsdp2xBX3BaUtYCCkMRZTwUiq7cha+A0myvAVXRHbXfjhfTf4mNoAWzm2iA==
-
 path-exists@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
@@ -5105,11 +4901,6 @@ regjsparser@^0.9.1:
   dependencies:
     jsesc "~0.5.0"
 
-repeat-string@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
-  integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
-
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
@@ -5261,13 +5052,6 @@ run-async@^2.2.0, run-async@^2.4.0:
   resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
   integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
 
-run-exclusive@^2.2.19:
-  version "2.2.19"
-  resolved "https://registry.npmjs.org/run-exclusive/-/run-exclusive-2.2.19.tgz"
-  integrity sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==
-  dependencies:
-    minimal-polyfills "^2.2.3"
-
 run-parallel@^1.1.9:
   version "1.2.0"
   resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
@@ -5337,11 +5121,6 @@ scoped-regex@^2.0.0:
   resolved "https://registry.npmjs.org/scoped-regex/-/scoped-regex-2.1.0.tgz"
   integrity sha512-g3WxHrqSWCZHGHlSrF51VXFdjImhwvH8ZO/pryFH56Qi0cDsZfylQa/t0jCzVQFNbNvM00HfHjkDPEuarKDSWQ==
 
-scripting-tools@^0.19.12, scripting-tools@^0.19.14:
-  version "0.19.14"
-  resolved "https://registry.npmjs.org/scripting-tools/-/scripting-tools-0.19.14.tgz"
-  integrity sha512-KGRES70dEmcaCdpx3R88bLWmfA4mQ/EGikCQy0FGTZwx3y9F5yYkzEhwp02+ZTgpvF25JcNOhDBbOqL6z92kwg==
-
 selfsigned@^2.0.1:
   version "2.4.1"
   resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz"
@@ -5866,11 +5645,6 @@ ts-api-utils@^1.0.1:
   resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz"
   integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==
 
-tsafe@^1.6.6:
-  version "1.6.6"
-  resolved "https://registry.npmjs.org/tsafe/-/tsafe-1.6.6.tgz"
-  integrity sha512-gzkapsdbMNwBnTIjgO758GujLCj031IgHK/PKr2mrmkCSJMhSOR5FeOuSxKLMUoYc0vAA4RGEYYbjt/v6afD3g==
-
 tsconfig-paths@^3.15.0:
   version "3.15.0"
   resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz"
@@ -6061,11 +5835,6 @@ unique-string@^2.0.0:
   dependencies:
     crypto-random-string "^2.0.0"
 
-universal-user-agent@^6.0.0:
-  version "6.0.1"
-  resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz"
-  integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==
-
 universalify@^0.2.0:
   version "0.2.0"
   resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz"
@@ -6098,11 +5867,6 @@ uri-js@^4.2.2:
   dependencies:
     punycode "^2.1.0"
 
-url-join@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz"
-  integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==
-
 url-parse@^1.5.3:
   version "1.5.10"
   resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz"