
Cursor plugin for Hono v4 (TypeScript edge web framework). 59 LLM regressions with BAD/CORRECT pairs. Pinned to hono ^4.12.19 (>= 4.9.7 for CVE-2025-59139). Covers Express middleware leakage, v3-era removed APIs, RPC inference traps, Cloudflare Workers gotchas, security defaults, JSX SSR hardening.
Cursor plugin for Hono v4 (TypeScript edge web framework) + TypeScript. Pinned to hono ^4.12.19, @hono/zod-validator ^0.8.0, @hono/zod-openapi ^1.4.0 (peer zod ^4.x), @hono/node-server ^2.0.3 (Node 20+). Teaches the v4 APIs that LLMs trained on pre-2024 data do not know (c.json() always typed, validator throws HTTPException, getCookie/setCookie from hono/cookie, as property, from , from , from , from , Workers Static Assets binding instead of deprecated , JSR for Deno). Catches 50+ LLM regressions with BAD / CORRECT TypeScript pairs.
c.envstreamTexthono/streamingshowRouteshono/devgetRuntimeKeyhono/adapterfire(app)hono/service-workerserveStatic@hono/honoNo Hono v5 exists. Latest stable is v4.12.19. Any "v5" in generated code is hallucination.
Hono's own maintainers filed Issue #3906 ("llm.txt file") and Issue #4812 ("Official AI Agent Skill for Hono") explicitly because "LLMs have basically no knowledge of how the latest Hono works." Pre-2025 training data is v3-era. LLMs emit:
c.jsonT() instead of c.json() (always typed since v4.0.0)c.stream() / c.streamText() as Context methods (moved to hono/streaming in v4)c.env() function form (now property; runtime detection via getRuntimeKey() from hono/adapter)c.req.cookie() (removed; use getCookie(c) from hono/cookie)app.showRoutes(), app.routerName (moved to hono/dev)addEventListener('fetch') + app.handleEvent() (Service Worker syntax; use export default { fetch: app.fetch })app.head(...) routes (HEAD auto-derived from GET in v4)hono/nextjs import (use hono/vercel)hono/middleware barrel import (use per-middleware subpath)c.req.headers() / c.req.body() / c.req.signal() accessor methods (use c.req.raw.*)FC with implicit children (use PropsWithChildren<P>)app.fire() (deprecated v4.8.0; use fire(app) from hono/service-worker)import { Hono } from 'https://deno.land/x/hono/mod.ts' on Deno (stale since v4.4.0; use jsr:@hono/hono)return on c.json() (resolves to undefined; v4 throws "Context is not finalized")res.json() / res.send() instead of c.json() (no res in Hono)(req, res, next) middleware signature (use (c, next))(err, req, res, next) error middleware (use app.onError + HTTPException)app.use(express.json()) body parser (Hono parses on demand via c.req.json())import cors from 'cors' from npm (use hono/cors)supertest for tests (use app.request() / testClient(app))c.req.body as already parsed (it's a ReadableStream)c.req.parseBody() for JSON (only form / multipart)c.req.text() then c.req.json() (body consumed twice)c.userId = ... inline assignment (use c.set('userId', ...) with typed Variables)new Hono() without Bindings / Variables generics (c.env is {})app.get(...) then app.post(...)) - drops RPC typesapp.route() calls as statements - same ruleContext around (loses path-param inference, per Hono Best Practices)app.use('/path', zValidator(...)) instead of as route arg (TS error: 'json' not assignable to 'never')c.notFound() in RPC-consumed routes (cannot type on client)new Response(JSON.stringify(...)) in RPC routes (client sees unknown)hc<AppType>('/') relative URL (throws on $url())drizzle-orm, fs, native deps - the #1 RPC bundle-bloat pitfall)createMiddleware<Env> (Variables types do not propagate)process.env.X in Workers code (undefined; use c.env.X with typed Bindings)fs / path imports in Workers (no filesystem)compatibility_flags: ["node_compat"] legacy flag (use nodejs_compat)serveStatic from hono/cloudflare-workers (since v4.3.0; use asset binding)c.executionCtx.waitUntil() for fire-and-forgetif (c.executionCtx) (getter throws on Bun and Next.js App Router).run() / .first() / .all() (insert cancelled when worker terminates)secureHeaders() middlewarecsrf() on cookie-authenticated mutationscors({ origin: '*', credentials: true }) (browsers silently drop; AJAX fails)bodyLimit() on POST / PUT routes and pin hono >= 4.9.7 for CVE-2025-59139httpOnly / secure / sameSite / pathsameSite: 'None' without secure: true (silently dropped)etag() / cache() on static GETsstreamText (Workers 128MB cap)notFound handler (dead code; only top-level fires)/users vs /users/ are different routes by default)await next() more than once (doubles downstream work)app.use(prefix, mw) + app.route(prefix, subApp) overlap (middleware fires twice)app.basePath('/api') as statement (prefix is thrown away from the type)serve(app) on @hono/node-server (use serve({ fetch: app.fetch }))export default app on Workers (use export default { fetch: app.fetch })Bun.serve({ fetch: app }) (use app.fetch)c.req.query() with no arg when expecting single valuec.req.param('id') in global middleware (undefined where :id isn't in path)@hono/zod-openapicors() mounted AFTER routes (never matches)A handful of Hono rules already live on cursor.directory and in awesome-cursorrules (PR #152): they cover c.json() returns, zValidator + Zod, c.env for Workers, chained routes for RPC, and app.fetch Workers export. They have three structural problems this plugin fixes:
c.jsonT, c.stream, c.env(), c.req.cookie, app.showRoutes, the hono/middleware barrel, and app.handleEvent - all removed in v4.0.0 (2024-02). Existing rules silently allow them.(req, res, next), (err, req, res, next), npm cors, app.use(express.json()), supertest, missing return on c.json - all happen constantly in LLM-generated Hono code. Existing rules treat them as one-offs.secureHeaders() / csrf(); none mention bodyLimit CVE-2025-59139 (fix in v4.9.7); none address RPC client pitfalls (relative URL, value-import leakage, c.notFound typing).This plugin ships:
globs so the routes / RPC checks fire on src/routes/**, Workers checks on wrangler.{toml,jsonc} + Worker entry, security checks on middleware files, etc./hono-new-route, /hono-rpc-setup, /hono-cloudflare-workers-setup, /hono-migrate-to-v4, /hono-validatecorrect-sample (gold-standard Hono 4.12.19 + Workers + D1 + Drizzle + Zod) and anti-pattern-sample (Hono v3 hangover with 25+ tracked violations)Copy the rules, skills, and agent into your project's Cursor configuration. Back up your existing files first; cp -r will overwrite same-named rules.
git clone https://github.com/RoninForge/roninforge-hono.git
# Use -n to avoid clobbering an existing customised rule of the same name.
cp -rn roninforge-hono/rules/* your-project/.cursor/rules/
cp -rn roninforge-hono/skills/* your-project/.cursor/skills/
cp -rn roninforge-hono/agents/* your-project/.cursor/agents/
Or vendor the whole repo as a git submodule under your-project/.cursor/plugins/. Refer to the Cursor plugin docs for the current global-install path on your Cursor version.
| Rule | Scope (globs) | What it does |
|---|---|---|
hono-anti-patterns | **/*.ts,**/*.js,**/*.tsx,**/*.jsx,wrangler.{toml,jsonc,json} | 59 LLM regressions with BAD / CORRECT pairs, organized A-H by category (Express leakage, v3-era APIs, TypeScript / RPC, CF Workers, security, routing, runtime, smaller issues) |
hono-core | **/*.ts,**/*.tsx,**/*.js,**/*.jsx (alwaysApply) | App init with typed Bindings + Variables, Context API, request accessors, middleware signature, built-in middleware list, cookie helpers, runtime detection |
hono-routing-and-rpc | src/**/*.ts,src/routes/**/*,src/api/**/*,src/server/**/*,src/client/**/*,routes/**/* | Chained routes, sub-app composition, basePath immutability, double-execution overlap fix, sub-app notFound dead code, hc<AppType> setup, import type rule, typed base URL, $path(), TanStack Query / SWR integration, factory.createHandlers, RPC at 30+ routes mitigation |
hono-validators | src/**/*.ts,routes/**/*.ts,api/**/*.ts,handlers/**/*.ts | @hono/zod-validator placement, c.req.valid() accessor, validator-throws-on-failure, @hono/zod-openapi (zod ^4 peer gotcha), @hono/standard-validator, @hono/valibot-validator, built-in hono/validator, decision tree |
hono-cloudflare-workers | src/**/*.ts,worker/**/*.ts,workers/**/*.ts,wrangler.{toml,jsonc,json},**/cloudflare-env.d.ts,**/worker-configuration.d.ts | wrangler.jsonc canonical shape, compatibility flag rules, wrangler types, typed Bindings, c.env vs process.env, c.executionCtx.waitUntil + portability, Static Assets binding, D1 awaits, Drizzle + D1 stack, Hyperdrive + Prisma adapter gotcha, Durable Objects for WebSockets, hono/cache custom-domain rule, ES Module Worker export |
hono-security | src/**/*.ts,src/**/*.tsx,src/middleware/**/*.ts,src/auth/**/*.ts,src/index.ts,src/app.ts | secureHeaders(), , CORS allow-list, + CVE-2025-59139 pin floor 4.9.7, cookie defaults, JWT secret from c.env, logging without PII leaks, + , IP restriction, timeouts, request ID, auth library decision (Lucia deprecated; Better Auth / Clerk recommended), over |
| Skill | Command | What it does |
|---|---|---|
| New route | /hono-new-route | Scaffold a chained sub-app with zValidator as route argument, c.req.valid() typed access, c.json({ ... } as const, status) for typed RPC responses, Bindings + Variables generics, sub-app exported as typeof users, wired into parent with chained .route(). Refuses Rails-style controllers, c.notFound() in RPC routes, raw new Response(). |
| RPC setup | /hono-rpc-setup | Scaffold the hc<AppType> client with import type (the load-bearing rule), absolute base URL, typed shared api module, TanStack Query / SWR integration via InferRequestType / InferResponseType, parseResponse utility, $path() method, IDE-slowdown mitigations for 30+ routes. |
| Workers setup | /hono-cloudflare-workers-setup | Scaffold a fresh Hono + Workers project with wrangler.jsonc (NOT .toml), nodejs_compat, typed Bindings generated from wrangler types, D1 + Drizzle middleware pattern, secureHeaders + cors + csrf + bodyLimit stack, Vitest config for @cloudflare/vitest-pool-workers. |
| Migrate to v4 | /hono-migrate-to-v4 | Stage-by-stage v3 -> v4 migration: bump pins (CVE-2025-59139 floor), replace c.jsonT / c.stream / c.env() / c.req.cookie / app.showRoutes / app.handleEvent, drop hono/middleware barrel, switch Deno to JSR, @hono/node-server v2 + Node 20+, register app.onError for validator throws. |
| Validate | /hono-validate | Run + + tests + grep audit for syntactic anti-patterns the type checker won't catch (, , , , from , hard-coded JWT secret, without , missing , value-import on client). |
| Agent | What it does |
|---|---|
hono-reviewer | Reviews Hono v4 + TypeScript code by severity. CRITICAL: hono < 4.9.7 (CVE), v5 references (hallucination), cors wildcard + credentials, sameSite:'None' without secure, hard-coded JWT secret, process.env in Workers, missing bodyLimit, no csrf on cookie-auth, deprecated serveStatic, JSX SSR on < 4.12.18. ERROR: missing return on c.json, Express middleware shapes, all v3-era removed APIs, unchained routes / sub-apps, Rails controllers, zValidator placement, c.notFound/raw Response in RPC, relative URL hc(), value-import server app, unawaited D1, runtime export shapes. WARN: cookie defaults, secureHeaders, body-logging without redaction, app.onError, sub-app notFound, c.executionCtx truthy-check, no Bindings generic, cors after routes, middleware overlap, basePath statement, trailing slashes, hono/middleware barrel, wrangler.toml on greenfield, Lucia, @hono/sentry. NIT: missing satisfies ExportedHandler<Env>, hand-rolled OpenAPI, missing observability.enabled. |
tests/fixtures/correct-sample/ is a slim Hono 4.12.19 + Cloudflare Workers + D1 + Drizzle + Zod project demonstrating the gold-standard shape: chained routes, typed RPC, zValidator as route arg, c.json({ ... } as const, status) typed responses, secureHeaders + cors + csrf + bodyLimit stack, app.onError + app.notFound at top-level, export default { fetch: app.fetch } satisfies ExportedHandler<Env>.
tests/fixtures/anti-pattern-sample/ is the inverse. Every file violates a numbered anti-pattern. package.json pins hono ^3.12.0 + cors ^2.8.5 + supertest ^6.3.0 + @hono/sentry ^1.0.0 + lucia ^3.2.0 on purpose - the v3 era is the LLM-training-data baseline for most pre-2025 models, plus deprecated companions that LLMs still recommend. Tracked violations include: missing return on c.json (#1), (req, res) Express handler shape (#2), (req, res, next) middleware (#3), (err, req, res, next) (#4), npm cors (#6), supertest (#12), c.jsonT (#13), addEventListener('fetch') + app.handleEvent (#15), c.req.cookie (#16), c.env() function call (#17), hono/middleware barrel (#20), app.head() (#23), no Bindings/Variables (#24), c.notFound in RPC route (#29), process.env in Workers (#34), node_compat flag (#36), serveStatic from hono/cloudflare-workers (#37), unawaited D1 (#40), cors * + credentials (#43), cookie without httpOnly/secure/sameSite/path (#45), sameSite:'None' without secure:true (#46), hard-coded JWT secret (#48), sub-app notFound (#50), basePath as statement (#53), export default app on Workers (#55), deprecated @hono/sentry + lucia references.
Rules target hono ^4.12.19 with Node 20+ (when on Node), Bun latest, Deno latest, Wrangler ^4.0.0. Most patterns work back to Hono 4.0.0 (Feb 2024) with the deltas called out inline. Pin floors:
hono >= 4.9.7 mandatory - CVE-2025-59139 / GHSA-92vj-g62v-jqhh bodyLimit bypass fixhono >= 4.12.18 mandatory if rendering JSX SSR - tag-name, attribute-name, CSS-injection hardening@hono/node-server >= 2.0.0 requires Node 20+@hono/zod-openapi >= 1.0.0 requires zod ^4.0.0 (peer is ^4.0.0 ONLY, not ^3.x)compatibility_date >= "2024-09-23" required for nodejs_compat to imply nodejs_compat_v2Where the rule cites a version (c.json() always typed since v4.0.0, c.text() typed since v4.3.0, JSR for Deno since v4.4.0, secureHeaders Permissions-Policy since v4.6.0, Standard Schema validator since v4.7.0, fire(app) since v4.8.0, JSR parseResponse since v4.9.0, typed base URL on hc since v4.11.0, $path() method since v4.12.0), verify against the changelog for the version you have installed before adopting.
MIT - see LICENSE
RoninForge builds free tools for developers working with AI coding assistants:
csrf()bodyLimit()etag()cache()@sentry/hono@hono/sentryhono-error-handling | src/**/*.ts,routes/**/*.ts,api/**/*.ts,middleware/**/*.ts,src/index.ts,src/app.ts | HTTPException canonical throw, app.onError global handler, app.notFound top-level only, typed RPC errors via discriminated unions, validator throws, Sentry via @sentry/hono, structured logging with pino redaction, error response shape convention |
hono-jsx | **/*.tsx,**/*.jsx,**/jsx-runtime.ts,src/components/**/*,src/views/**/*,src/islands/**/*,app/islands/**/* | hono/jsx server-side, tsconfig setup, FC does NOT include children, jsxRenderer middleware for layouts, hono/jsx/streaming with Suspense, hono/jsx/dom client components, HonoX islands, htmx integration, JSX SSR security pin floor 4.12.18 |
hono-testing | **/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,vitest.config.{ts,js},**/test/**/*.ts,**/tests/**/*.ts,**/__tests__/**/*.ts | app.request() universal pattern, testClient(app) typed RPC tests, Vitest + @cloudflare/vitest-pool-workers for real-runtime D1, applyD1Migrations fixture, Bun + bun:test, snapshot testing, middleware / validator / waitUntil testing, NEVER supertest |
hono-deployment | wrangler.{toml,jsonc,json},deno.json,deno.jsonc,package.json,Dockerfile,fly.toml,vercel.json,netlify.toml,**/serverless.yml,**/template.yaml | Cloudflare Workers (wrangler.jsonc + compatibility flags), Bun.serve, Deno + JSR, @hono/node-server v2 (Node 20+), AWS Lambda + Lambda@Edge, Vercel Edge, Netlify, build pipelines, pin floors, common deployment mistakes |
validate-plugin.shtsc --noEmitc.jsonTc.req.cookieprocess.envnode_compatserveStatichono/cloudflare-workerssameSite:'None'securebodyLimithc