A Node.js .gitignore starts with node_modules/, then the debug logs npm, Yarn and pnpm write, coverage/, TypeScript’s *.tsbuildinfo and your local .env files. Those are the key lines of the tool’s Node.js template; the whole template is 39 lines, and the tool below starts with it.
What the blocks ignore
- Dependencies:
node_modules/, at any depth, so every workspace package’s folder goes too.npm cirebuilds it from the lockfile. - Logs and caches:
npm-debug.log*,yarn-error.log*,.eslintcache,.cache/,.parcel-cache/and*.tsbuildinfo, TypeScript’s incremental build state. - Test output:
coverage/and.nyc_output/. - Packages:
*.tgz, whichnpm packwrites. - Environment files:
.env,.env.localand.env.*.local.
The template doesn’t ignore dist/, because Node itself never writes one: add your build folder as a custom line, or pick the Vite or Next.js template as well. Application logs such as logs/app.log need the Logs template.
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:3:node_modules/ packages/web/node_modules/vite/index.js
:: package-lock.json
:: yarn.lock
:: pnpm-lock.yaml
.gitignore:47:.env .env
.gitignore:49:.env.*.local .env.production.local
:: .env.production
:: .env.example
:: dist/index.js
Keep the lockfile, and know which .env files are safe
Commit package-lock.json, yarn.lock or pnpm-lock.yaml: npm’s documentation says the lockfile is intended to be committed, and it is what makes npm ci install the same tree everywhere. .env.production and .env.example aren’t ignored either. Vite, for one, loads .env.production in production builds and expects only the .local files to stay out of Git; if yours holds secrets, add .env.* and !.env.example as custom lines.
Yarn’s ! lines depend on .yarn/*
The template ignores .yarn/*, the folder’s contents, then re-includes patches, plugins, releases, sdks and versions. Git never looks inside an excluded directory, so writing .yarn/ instead breaks every one of those lines:
.gitignore:34:.yarn/ .yarn/releases/yarn-4.5.0.cjs
With the template’s .yarn/*, the same path gives ::. These lines follow Yarn’s advice for projects without Zero-Installs; with Zero-Installs, Yarn wants .yarn/cache and .pnp.cjs committed, so drop the .pnp.* line and add !.yarn/cache.
node_modules was committed before the line?
.gitignore only affects untracked files, so a tracked node_modules stays tracked. Untrack it, keeping it on disk, and commit:
git rm -r --cached node_modules
git commit -m "Stop tracking node_modules"
Editor and OS files
.DS_Store, Thumbs.db and editor swap files come from your machine, not from the project. Put them in a global ignore file once, rather than in every repository:
git config --global core.excludesFile ~/.gitignore_global
Without that setting, Git reads ~/.config/git/ignore (or $XDG_CONFIG_HOME/git/ignore).