What version of Hono are you using?
4.7.x
What runtime/platform is your app running on? (with version if possible)
Next.js 15 (App Router), Node.js 20+
What steps can reproduce the bug?
- Create a Next.js 15 project with App Router.
- Install Hono:
pnpm add hono.
- Create a catch-all route handler at
app/api/[[...route]]/route.ts:
// app/api/[[...route]]/route.ts
import { Hono } from "hono";
import { handle } from "hono/vercel";
const app = new Hono().basePath("/api");
app.get("/hello", (c) => c.json({ message: "Hello, World!" }));
export const GET = handle(app);
export const POST = handle(app);
export const PUT = handle(app);
export const PATCH = handle(app);
export const DELETE = handle(app);
export const OPTIONS = handle(app);
- Run
tsc --noEmit in the Next.js project root.
TypeScript reports the following errors for every exported method:
app/api/[[...route]]/route.ts:8:14
error TS2344: Type '{ __tag__: "GET"; __param_position__: "first"; __param_type__: Hono<BlankEnv, BlankSchema, "/">; }' does not satisfy the constraint 'ParamCheck<NextRequest | Request>'.
Types of property '__param_type__' are incompatible.
Type 'Hono<BlankEnv, BlankSchema, "/">' is not assignable to type 'NextRequest | Request'.
error TS2344: Type '{ __tag__: "GET"; __return_type__: (req: Request) => Response | Promise<Response>; }' does not satisfy the constraint '{ __tag__: "GET"; __return_type__: Response | void | never | Promise<Response | void | never>; }'.
Types of property '__return_type__' are incompatible.
Type '(req: Request) => Response | Promise<Response>' is not assignable to type 'Response | void | never | Promise<Response | void | never>'.
The same pair of errors is emitted for POST, PUT, PATCH, DELETE, and OPTIONS.
What is the expected behavior?
tsc --noEmit should pass without errors. Assigning handle(app) to a Next.js 15 App Router route export should be type-safe without requiring any type assertions or suppression comments.
What do you see instead?
Two categories of type errors are produced for every HTTP method export:
1. Return type mismatch
handle() is typed as returning (req: Request) => Response | Promise<Response>.
Next.js 15's generated route constraint (__return_type__) expects Response | void | Promise<Response | void>. Because the void union member is absent from Hono's return type, TypeScript rejects the assignment.
2. First parameter type mismatch
Next.js 15 validates the first parameter type via a ParamCheck constraint and expects NextRequest | Request. Hono's handle() only declares Request, which fails the constraint.
The underlying handle implementation in hono/vercel:
var handle = (app) => (req) => {
return app.fetch(req);
};
works correctly at runtime — the type errors are purely a TypeScript-level incompatibility introduced by the stricter route handler type constraints added in Next.js 15.
Workaround
Cast the result of handle() to suppress the errors:
import type { NextRequest } from "next/server";
type NextHandler = (
req: NextRequest | Request,
ctx?: unknown
) => Response | Promise<Response>;
export const GET = handle(app) as unknown as NextHandler;
Or use // @ts-ignore on each export line.
Neither option is acceptable as a long-term solution since they lose type safety entirely.
Additional information
No response
What version of Hono are you using?
4.7.x
What runtime/platform is your app running on? (with version if possible)
Next.js 15 (App Router), Node.js 20+
What steps can reproduce the bug?
pnpm add hono.app/api/[[...route]]/route.ts:tsc --noEmitin the Next.js project root.TypeScript reports the following errors for every exported method:
The same pair of errors is emitted for POST, PUT, PATCH, DELETE, and OPTIONS.
What is the expected behavior?
tsc --noEmitshould pass without errors. Assigninghandle(app)to a Next.js 15 App Router route export should be type-safe without requiring any type assertions or suppression comments.What do you see instead?
Two categories of type errors are produced for every HTTP method export:
1. Return type mismatch
handle()is typed as returning(req: Request) => Response | Promise<Response>.Next.js 15's generated route constraint (
__return_type__) expectsResponse | void | Promise<Response | void>. Because thevoidunion member is absent from Hono's return type, TypeScript rejects the assignment.2. First parameter type mismatch
Next.js 15 validates the first parameter type via a
ParamCheckconstraint and expectsNextRequest | Request. Hono'shandle()only declaresRequest, which fails the constraint.The underlying
handleimplementation inhono/vercel:works correctly at runtime — the type errors are purely a TypeScript-level incompatibility introduced by the stricter route handler type constraints added in Next.js 15.
Workaround
Cast the result of
handle()to suppress the errors:Or use
// @ts-ignoreon each export line.Neither option is acceptable as a long-term solution since they lose type safety entirely.
Additional information
No response