{"owner":"h3js","repo":"h3","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"<!-- NOTE: Keep this file updated as the project evolves. When making architectural changes, adding new patterns, or discovering important conventions, update the relevant sections. -->\n\n# H3 - Agent Guide\n\nH3 (pronounced /eɪtʃθriː/) is a minimal HTTP framework built for high performance and portability. Currently on **v2** — a major rewrite based on **web standard primitives** (Request, Response, URL, Headers).\n\n## Quick Reference\n\n```bash\n# Setup\ncorepack enable && pnpm install\n\n# Development\npnpm dev                    # vitest watch mode\npnpm vitest run <path>      # run specific test\npnpm test                   # full suite (lint + typecheck + coverage)\npnpm build                  # build with obuild\npnpm lint                   # oxlint + oxfmt --check (lint + typecheck)\npnpm fmt                    # automd + oxlint --fix + oxfmt\npnpm bench:node             # node benchmarks\npnpm bench:bun              # bun benchmarks\n```\n\n## Architecture\n\n### Core Design\n\n- **Web standards first**: Built on native `Request`, `Response`, `URL`, `Headers`\n- **Multi-runtime**: Node.js, Bun, Deno, Cloudflare Workers, Service Workers, browsers\n- **Minimal core**: 2 production deps (`rou3` for routing, `srvx` for server abstraction)\n- **Handler-based**: Composable handlers + middleware, no class-heavy patterns\n- **Type-safe**: Strict TypeScript with generic inference throughout\n\n### Key Classes\n\n| Class          | File              | Purpose                                                                           |\n| -------------- | ----------------- | --------------------------------------------------------------------------------- |\n| `H3`           | `src/h3.ts`       | Main app class (extends `H3Core`), adds routing methods (get/post/put/delete/...) |\n| `H3Event`      | `src/event.ts`    | Request wrapper — wraps web `Request` with lazy properties (URL, context)         |\n| `HTTPError`    | `src/error.ts`    | Structured HTTP error with status, data, headers                                  |\n| `HTTPResponse` | `src/response.ts` | Flexible response builder                                                         |\n\n### Request Flow\n\n1. Request enters via platform adapter (`src/_entries/*.ts`)\n2. `H3.fetch()` creates `H3Event` from `Request`\n3. Global `onRequest` hooks run\n4. Middleware chain executes (matched by route/method)\n5. Route handler processes request, returns a value\n6. `toResponse()` converts return value → `Response` (auto-handles JSON, streams, blobs, primitives)\n7. Global `onResponse` hooks run\n\n## Project Structure\n\n```\nsrc/\n├── index.ts              # Public API exports\n├── h3.ts                 # H3Core + H3 classes\n├── event.ts              # H3Event\n├── handler.ts            # defineHandler, defineValidatedHandler, etc.\n├── middleware.ts          # Middleware system\n├── response.ts           # toResponse, HTTPResponse\n├── error.ts              # HTTPError\n├── adapters.ts           # Web/Node handler adapters\n├── tracing.ts            # Tracing plugin (separate entry point)\n├── types/                # Type definitions\n│   ├── h3.ts             # App types (H3Config, H3Plugin, H3Route, HTTPMethod)\n│   ├── handler.ts        # Handler types (EventHandler, Middleware)\n│   ├── context.ts        # H3EventContext\n│   └── _utils.ts         # Internal type helpers\n├── utils/                # ~30 utility modules (public API)\n│   ├── request.ts        # getQuery, getRouterParams, getRequestURL, ...\n│   ├── response.ts       # redirect, noContent, html, iterable, ...\n│   ├── body.ts           # readBody, readValidatedBody, assertBodySize\n│   ├── cookie.ts         # getCookie, setCookie, parseCookies, chunked cookies\n│   ├── session.ts        # getSession, useSession, sealSession, ...\n│   ├── auth.ts           # requireBasicAuth, basicAuth\n│   ├── cors.ts           # handleCors, appendCorsHeaders, ...\n│   ├── proxy.ts          # proxy, proxyRequest, fetchWithEvent\n│   ├── ws.ts             # defineWebSocketHandler, defineWebSocket\n│   ├── json-rpc.ts       # defineJsonRpcHandler, defineJsonRpcWebSocketHandler\n│   ├── event-stream.ts   # createEventStream (SSE)\n│   ├── static.ts         # serveStatic\n│   ├── cache.ts          # handleCacheHeaders\n│   ├── middleware.ts      # onRequest, onResponse, onError, bodyLimit\n│   ├── route.ts          # defineRoute\n│   ├── base.ts           # withBase\n│   └── internal/         # Internal helpers (not exported)\n│       ├── auth.ts, body.ts, cors.ts, encoding.ts, ...\n│       ├── iron-crypto.ts    # Session sealing crypto\n│       ├── standard-schema.ts # Standard schema validation\n│       └── validate.ts\n├── _entries/             # Platform-specific entry points\n│   ├── generic.ts        # Web Worker / Browser\n│   ├── node.ts           # Node.js (adds toNodeHandler)\n│   ├── bun.ts            # Bun\n│   ├── deno.ts           # Deno\n│   ├── cloudflare.ts     # Cloudflare Workers\n│   ├── service-worker.ts # Service Workers\n│   └── _common.ts        # Shared entry utilities\n└── _deprecated.ts        # Deprecated exports (v1 compat)\n\ntest/\n├── _setup.ts             # Test infrastructure (describeMatrix, setupWebTest, setupNodeTest)\n├── *.test.ts             # ~30 integration test files\n├── unit/                 # Unit tests (including type tests: types.test-d.ts)\n├── bench/                # Benchmarks (mitata)\n└── fixture/              # Runtime-specific playground fixtures\n```\n\n## Code Conventions\n\n### Style\n\n- **ESM only** — no CommonJS\n- **Explicit `.ts` extensions** in all import paths\n- **No barrel files** — import directly from specific modules\n- **Internal files** use `_` prefix (e.g., `_deprecated.ts`, `_entries/`, `_utils.ts`)\n- **Internal helpers** go at the end of files or in `utils/internal/`\n- **Short files** — aim for < 200 LoC per file, split when larger\n- **Options object** as second param for multi-arg functions\n- Formatting: `oxfmt` (no config, uses defaults)\n- Linting: `oxlint` with `unicorn`, `typescript`, `oxc` plugins\n\n### Naming\n\n- `k` prefix for symbol constants (`kNotFound`, `kHandled`)\n- `~` prefix for private/non-enumerable properties\n- `#` for truly private class fields\n- `define*()` for factory functions (`defineHandler`, `defineMiddleware`, `defineWebSocketHandler`)\n- `to*()` for conversion functions (`toResponse`, `toEventHandler`, `toWebHandler`)\n- `from*()` for adapter functions (`fromWebHandler`, `fromNodeHandler`)\n\n### TypeScript\n\n- Strict mode + `isolatedDeclarations` + `verbatimModuleSyntax`\n- `erasableSyntaxOnly: true` (no enums, no namespaces)\n- Target/module: `ESNext` / `NodeNext`\n- Lib: `[\"ESNext\", \"WebWorker\", \"DOM\", \"DOM.Iterable\"]`\n- Heavy use of generics for type inference in handlers\n\n### Response Handling\n\nHandlers return values directly — no `res.send()` pattern:\n\n- Return `string` → text response\n- Return `object` → JSON response\n- Return `Response` / `HTTPResponse` → direct response\n- Return `ReadableStream` / `Blob` / `File` → streamed response\n- Return `kNotFound` symbol → 404\n- Return `kHandled` symbol → already handled (SSE, WebSocket, etc.)\n\n## Testing\n\n### Framework\n\n- **Vitest** v4+ with **v8** coverage\n- Matrix testing: every test runs in both `web` and `node` modes\n\n### Writing Tests\n\n```typescript\nimport { describeMatrix } from \"./_setup.ts\";\n\ndescribeMatrix(\"feature name\", (ctx, { it, expect }) => {\n  it(\"does something\", async () => {\n    ctx.app.get(\"/test\", () => \"hello\");\n    const res = await ctx.fetch(\"/test\");\n    expect(await res.text()).toBe(\"hello\");\n  });\n});\n```\n\nKey patterns:\n\n- Use `describeMatrix` for cross-runtime tests\n- `ctx.app` is a fresh `H3` instance per test (via `beforeEach`)\n- `ctx.fetch` handles URL resolution for both web/node\n- `ctx.errors` tracks unhandled errors (auto-asserted in `afterEach`)\n- Use `it.skipIf(ctx.target === \"node\")` for runtime-specific skips\n\n### Running Tests\n\n```bash\npnpm vitest run test/body.test.ts        # single file\npnpm vitest run test/unit/               # unit tests\npnpm dev                                 # watch mode (all)\npnpm test                                # full: lint + typecheck + coverage\n```\n\n### Bug Fix Workflow\n\n1. Write regression test that reproduces the bug\n2. Confirm test **fails** before any code changes\n3. Fix the implementation (minimal change)\n4. Confirm test **passes**\n5. Run broader test suite for regressions\n\n## Build\n\n- **obuild** with Rolldown bundler\n- 6 platform entries + `tracing.ts` as separate entry\n- Code splitting enabled (`h3-[hash].mjs` chunks)\n- Custom plugin strips comments (preserves `#/@` annotations)\n- Output: `dist/_entries/*.mjs` + `dist/*.d.mts`\n\n### Package Exports\n\n```\nh3           → auto-resolved by runtime (deno/bun/workerd/node/default)\nh3/node      → Node.js runtime (adds toNodeHandler)\nh3/bun       → Bun runtime\nh3/deno      → Deno runtime\nh3/cloudflare → Cloudflare Workers\nh3/service-worker → Service Workers\nh3/generic   → Universal web standard\nh3/tracing   → Tracing plugin\n```\n\n## Dependencies\n\n| Dep       | Purpose                                   |\n| --------- | ----------------------------------------- |\n| `rou3`    | Route matching engine                     |\n| `srvx`    | Server abstraction (multi-runtime)        |\n| `crossws` | WebSocket abstraction (optional peer dep) |\n\n## Best Practices for Contributing\n\n- Prefer web standard APIs over runtime-specific ones\n- Keep the core minimal — add utilities, not core complexity\n- Test across runtimes using `describeMatrix`\n- Return values from handlers instead of mutating responses\n- Use `defineHandler`/`defineMiddleware` for type safety\n"},"files":{"AGENTS.md":"<!-- NOTE: Keep this file updated as the project evolves. When making architectural changes, adding new patterns, or discovering important conventions, update the relevant sections. -->\n\n# H3 - Agent Guide\n\nH3 (pronounced /eɪtʃθriː/) is a minimal HTTP framework built for high performance and portability. Currently on **v2** — a major rewrite based on **web standard primitives** (Request, Response, URL, Headers).\n\n## Quick Reference\n\n```bash\n# Setup\ncorepack enable && pnpm install\n\n# Development\npnpm dev                    # vitest watch mode\npnpm vitest run <path>      # run specific test\npnpm test                   # full suite (lint + typecheck + coverage)\npnpm build                  # build with obuild\npnpm lint                   # oxlint + oxfmt --check (lint + typecheck)\npnpm fmt                    # automd + oxlint --fix + oxfmt\npnpm bench:node             # node benchmarks\npnpm bench:bun              # bun benchmarks\n```\n\n## Architecture\n\n### Core Design\n\n- **Web standards first**: Built on native `Request`, `Response`, `URL`, `Headers`\n- **Multi-runtime**: Node.js, Bun, Deno, Cloudflare Workers, Service Workers, browsers\n- **Minimal core**: 2 production deps (`rou3` for routing, `srvx` for server abstraction)\n- **Handler-based**: Composable handlers + middleware, no class-heavy patterns\n- **Type-safe**: Strict TypeScript with generic inference throughout\n\n### Key Classes\n\n| Class          | File              | Purpose                                                                           |\n| -------------- | ----------------- | --------------------------------------------------------------------------------- |\n| `H3`           | `src/h3.ts`       | Main app class (extends `H3Core`), adds routing methods (get/post/put/delete/...) |\n| `H3Event`      | `src/event.ts`    | Request wrapper — wraps web `Request` with lazy properties (URL, context)         |\n| `HTTPError`    | `src/error.ts`    | Structured HTTP error with status, data, headers                                  |\n| `HTTPResponse` | `src/response.ts` | Flexible response builder                                                         |\n\n### Request Flow\n\n1. Request enters via platform adapter (`src/_entries/*.ts`)\n2. `H3.fetch()` creates `H3Event` from `Request`\n3. Global `onRequest` hooks run\n4. Middleware chain executes (matched by route/method)\n5. Route handler processes request, returns a value\n6. `toResponse()` converts return value → `Response` (auto-handles JSON, streams, blobs, primitives)\n7. Global `onResponse` hooks run\n\n## Project Structure\n\n```\nsrc/\n├── index.ts              # Public API exports\n├── h3.ts                 # H3Core + H3 classes\n├── event.ts              # H3Event\n├── handler.ts            # defineHandler, defineValidatedHandler, etc.\n├── middleware.ts          # Middleware system\n├── response.ts           # toResponse, HTTPResponse\n├── error.ts              # HTTPError\n├── adapters.ts           # Web/Node handler adapters\n├── tracing.ts            # Tracing plugin (separate entry point)\n├── types/                # Type definitions\n│   ├── h3.ts             # App types (H3Config, H3Plugin, H3Route, HTTPMethod)\n│   ├── handler.ts        # Handler types (EventHandler, Middleware)\n│   ├── context.ts        # H3EventContext\n│   └── _utils.ts         # Internal type helpers\n├── utils/                # ~30 utility modules (public API)\n│   ├── request.ts        # getQuery, getRouterParams, getRequestURL, ...\n│   ├── response.ts       # redirect, noContent, html, iterable, ...\n│   ├── body.ts           # readBody, readValidatedBody, assertBodySize\n│   ├── cookie.ts         # getCookie, setCookie, parseCookies, chunked cookies\n│   ├── session.ts        # getSession, useSession, sealSession, ...\n│   ├── auth.ts           # requireBasicAuth, basicAuth\n│   ├── cors.ts           # handleCors, appendCorsHeaders, ...\n│   ├── proxy.ts          # proxy, proxyRequest, fetchWithEvent\n│   ├── ws.ts             # defineWebSocketHandler, defineWebSocket\n│   ├── json-rpc.ts       # defineJsonRpcHandler, defineJsonRpcWebSocketHandler\n│   ├── event-stream.ts   # createEventStream (SSE)\n│   ├── static.ts         # serveStatic\n│   ├── cache.ts          # handleCacheHeaders\n│   ├── middleware.ts      # onRequest, onResponse, onError, bodyLimit\n│   ├── route.ts          # defineRoute\n│   ├── base.ts           # withBase\n│   └── internal/         # Internal helpers (not exported)\n│       ├── auth.ts, body.ts, cors.ts, encoding.ts, ...\n│       ├── iron-crypto.ts    # Session sealing crypto\n│       ├── standard-schema.ts # Standard schema validation\n│       └── validate.ts\n├── _entries/             # Platform-specific entry points\n│   ├── generic.ts        # Web Worker / Browser\n│   ├── node.ts           # Node.js (adds toNodeHandler)\n│   ├── bun.ts            # Bun\n│   ├── deno.ts           # Deno\n│   ├── cloudflare.ts     # Cloudflare Workers\n│   ├── service-worker.ts # Service Workers\n│   └── _common.ts        # Shared entry utilities\n└── _deprecated.ts        # Deprecated exports (v1 compat)\n\ntest/\n├── _setup.ts             # Test infrastructure (describeMatrix, setupWebTest, setupNodeTest)\n├── *.test.ts             # ~30 integration test files\n├── unit/                 # Unit tests (including type tests: types.test-d.ts)\n├── bench/                # Benchmarks (mitata)\n└── fixture/              # Runtime-specific playground fixtures\n```\n\n## Code Conventions\n\n### Style\n\n- **ESM only** — no CommonJS\n- **Explicit `.ts` extensions** in all import paths\n- **No barrel files** — import directly from specific modules\n- **Internal files** use `_` prefix (e.g., `_deprecated.ts`, `_entries/`, `_utils.ts`)\n- **Internal helpers** go at the end of files or in `utils/internal/`\n- **Short files** — aim for < 200 LoC per file, split when larger\n- **Options object** as second param for multi-arg functions\n- Formatting: `oxfmt` (no config, uses defaults)\n- Linting: `oxlint` with `unicorn`, `typescript`, `oxc` plugins\n\n### Naming\n\n- `k` prefix for symbol constants (`kNotFound`, `kHandled`)\n- `~` prefix for private/non-enumerable properties\n- `#` for truly private class fields\n- `define*()` for factory functions (`defineHandler`, `defineMiddleware`, `defineWebSocketHandler`)\n- `to*()` for conversion functions (`toResponse`, `toEventHandler`, `toWebHandler`)\n- `from*()` for adapter functions (`fromWebHandler`, `fromNodeHandler`)\n\n### TypeScript\n\n- Strict mode + `isolatedDeclarations` + `verbatimModuleSyntax`\n- `erasableSyntaxOnly: true` (no enums, no namespaces)\n- Target/module: `ESNext` / `NodeNext`\n- Lib: `[\"ESNext\", \"WebWorker\", \"DOM\", \"DOM.Iterable\"]`\n- Heavy use of generics for type inference in handlers\n\n### Response Handling\n\nHandlers return values directly — no `res.send()` pattern:\n\n- Return `string` → text response\n- Return `object` → JSON response\n- Return `Response` / `HTTPResponse` → direct response\n- Return `ReadableStream` / `Blob` / `File` → streamed response\n- Return `kNotFound` symbol → 404\n- Return `kHandled` symbol → already handled (SSE, WebSocket, etc.)\n\n## Testing\n\n### Framework\n\n- **Vitest** v4+ with **v8** coverage\n- Matrix testing: every test runs in both `web` and `node` modes\n\n### Writing Tests\n\n```typescript\nimport { describeMatrix } from \"./_setup.ts\";\n\ndescribeMatrix(\"feature name\", (ctx, { it, expect }) => {\n  it(\"does something\", async () => {\n    ctx.app.get(\"/test\", () => \"hello\");\n    const res = await ctx.fetch(\"/test\");\n    expect(await res.text()).toBe(\"hello\");\n  });\n});\n```\n\nKey patterns:\n\n- Use `describeMatrix` for cross-runtime tests\n- `ctx.app` is a fresh `H3` instance per test (via `beforeEach`)\n- `ctx.fetch` handles URL resolution for both web/node\n- `ctx.errors` tracks unhandled errors (auto-asserted in `afterEach`)\n- Use `it.skipIf(ctx.target === \"node\")` for runtime-specific skips\n\n### Running Tests\n\n```bash\npnpm vitest run test/body.test.ts        # single file\npnpm vitest run test/unit/               # unit tests\npnpm dev                                 # watch mode (all)\npnpm test                                # full: lint + typecheck + coverage\n```\n\n### Bug Fix Workflow\n\n1. Write regression test that reproduces the bug\n2. Confirm test **fails** before any code changes\n3. Fix the implementation (minimal change)\n4. Confirm test **passes**\n5. Run broader test suite for regressions\n\n## Build\n\n- **obuild** with Rolldown bundler\n- 6 platform entries + `tracing.ts` as separate entry\n- Code splitting enabled (`h3-[hash].mjs` chunks)\n- Custom plugin strips comments (preserves `#/@` annotations)\n- Output: `dist/_entries/*.mjs` + `dist/*.d.mts`\n\n### Package Exports\n\n```\nh3           → auto-resolved by runtime (deno/bun/workerd/node/default)\nh3/node      → Node.js runtime (adds toNodeHandler)\nh3/bun       → Bun runtime\nh3/deno      → Deno runtime\nh3/cloudflare → Cloudflare Workers\nh3/service-worker → Service Workers\nh3/generic   → Universal web standard\nh3/tracing   → Tracing plugin\n```\n\n## Dependencies\n\n| Dep       | Purpose                                   |\n| --------- | ----------------------------------------- |\n| `rou3`    | Route matching engine                     |\n| `srvx`    | Server abstraction (multi-runtime)        |\n| `crossws` | WebSocket abstraction (optional peer dep) |\n\n## Best Practices for Contributing\n\n- Prefer web standard APIs over runtime-specific ones\n- Keep the core minimal — add utilities, not core complexity\n- Test across runtimes using `describeMatrix`\n- Return values from handlers instead of mutating responses\n- Use `defineHandler`/`defineMiddleware` for type safety\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"<!-- NOTE: Keep this file updated as the project evolves. When making architectural changes, adding new patterns, or discovering important conventions, update the relevant sections. -->\n\n# H3 - Agent Guide\n\nH3 (pronounced /eɪtʃθriː/) is a minimal HTTP framework built for high performance and portability. Currently on **v2** — a major rewrite based on **web standard primitives** (Request, Response, URL, Headers).\n\n## Quick Reference\n\n```bash\n# Setup\ncorepack enable && pnpm install\n\n# Development\npnpm dev                    # vitest watch mode\npnpm vitest run <path>      # run specific test\npnpm test                   # full suite (lint + typecheck + coverage)\npnpm build                  # build with obuild\npnpm lint                   # oxlint + oxfmt --check (lint + typecheck)\npnpm fmt                    # automd + oxlint --fix + oxfmt\npnpm bench:node             # node benchmarks\npnpm bench:bun              # bun benchmarks\n```\n\n## Architecture\n\n### Core Design\n\n- **Web standards first**: Built on native `Request`, `Response`, `URL`, `Headers`\n- **Multi-runtime**: Node.js, Bun, Deno, Cloudflare Workers, Service Workers, browsers\n- **Minimal core**: 2 production deps (`rou3` for routing, `srvx` for server abstraction)\n- **Handler-based**: Composable handlers + middleware, no class-heavy patterns\n- **Type-safe**: Strict TypeScript with generic inference throughout\n\n### Key Classes\n\n| Class          | File              | Purpose                                                                           |\n| -------------- | ----------------- | --------------------------------------------------------------------------------- |\n| `H3`           | `src/h3.ts`       | Main app class (extends `H3Core`), adds routing methods (get/post/put/delete/...) |\n| `H3Event`      | `src/event.ts`    | Request wrapper — wraps web `Request` with lazy properties (URL, context)         |\n| `HTTPError`    | `src/error.ts`    | Structured HTTP error with status, data, headers                                  |\n| `HTTPResponse` | `src/response.ts` | Flexible response builder                                                         |\n\n### Request Flow\n\n1. Request enters via platform adapter (`src/_entries/*.ts`)\n2. `H3.fetch()` creates `H3Event` from `Request`\n3. Global `onRequest` hooks run\n4. Middleware chain executes (matched by route/method)\n5. Route handler processes request, returns a value\n6. `toResponse()` converts return value → `Response` (auto-handles JSON, streams, blobs, primitives)\n7. Global `onResponse` hooks run\n\n## Project Structure\n\n```\nsrc/\n├── index.ts              # Public API exports\n├── h3.ts                 # H3Core + H3 classes\n├── event.ts              # H3Event\n├── handler.ts            # defineHandler, defineValidatedHandler, etc.\n├── middleware.ts          # Middleware system\n├── response.ts           # toResponse, HTTPResponse\n├── error.ts              # HTTPError\n├── adapters.ts           # Web/Node handler adapters\n├── tracing.ts            # Tracing plugin (separate entry point)\n├── types/                # Type definitions\n│   ├── h3.ts             # App types (H3Config, H3Plugin, H3Route, HTTPMethod)\n│   ├── handler.ts        # Handler types (EventHandler, Middleware)\n│   ├── context.ts        # H3EventContext\n│   └── _utils.ts         # Internal type helpers\n├── utils/                # ~30 utility modules (public API)\n│   ├── request.ts        # getQuery, getRouterParams, getRequestURL, ...\n│   ├── response.ts       # redirect, noContent, html, iterable, ...\n│   ├── body.ts           # readBody, readValidatedBody, assertBodySize\n│   ├── cookie.ts         # getCookie, setCookie, parseCookies, chunked cookies\n│   ├── session.ts        # getSession, useSession, sealSession, ...\n│   ├── auth.ts           # requireBasicAuth, basicAuth\n│   ├── cors.ts           # handleCors, appendCorsHeaders, ...\n│   ├── proxy.ts          # proxy, proxyRequest, fetchWithEvent\n│   ├── ws.ts             # defineWebSocketHandler, defineWebSocket\n│   ├── json-rpc.ts       # defineJsonRpcHandler, defineJsonRpcWebSocketHandler\n│   ├── event-stream.ts   # createEventStream (SSE)\n│   ├── static.ts         # serveStatic\n│   ├── cache.ts          # handleCacheHeaders\n│   ├── middleware.ts      # onRequest, onResponse, onError, bodyLimit\n│   ├── route.ts          # defineRoute\n│   ├── base.ts           # withBase\n│   └── internal/         # Internal helpers (not exported)\n│       ├── auth.ts, body.ts, cors.ts, encoding.ts, ...\n│       ├── iron-crypto.ts    # Session sealing crypto\n│       ├── standard-schema.ts # Standard schema validation\n│       └── validate.ts\n├── _entries/             # Platform-specific entry points\n│   ├── generic.ts        # Web Worker / Browser\n│   ├── node.ts           # Node.js (adds toNodeHandler)\n│   ├── bun.ts            # Bun\n│   ├── deno.ts           # Deno\n│   ├── cloudflare.ts     # Cloudflare Workers\n│   ├── service-worker.ts # Service Workers\n│   └── _common.ts        # Shared entry utilities\n└── _deprecated.ts        # Deprecated exports (v1 compat)\n\ntest/\n├── _setup.ts             # Test infrastructure (describeMatrix, setupWebTest, setupNodeTest)\n├── *.test.ts             # ~30 integration test files\n├── unit/                 # Unit tests (including type tests: types.test-d.ts)\n├── bench/                # Benchmarks (mitata)\n└── fixture/              # Runtime-specific playground fixtures\n```\n\n## Code Conventions\n\n### Style\n\n- **ESM only** — no CommonJS\n- **Explicit `.ts` extensions** in all import paths\n- **No barrel files** — import directly from specific modules\n- **Internal files** use `_` prefix (e.g., `_deprecated.ts`, `_entries/`, `_utils.ts`)\n- **Internal helpers** go at the end of files or in `utils/internal/`\n- **Short files** — aim for < 200 LoC per file, split when larger\n- **Options object** as second param for multi-arg functions\n- Formatting: `oxfmt` (no config, uses defaults)\n- Linting: `oxlint` with `unicorn`, `typescript`, `oxc` plugins\n\n### Naming\n\n- `k` prefix for symbol constants (`kNotFound`, `kHandled`)\n- `~` prefix for private/non-enumerable properties\n- `#` for truly private class fields\n- `define*()` for factory functions (`defineHandler`, `defineMiddleware`, `defineWebSocketHandler`)\n- `to*()` for conversion functions (`toResponse`, `toEventHandler`, `toWebHandler`)\n- `from*()` for adapter functions (`fromWebHandler`, `fromNodeHandler`)\n\n### TypeScript\n\n- Strict mode + `isolatedDeclarations` + `verbatimModuleSyntax`\n- `erasableSyntaxOnly: true` (no enums, no namespaces)\n- Target/module: `ESNext` / `NodeNext`\n- Lib: `[\"ESNext\", \"WebWorker\", \"DOM\", \"DOM.Iterable\"]`\n- Heavy use of generics for type inference in handlers\n\n### Response Handling\n\nHandlers return values directly — no `res.send()` pattern:\n\n- Return `string` → text response\n- Return `object` → JSON response\n- Return `Response` / `HTTPResponse` → direct response\n- Return `ReadableStream` / `Blob` / `File` → streamed response\n- Return `kNotFound` symbol → 404\n- Return `kHandled` symbol → already handled (SSE, WebSocket, etc.)\n\n## Testing\n\n### Framework\n\n- **Vitest** v4+ with **v8** coverage\n- Matrix testing: every test runs in both `web` and `node` modes\n\n### Writing Tests\n\n```typescript\nimport { describeMatrix } from \"./_setup.ts\";\n\ndescribeMatrix(\"feature name\", (ctx, { it, expect }) => {\n  it(\"does something\", async () => {\n    ctx.app.get(\"/test\", () => \"hello\");\n    const res = await ctx.fetch(\"/test\");\n    expect(await res.text()).toBe(\"hello\");\n  });\n});\n```\n\nKey patterns:\n\n- Use `describeMatrix` for cross-runtime tests\n- `ctx.app` is a fresh `H3` instance per test (via `beforeEach`)\n- `ctx.fetch` handles URL resolution for both web/node\n- `ctx.errors` tracks unhandled errors (auto-asserted in `afterEach`)\n- Use `it.skipIf(ctx.target === \"node\")` for runtime-specific skips\n\n### Running Tests\n\n```bash\npnpm vitest run test/body.test.ts        # single file\npnpm vitest run test/unit/               # unit tests\npnpm dev                                 # watch mode (all)\npnpm test                                # full: lint + typecheck + coverage\n```\n\n### Bug Fix Workflow\n\n1. Write regression test that reproduces the bug\n2. Confirm test **fails** before any code changes\n3. Fix the implementation (minimal change)\n4. Confirm test **passes**\n5. Run broader test suite for regressions\n\n## Build\n\n- **obuild** with Rolldown bundler\n- 6 platform entries + `tracing.ts` as separate entry\n- Code splitting enabled (`h3-[hash].mjs` chunks)\n- Custom plugin strips comments (preserves `#/@` annotations)\n- Output: `dist/_entries/*.mjs` + `dist/*.d.mts`\n\n### Package Exports\n\n```\nh3           → auto-resolved by runtime (deno/bun/workerd/node/default)\nh3/node      → Node.js runtime (adds toNodeHandler)\nh3/bun       → Bun runtime\nh3/deno      → Deno runtime\nh3/cloudflare → Cloudflare Workers\nh3/service-worker → Service Workers\nh3/generic   → Universal web standard\nh3/tracing   → Tracing plugin\n```\n\n## Dependencies\n\n| Dep       | Purpose                                   |\n| --------- | ----------------------------------------- |\n| `rou3`    | Route matching engine                     |\n| `srvx`    | Server abstraction (multi-runtime)        |\n| `crossws` | WebSocket abstraction (optional peer dep) |\n\n## Best Practices for Contributing\n\n- Prefer web standard APIs over runtime-specific ones\n- Keep the core minimal — add utilities, not core complexity\n- Test across runtimes using `describeMatrix`\n- Return values from handlers instead of mutating responses\n- Use `defineHandler`/`defineMiddleware` for type safety\n","category":"root","tokens":2392}]}