{"id":17455,"library":"next-connect","title":"Next.js Connect Router","description":"next-connect is a promise-based routing and middleware layer designed specifically for Next.js applications, supporting various environments including API Routes, Edge API Routes, Middleware, App Router Route Handlers, and `getServerSideProps`. Currently at stable version 1.0.0, the library has historically followed an active release cadence, with pre-releases leading up to major versions. Its key differentiators include asynchronous middleware support, a lightweight footprint suitable for serverless environments, and significantly faster performance compared to traditional Express.js setups. It also offers robust TypeScript support and handles asynchronous handlers with integrated error catching, providing a flexible and efficient alternative for managing server-side logic in Next.js projects.","status":"active","version":"1.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/hoangvvo/next-connect","tags":["javascript","nextjs","middleware","router","connect","typescript"],"install":[{"cmd":"npm install next-connect","lang":"bash","label":"npm"},{"cmd":"yarn add next-connect","lang":"bash","label":"yarn"},{"cmd":"pnpm add next-connect","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v1.0.0-next.0, `next-connect` moved to named exports. `createRouter` is for Node.js API Routes (pages/api).","wrong":"import nextConnect from 'next-connect';\nconst router = nextConnect();","symbol":"createRouter","correct":"import { createRouter } from 'next-connect';"},{"note":"`createEdgeRouter` is specifically for Next.js Edge API Routes and App Router Route Handlers, requiring a different request/response object structure than Node.js API Routes.","wrong":"import { createRouter } from 'next-connect'; // Incorrect for Edge Runtime","symbol":"createEdgeRouter","correct":"import { createEdgeRouter } from 'next-connect';"},{"note":"Used to adapt traditional Express.js middleware for compatibility with next-connect handlers, as direct Express.js middleware support was dropped in v1.0.0-next.0.","wrong":null,"symbol":"expressWrapper","correct":"import { expressWrapper } from 'next-connect';"},{"note":"This is a TypeScript type import for defining router instances, primarily for type inference and extension.","wrong":null,"symbol":"NextConnect","correct":"import type { NextConnect } from 'next-connect';"}],"quickstart":{"code":"import type { NextApiRequest, NextApiResponse } from \"next\";\nimport { createRouter } from \"next-connect\";\n\n// Mock dependencies for a runnable example\nconst getUser = (id: string) => ({ id, name: `User ${id}`, email: `${id}@example.com` });\nconst updateUser = async (data: any) => ({ ...data, updatedAt: new Date().toISOString() });\nclass ForbiddenError extends Error {\n  statusCode: number;\n  constructor(message: string) {\n    super(message);\n    this.name = 'ForbiddenError';\n    this.statusCode = 403;\n  }\n}\n\nconst router = createRouter<NextApiRequest, NextApiResponse>();\n\nrouter\n  .use(async (req, res, next) => {\n    const start = Date.now();\n    // Simulate authentication or logging\n    console.log(`Incoming request to ${req.url}`);\n    await next(); // call next in chain\n    const end = Date.now();\n    console.log(`Request to ${req.url} took ${end - start}ms`);\n  })\n  .get((req, res) => {\n    const { id } = req.query;\n    if (typeof id !== 'string') {\n      res.status(400).json({ message: 'Invalid user ID' });\n      return;\n    }\n    const user = getUser(id);\n    res.json({ user });\n  })\n  .put(async (req, res) => {\n    // Simulate user context (e.g., from session/token)\n    const currentUser = { id: 'currentUserId123' }; // Mock current user\n    const { id } = req.query;\n    if (typeof id !== 'string') {\n      throw new Error('Invalid user ID for update');\n    }\n\n    // Example authorization check\n    if (currentUser.id !== id) {\n      throw new ForbiddenError(\"You can't update other user's profile\");\n    }\n    const updatedUser = await updateUser({ id, ...req.body });\n    res.json({ user: updatedUser });\n  });\n\nexport default router.handler({\n  onError: (err, req, res) => {\n    console.error(err.stack); // Log the error for debugging\n    const statusCode = (err as ForbiddenError).statusCode || 500;\n    res.status(statusCode).end(err.message || \"Something broke!\");\n  },\n  onNoMatch: (req, res) => {\n    res.status(404).end(`Route ${req.method} ${req.url} not found`);\n  },\n});","lang":"typescript","description":"This example demonstrates creating an API route with `next-connect`, handling GET and PUT requests, implementing asynchronous middleware for logging, and setting up global error handling for unmatched routes and exceptions."},"warnings":[{"fix":"For Express.js middleware, import and wrap it with `expressWrapper(middleware)`. For error handling, instead of calling `next(err)`, simply `throw new Error('...')` or a custom error object. The `onError` handler in `.handler()` will catch these.","message":"Version 1.0.0-next.0 (and thus v1.0.0 stable) introduced significant breaking changes. Built-in support for Express.js middleware was removed, requiring the use of `expressWrapper` for compatibility. Additionally, the `next(err)` pattern for error propagation within middleware chains was deprecated in favor of throwing errors directly.","severity":"breaking","affected_versions":">=1.0.0-next.0"},{"fix":"Ensure your error handling is configured within the `.handler({ onError: ... })` options object, as this is the standard and supported approach for catching errors thrown in middleware or route handlers.","message":"In version 0.12.1, the `handle()` method (now `.handler()` in v1) no longer directly used the `onError` option. This change affected how error handling was configured for those upgrading from older `v0` versions.","severity":"breaking","affected_versions":"0.12.1"},{"fix":"Always `await next()` in your `async` middleware functions: `router.use(async (req, res, next) => { /* ... */ await next(); /* ... */ });`","message":"When using `next-connect` with async middleware or handlers, it is crucial to `await next()` to ensure that errors thrown later in the chain are properly caught by the `onError` handler and to allow for proper control flow. Failing to await `next()` can lead to `UnhandledPromiseRejection` errors.","severity":"gotcha","affected_versions":">=0.x"},{"fix":"Use `createRouter` when targeting `pages/api` (Node.js runtime). Use `createEdgeRouter` when targeting the Edge Runtime in `pages/api` (with `export const config = { runtime: 'edge' };`) or in App Router Route Handlers (`app/api`).","message":"The library offers `createRouter` for standard Node.js-based Next.js API Routes (`pages/api`) and `createEdgeRouter` for Next.js Edge API Routes and App Router Route Handlers. Using the wrong router for the intended runtime can lead to type mismatches or runtime errors, as their request/response objects differ.","severity":"gotcha","affected_versions":">=1.0.0-next.2"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Update your import statements to use named exports: `import { createRouter } from 'next-connect';` or `import { createEdgeRouter } from 'next-connect';`","cause":"Attempting to use `next-connect` with a default import (`import nextConnect from 'next-connect';`) after upgrading to v1, which switched to named exports.","error":"TypeError: (0 , next_connect__WEBPACK_IMPORTED_MODULE_0__.default) is not a function"},{"fix":"Replace calls to `next(err)` with `throw err;` or `throw new Error('...')`. Errors will be caught by the `onError` handler configured in `.handler()`.","cause":"Calling `next(err)` in middleware after upgrading to `next-connect` v1.0.0, which removed this pattern.","error":"Error: You can't use next(err) here. Please throw an error instead."},{"fix":"Ensure all middleware functions are correctly structured `(req, res, next) => { ... }` and that `async` middleware explicitly `await next();`. Double-check any `expressWrapper` usage for correct integration.","cause":"This error can occur if a middleware function is not properly defined or if an `async` middleware does not correctly call `await next()`, leading to issues in the promise chain resolution.","error":"TypeError: handlers[(i++)] is not a function"},{"fix":"Ensure that `res` is always available and that all asynchronous operations either return a value or explicitly call `next()` or `res.end()`/`res.json()`. Await all `next()` calls in async middleware. Implement a robust `onError` handler in `router.handler()` to catch and gracefully respond to errors.","cause":"This error often indicates issues with the `res` object not being properly handled or passed through the middleware chain, or an unhandled promise rejection in an async handler where `res` might become undefined.","error":"TypeError: Cannot read properties of undefined (reading 'end') at nextConnect/lib/index.js"}],"ecosystem":"npm","meta_description":null}