{"id":17124,"library":"zod-express-middleware","title":"Zod Express Middleware","description":"`zod-express-middleware` is an Express.js middleware library designed to enforce type safety and validate incoming request data (body, query, and parameters) using Zod schemas. Currently at version 1.4.0, it provides functions like `validateRequest` to check if an incoming request conforms to predefined Zod schemas without modifying the request object. For scenarios requiring data transformation or stripping unknown keys, it offers `processRequest` and its specific variants (`processRequestBody`, `processRequestQuery`, `processRequestParams`), which leverage Zod's `.transform` and `.refine` methods. The package maintains a steady release cadence, integrating smoothly with `express` and `zod` as peer dependencies. Its primary differentiator is the direct integration of Zod's powerful, inferential schema validation capabilities into the Express middleware pipeline, providing a robust solution for ensuring API contract adherence and improving developer experience through strong typing.","status":"maintenance","version":"1.4.0","language":"javascript","source_language":"en","source_url":"https://github.com/Aquila169/zod-express-middleware","tags":["javascript","express","zod","middleware","endpoint","validation","typescript"],"install":[{"cmd":"npm install zod-express-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add zod-express-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add zod-express-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides TypeScript type definitions for Express.js, essential for type-safe usage.","package":"@types/express","optional":true},{"reason":"The core web framework that this package extends with middleware.","package":"express","optional":false},{"reason":"The primary schema declaration and validation library used for defining request schemas.","package":"zod","optional":false}],"imports":[{"note":"The library primarily uses ES Modules. While CommonJS `require` might work in some transpiled environments, native ESM `import` is the recommended and type-safe approach. `validateRequest` is the main entry point for combining body, query, and params validation.","wrong":"const { validateRequest } = require('zod-express-middleware');","symbol":"validateRequest","correct":"import { validateRequest } from 'zod-express-middleware';"},{"note":"Use `processRequest` (or its specific variants like `processRequestBody`) when you need to apply Zod transformations (`.transform()`, `.refine()`) to the request data, as `validateRequest` only performs validation without modifying the request object.","wrong":"import { validateRequest } from 'zod-express-middleware'; // Used for transformations","symbol":"processRequest","correct":"import { processRequest } from 'zod-express-middleware';"},{"note":"Although `zod-express-middleware` uses Zod internally, `z` itself must be imported directly from the `zod` package to define your schemas. This is a crucial peer dependency.","symbol":"z","correct":"import { z } from 'zod';"},{"note":"For explicit type annotations, especially when separating endpoint logic from route definitions, `TypedRequestBody`, `TypedRequestQuery`, `TypedRequestParams`, and `TypedRequest` are provided. Pass the `typeof` your Zod schema into these types.","symbol":"TypedRequestBody","correct":"import { TypedRequestBody } from 'zod-express-middleware';"}],"quickstart":{"code":"import express from 'express';\nimport { validateRequest } from 'zod-express-middleware';\nimport { z } from 'zod';\n\n// Create an express app\nconst app = express();\n\n// Add express.json() middleware to parse JSON bodies\napp.use(express.json());\n\n// Define an endpoint using express, zod and zod-express-middleware\napp.post(\"/:urlParameter/\", validateRequest({\n    params: z.object({\n      urlParameter: z.string().uuid(\"Invalid URL parameter format\"),\n    }),\n    body: z.object({\n      bodyKey: z.number().int().positive(\"bodyKey must be a positive integer\"),\n      optionalField: z.string().optional()\n    }),\n    query: z.object({\n      queryKey: z.string().length(64, \"queryKey must be 64 characters long\"),\n    }),\n  }), (req, res) => {\n    // req.params, req.body and req.query are now strictly-typed and confirm to the zod schema's above.\n    // req.params has type { urlParameter: string };\n    // req.body has type { bodyKey: number; optionalField?: string };\n    // req.query has type { queryKey: string };\n    console.log('Validated Params:', req.params);\n    console.log('Validated Body:', req.body);\n    console.log('Validated Query:', req.query);\n    return res.json({message: \"Validation for params, body and query passed\", data: { params: req.params, body: req.body, query: req.query }});  \n  }\n);\n\napp.get('/', (req, res) => {\n  res.send('Welcome to the Zod Express Middleware example!');\n});\n\n// Error handling middleware for ZodErrors\napp.use((err, req, res, next) => {\n  if (err instanceof z.ZodError) {\n    return res.status(400).json({\n      status: 'error',\n      message: 'Validation failed.',\n      errors: err.errors.map(e => ({ path: e.path.join('.'), message: e.message }))\n    });\n  }\n  next(err);\n});\n\n// Start the express app on port 8080\nconst PORT = process.env.PORT ?? 8080;\napp.listen(PORT, () => {\n  console.log(`Server running on http://localhost:${PORT}`);\n  console.log('Try POST to /<uuid-param>?queryKey=... (64 chars) with JSON body { \"bodyKey\": 123 }');\n});\n","lang":"typescript","description":"This example demonstrates how to set up an Express application with `zod-express-middleware` to validate `req.params`, `req.body`, and `req.query` using Zod schemas for a POST endpoint. It includes basic Express setup, JSON body parsing, and a global error handler for Zod validation failures."},"warnings":[{"fix":"Ensure you have `express`, `zod`, and `@types/express` installed alongside `zod-express-middleware` with compatible versions (e.g., `npm install express zod @types/express` or verify your `package.json` for correct ranges).","message":"This package relies on `express`, `zod`, and `@types/express` as peer dependencies. Failure to install these or installing incompatible versions will lead to runtime errors or TypeScript compilation issues.","severity":"gotcha","affected_versions":">=0.2.0"},{"fix":"If your Zod schema includes `.transform()` or `.refine()` and you expect the request object properties to be modified, switch from `validateRequest` to `processRequest` (or `processRequestBody`, etc.).","message":"`validateRequest` and its variants only perform validation and do not modify the `req.body`, `req.query`, or `req.params` objects to reflect parsed or transformed values. If you need to apply Zod's `.transform()` or `.refine()` methods that alter the data, you must use the `processRequest` functions (e.g., `processRequest`, `processRequestBody`).","severity":"gotcha","affected_versions":">=0.2.0"},{"fix":"Implement a custom Express error-handling middleware that catches `z.ZodError` instances and formats the `err.errors` array into a user-friendly response. Zod allows customizing messages directly in schema definitions or via a global error map.","message":"The default error messages provided by Zod for validation failures might be too technical for end-users. You'll likely need to implement custom error handling to present more user-friendly messages.","severity":"gotcha","affected_versions":">=0.2.0"},{"fix":"For new projects or if you require more advanced features and active maintenance, consider migrating to `express-zod-api` or `express-zod-safe`. For existing projects, `zod-express-middleware` will continue to function as a simple, unopinionated solution.","message":"As of June 17, 2021, the repository maintainer noted that the project is not likely to receive significant updates in the future, suggesting alternatives like `express-zod-api` or `express-zod-safe` for new projects seeking more active development and features.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Upgrade your project's TypeScript version to 5.x or higher to be compatible with newer Zod releases. Alternatively, you may need to pin your `zod` dependency to `~3.25.x` (e.g., `3.25.0` to `3.25.75`) if you cannot upgrade TypeScript.","message":"Recent Zod versions (e.g., 3.25.76 and higher) can bundle Zod 4 code, which uses TypeScript 5+ syntax. This can cause build failures for projects still on TypeScript 4.x, even when `zod-express-middleware` itself has not updated its direct dependencies, due to `zod` being a peer dependency.","severity":"breaking","affected_versions":">=3.25.76 (of Zod peer dependency)"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure `express` and `zod` are explicitly installed in your project: `npm install express zod`.","cause":"One of the peer dependencies (express or zod) is not installed or incorrectly configured in the project.","error":"Cannot find module 'express' or 'zod'"},{"fix":"Install `@types/express`: `npm install --save-dev @types/express`. Ensure your route handler is defined immediately after `validateRequest` so TypeScript can infer the request object's updated type.","cause":"TypeScript cannot infer the types of `req.body`, `req.query`, or `req.params` because `@types/express` is missing or the validation middleware is not correctly applied in a TypeScript environment.","error":"Property 'body' does not exist on type 'Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>'."},{"fix":"Review the `err.errors` array within the `ZodError` instance to understand which fields failed validation and why. Adjust the incoming request data or refine your Zod schema to match expected inputs. Implement a custom error handler to return specific validation messages to the client.","cause":"The incoming request data (body, query, or params) does not conform to the defined Zod schema.","error":"ZodError: Validation failed"},{"fix":"Ensure that appropriate Express body-parsing middleware (`app.use(express.json())`, `app.use(express.urlencoded({ extended: true }))`) is applied *before* the `zod-express-middleware` in your Express app. Also, mark optional fields in your Zod schema with `.optional()` or `.nullable()`.","cause":"Attempting to access properties on `req.body`, `req.query`, or `req.params` before `express.json()`, `express.urlencoded()`, or `express.query()` middleware has parsed the respective part of the request, or when a property is missing and not explicitly `optional()` in the schema.","error":"TypeError: Cannot read properties of undefined (reading 'someProperty')"}],"ecosystem":"npm","meta_description":null}