api-framework-hono-303e49 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited api-framework-hono-303e49 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Quick Guide: Use Hono with@hono/zod-openapifor type-safe REST APIs that auto-generate OpenAPI specs. Importzfrom@hono/zod-openapi(NOT fromzod) so.openapi()is available on all schemas. Always includeoperationIdin routes and export theappinstance for spec generation.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST import `z` from `@hono/zod-openapi`, NOT from `zod` -- this gives Zod the `.openapi()` method)
(You MUST export the `app` instance for OpenAPI spec generation)
(You MUST include `operationId` in every route for clean client generation)
</critical_requirements>
Auto-detection: Hono, @hono/zod-openapi, OpenAPIHono, createRoute, Zod schemas with .openapi(), app.route(), createMiddleware, rate limiting, CORS configuration, health checks, hc client, RPC mode, getContext, tryGetContext, contextStorage, some/every/except middleware
When to use:
When NOT to use:
Key patterns covered:
app.route() and OpenAPIHono.openapi() metadatacreateRoute (operationId, tags, responses)hc) with end-to-end type safetysome/every/except) for declarative authDetailed Resources:
<philosophy>
Type safety + documentation from code. Zod schemas serve both validation AND OpenAPI spec generation. Single source of truth flows to clients via generated SDKs or Hono's RPC client.
Use Hono + OpenAPI when: Building public/multi-client APIs, need auto-generated documentation, require formal OpenAPI specs, want type-safe validation.
Use simpler approaches when: Internal-only CRUD, no external API consumers, no documentation needs.
</philosophy>
<patterns>
Structure routes using app.route() for modularization. Export the app instance for spec generation.
import { OpenAPIHono } from "@hono/zod-openapi";
const app = new OpenAPIHono().basePath("/api");
app.route("/", jobsRoutes);
app.route("/", companiesRoutes);
// REQUIRED: Export app for spec generation
export { app };Why good: app.route() prevents God files, app export enables build-time spec generation
See examples/core.md for complete setup with framework adapter exports.
Import z from @hono/zod-openapi (not zod). Use .openapi() for schema registration and documentation.
import { z } from "@hono/zod-openapi";
const MIN_SALARY = 0;
const CURRENCY_CODE_LENGTH = 3;
export const SalarySchema = z
.object({
min: z.number().min(MIN_SALARY),
max: z.number().min(MIN_SALARY),
currency: z.string().length(CURRENCY_CODE_LENGTH),
})
.openapi("Salary", {
example: { min: 60000, max: 90000, currency: "EUR" },
});Why good: importing z from @hono/zod-openapi provides .openapi() automatically, named constants prevent magic number bugs, .openapi("Name") registers as #/components/schemas/Name
See examples/validation.md for complete schema patterns.
Define routes with createRoute and implement with app.openapi(). Always include operationId.
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
const getJobsRoute = createRoute({
method: "get",
path: "/jobs",
operationId: "getJobs", // Becomes client method name
tags: ["Jobs"],
request: { query: JobsQuerySchema },
responses: {
200: {
description: "List of jobs",
content: { "application/json": { schema: JobsResponseSchema } },
},
},
});
app.openapi(getJobsRoute, async (c) => {
const { country } = c.req.valid("query"); // Type-safe validated params
// ... handler logic
return c.json({ jobs: results }, 200);
});Why good: operationId becomes clean client method name (getJobs vs get_api_jobs), c.req.valid() enforces schema validation with types
See examples/core.md for list/detail endpoint examples.
Use named error code constants for consistent, machine-parseable error responses.
export const ErrorCodes = {
VALIDATION_ERROR: "validation_error",
NOT_FOUND: "not_found",
UNAUTHORIZED: "unauthorized",
INTERNAL_ERROR: "internal_error",
} as const;Why good: Named codes enable frontend switch handling, consistent shape across all endpoints
See examples/error-handling.md for the full handleRouteError utility.
Always specify the alg option on JWT/JWK middleware to prevent algorithm confusion attacks (CVE-2026-22817, CVE-2026-22818, patched in v4.11.4+).
import { verify } from "hono/jwt";
const JWT_ALGORITHM = "HS256";
const payload = await verify(token, secret, JWT_ALGORITHM);Why good: explicit algorithm prevents attackers from switching to symmetric verification with known public keys
See examples/middleware.md for complete auth middleware with type-safe variables.
</patterns>
<red_flags>
High Priority:
z from "zod" instead of "@hono/zod-openapi" -- .openapi() won't be availableoperationId in routes -- generated client has ugly method namesapp instance -- can't generate OpenAPI spec at build timealg option -- algorithm confusion vulnerability (CVE-2026-22817/22818)Medium Priority:
c.req.param() / c.req.query() instead of c.req.valid() -- bypasses Zod validation"*") with credentials: true -- browsers reject this (spec violation)Gotchas & Edge Cases:
c.req.valid("param") uses singular "param", not "params" -- easy to mistype.openapi(r1, h1).openapi(r2, h2)) for type inference -- separate calls break ittsconfig.json need "strict": true for RPC type inferencecontextStorage() middleware must be registered before any code calls getContext()tryGetContext() (v4.11.0+) in code that may run outside request context (tests, background jobs)next() never throws in Hono -- wrapping await next() in try/catch is unnecessarygetConnInfo is adapter-specific -- import from hono/bun, hono/deno, @hono/node-server/conninfo, etc. (NOT from hono/ip-restriction)</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST import `z` from `@hono/zod-openapi`, NOT from `zod` -- this gives Zod the `.openapi()` method)
(You MUST export the `app` instance for OpenAPI spec generation)
(You MUST include `operationId` in every route for clean client generation)
Failure to follow these rules will break OpenAPI spec generation and type safety.
</critical_reminders>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.