next-safe-route is a utility library for Next.js that provides type-safety and schema validation for Route Handlers/API Routes. It is compatible with Next.js 15+ (including 16) route handler signatures.
- ✅ Schema Validation: Automatically validate request parameters, query strings, and body content with built-in JSON error responses.
- 🧷 Type-Safe: Work with full TypeScript type safety for parameters, query strings, and body content, including transformation results.
- 🔗 Adapter-Friendly: Ships with a zod (v4+) adapter by default and lazily loads optional adapters for valibot and yup.
- 📦 Next-Ready: Matches the Next.js Route Handler signature (including Next 15/16) and supports middleware-style context extensions.
- 🧪 Fully Tested: Extensive test suite to ensure everything works reliably.
npm install @mhbdev/next-safe-route zodThe library uses zod v4+ by default. Adapters for valibot and yup are optional and lazy-loaded. Install them only if you plan to use them:
# valibot
npm install valibot
# yup
npm install yupIf an optional adapter is invoked without its peer dependency installed, a clear error message will explain what to install.
// app/api/hello/route.ts
import { createSafeRoute } from '@mhbdev/next-safe-route';
import { z } from 'zod';
const paramsSchema = z.object({
id: z.string(),
});
const querySchema = z.object({
search: z.string().optional(),
});
const bodySchema = z.object({
field: z.string(),
});
export const GET = createSafeRoute()
.params(paramsSchema)
.query(querySchema)
.body(bodySchema)
.handler((request, context) => {
const { id } = context.params;
const { search } = context.query;
const { field } = context.body;
return Response.json({ id, search, field }, { status: 200 });
});To define a route handler in Next.js:
- Import
createSafeRouteand your validation library (e.g.,zod). - Define validation schemas for params, query, and body as needed.
- Use
createSafeRoute()to create a route handler, chainingparams,query, andbodymethods. - Implement your handler function, accessing validated and type-safe params, query, and body through
context. Body validation expectsContent-Type: application/json.
The package exports adapters so you can bring your own schema library. Optional adapters can be imported from the main entry or their own subpaths to avoid pulling in unused code:
import { createSafeRoute } from '@mhbdev/next-safe-route';
import { valibotAdapter } from '@mhbdev/next-safe-route/valibot';
import { object, string } from 'valibot';
const querySchema = object({
search: string(),
});
export const GET = createSafeRoute({
validationAdapter: valibotAdapter(),
})
.query(querySchema)
.handler((request, context) => {
return Response.json({ search: context.query.search });
});Tests are written using Vitest. To run the tests, use the following command:
pnpm testContributions are welcome! For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.