.gitignore for Next.js

node_modules/ .next/ out/ .vercel next-env.d.ts .env .env.local .env.*.local

A Next.js .gitignore ignores node_modules/, the .next/ build folder, out/ from a static export, the .vercel project link, next-env.d.ts, and your local env files: .env, .env.local and .env.*.local. Those are the key lines of the tool’s Next.js template, which has 23, the Node.js essentials included, so it works on its own.

What the blocks ignore

  • Build output: .next/, which holds the compiled app and its cache, and out/, written by output: 'export'.
  • Generated files: next-env.d.ts, which Next.js rewrites itself and create-next-app ignores too, and *.tsbuildinfo.
  • Deployment: .vercel, the folder vercel link writes with your project and team ids.
  • Secrets: the env files above, and *.pem, which covers private keys such as a local HTTPS setup’s.
  • The rest: coverage/, package manager logs, Yarn’s cache lines and .DS_Store.

In a scratch repository with this file, git check-ignore -v -n --no-index names the line that matched each path, or prints :: when none did:

.gitignore:4:.next/	.next/cache/images/x
.gitignore:10:next-env.d.ts	next-env.d.ts
.gitignore:8:.vercel	.vercel/project.json
.gitignore:24:.env	.env
.gitignore:25:.env.local	.env.local
::	.env.production
.gitignore:26:.env.*.local	.env.development.local
.gitignore:27:*.pem	certificates/localhost-key.pem
::	package-lock.json

Which env files are committed

Next.js loads .env.production and .env.development as defaults for each environment, so the template leaves them tracked; keep real secrets in .env.local or your host’s settings. Anything prefixed NEXT_PUBLIC_ is inlined into the browser bundle, so it is never a secret. Commit the lockfile too.

out/ can hide a route

out/ has no leading slash, so it matches at any depth, and an App Router route folder called out disappears with the export:

.gitignore:6:out/	src/app/out/page.tsx

create-next-app writes /out/ instead. If the app sits at the repository root, use that:

.gitignore:6:/out/	out/index.html
::	src/app/out/page.tsx

In a monorepo, keep out/ or put the .gitignore in the app’s folder, since a leading slash anchors to the folder the file is in.

Keeping one file a pattern catches

*.pem also matches a public certificate you may want in the repository. A later ! line brings it back, because its folder isn’t excluded:

.gitignore:31:!certs/public-ca.pem	certs/public-ca.pem

A file inside an excluded folder, such as .next/, can’t be re-included: Git never looks inside it.

Already committed .next/?

.gitignore only affects untracked files. Untrack it, keeping it on disk, and commit:

git rm -r --cached .next
git commit -m "Stop tracking .next"

Editor and OS files

The template already has .DS_Store. Keep the rest, such as Thumbs.db and editor swap files, in a global ignore file:

git config --global core.excludesFile ~/.gitignore_global

Try it in the Gitignore Generator

In the file: Next.js

.gitignore

1 template · 23 pattern lines
# Next.js
node_modules/
# The build output and client bundle cache
.next/
# Static export from next export
out/
# Vercel's project link
.vercel
# Rewritten by Next.js on every build
next-env.d.ts
*.tsbuildinfo
coverage/
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
.env
.env.local
.env.*.local
*.pem
.DS_Store
  • ✓Not ignored: no line in this file matches "/.env.production".

Lines are applied top to bottom, and the last one that matches wins — which is why a line of your own can overrule a template.

Runs in your browser. Nothing you enter is sent anywhere.