GUIDES · ALL NINE CHECKS

Next.js works locally but fails on Vercel: the five usual causes

A passing local build proves less than you think. The five reasons a Next.js app works on your machine and fails on Vercel, with the fix for each.

Why local success means little

npm run dev on your laptop uses your .env.local, a case insensitive file system on macOS and Windows, your globally installed tools and whatever is in node_modules right now. Vercel builds from a clean clone on Linux, installs from the lockfile, and only sees the environment variables you added in the project settings. Each of those differences is a way for a green local build to turn into a red deploy.

1. Environment variables that only exist on your machine

The code reads process.env.STRIPE_SECRET_KEY, .env.local has it, Vercel does not. The build log rarely says so directly. It fails somewhere downstream with undefined or a client constructor throwing at module scope.

Fix: keep .env.example in sync with every variable the code reads, and add each one to the Vercel project for every environment you deploy. Preview deployments are the ones people forget.

2. Imports that resolve on macOS and fail on Linux

import Header from ./components/Header finds header.tsx on a case insensitive disk. Vercel builds on Linux, where that import does not resolve and the build stops with Module not found.

Fix: match the casing of every import to the file name exactly. Renaming only the case of a file needs two git mv steps, because git ignores a case only rename on macOS.

3. Node only packages in Edge routes

An API route or middleware that declares runtime edge cannot use fs, net, dns, child_process or packages built on them, such as ioredis or pg. The bundler follows every static import, so even a branch that never runs will break the build.

Fix: move the route to the Node runtime with export const runtime = nodejs, or use an HTTP based client such as @upstash/redis.

4. A lockfile that does not match package.json

Vercel installs with a frozen lockfile. If package.json changed and the lockfile did not, or the lockfile was written by a different package manager version, the install fails before the build starts.

Fix: run the install locally with the same package manager Vercel uses, commit the updated lockfile, and never use latest as a version.

5. Prisma client not generated

The generated Prisma client is gitignored. If nothing runs prisma generate during install on Vercel, the import of @prisma/client fails or the query engine is missing at runtime.

Fix: add a postinstall script that runs prisma generate, and make sure the schema sets the binary targets Vercel needs.

{
  "scripts": {
    "postinstall": "prisma generate"
  }
}

Updated 2026-10-05