
If you've ever accidentally pushed an API key to GitHub, you know the exact sinking feeling. A .gitignore file tells Git which files to skip entirely — it never tracks them, never includes them in commits, never sends them to the remote. But a well-crafted one, especially for a Claude Code project, does a lot of quiet heavy lifting.
Here's a breakdown of every section in this .gitignore and what would break without each one.
Download a copy of this .gitignore from my Github page: https://github.com/guillaumelai/claude-code-starter/blob/main/.gitignore
Claude Code: The Files That Should Never Leave Your Machine
| Entry | What it is | What happens without it |
|---|---|---|
.claude/settings.local.json |
Your personal Claude preferences (local overrides) | Your local tweaks stomp on teammates' settings every time you commit |
.claude/.credentials.json |
Your API keys and auth tokens | Your credentials go public — anyone with repo access can use them |
.claude/cache/ |
Cached responses and indexes | Repo fills with gigabytes of cache data that rebuilds itself anyway |
.claude/sessions/ |
Active session state | Other devs check out your half-finished session, causing confusing state |
.claude/transcripts/ |
Conversation history with Claude | Private conversations and context get committed to version history |
.claude/todos/ |
Your personal task lists | Your private TODOs become part of the shared codebase |
.claude/projects/ |
Per-project local metadata | Merge conflicts on files that should never be shared |
.claude/statsig/ |
Feature flag evaluation cache | Stale flag state gets accidentally shared across environments |
.claude/shell-snapshots/ |
Shell environment snapshots | Machine-specific paths and env vars pollute others' setups |
.claude/ide/ |
IDE integration state | Editor-specific state causes confusion across different IDE setups |
Anthropic SDK Noise
| Entry | What it is | What happens without it |
|---|---|---|
.anthropic/ |
SDK-level cache and config | SDK noise clutters your repo history |
*.claude.log |
Debug log files from Claude | Potentially sensitive prompts/responses end up in version control |
Secrets & Environment Variables
This is the critical section. Getting this wrong is a security incident waiting to happen.
| Entry | What it is | What happens without it |
|---|---|---|
.env |
Local environment variables (API keys, DB URLs) | Credentials pushed to a public repo — a serious security incident |
.env.* |
All env variants (.env.production, .env.staging) |
Same risk, across every environment |
!.env.example |
Exception: the example file IS committed | Intentional — the template stays, the real values don't |
!.env.sample |
Exception: .env.sample IS committed |
Same idea — a safe placeholder with dummy values |
*.pem |
SSL/TLS certificate files | Private keys exposed — your HTTPS trust can be compromised |
*.key |
Private key files | Same risk as .pem files |
secrets/ |
Any folder named secrets/ |
Ironically, your secrets folder would be completely public |
OS Files
| Entry | What it is | What happens without it |
|---|---|---|
.DS_Store |
macOS folder metadata | Every Mac developer pollutes the repo with invisible OS files |
Thumbs.db |
Windows thumbnail cache | Every Windows user does the same |
desktop.ini |
Windows folder config | More Windows clutter with zero value to the project |
Editor / IDE Files
| Entry | What it is | What happens without it |
|---|---|---|
.vscode/ |
VS Code workspace config | Your editor layout, theme, and font size get forced on everyone |
!.vscode/settings.json |
Exception: shared settings ARE committed | Shared formatter rules and language settings benefit the whole team |
!.vscode/extensions.json |
Exception: recommended extensions ARE committed | Team sees extension suggestions when they open the project |
.idea/ |
JetBrains IDE config | IntelliJ/WebStorm personal settings get committed |
*.swp, *.swo |
Vim swap files | Open-file indicators from Vim end up in the repo |
*~ |
Backup files (Emacs, etc.) | Editor temp files get tracked as if they were real source files |
Logs & Temp Files
| Entry | What it is | What happens without it |
|---|---|---|
*.log |
Any log file | Logs grow unbounded inside your git history |
logs/ |
Logs directory | Same, but for the whole folder |
tmp/, .tmp/, *.tmp |
Temporary files | Transient data gets permanently stored in version history |
Node / JavaScript
| Entry | What it is | What happens without it |
|---|---|---|
node_modules/ |
NPM/Yarn/pnpm dependencies | Tens of thousands of files committed — clones become enormous and slow |
.pnp.* |
Plug'n'Play files (Yarn Berry) | PnP-specific files cause conflicts on non-Yarn setups |
.yarn/cache |
Yarn's offline cache | Large binary files clog the repo history |
.yarn/install-state.gz |
Yarn install state snapshot | Machine-specific install state causes broken setups for others |
dist/, build/ |
Compiled output | Generated code gets committed — source of truth becomes ambiguous |
.next/ |
Next.js build cache | Framework-specific cache fills up the repo |
.turbo/ |
Turborepo build cache | Build tool cache committed unnecessarily |
.vercel/ |
Vercel deployment config/cache | Local deployment state and sensitive project config gets shared |
coverage/ |
Test coverage reports | Auto-generated HTML reports committed instead of generated fresh |
Python
| Entry | What it is | What happens without it |
|---|---|---|
__pycache__/ |
Python bytecode cache | Platform-specific .pyc files cause errors on different OSes |
*.py[cod] |
Compiled Python files (.pyc, .pyo, .pyd) |
Binary bytecode gets version-controlled — it's regenerated anyway |
*.egg-info/ |
Python package metadata | Build artifacts clutter the source tree |
.venv/, venv/ |
Python virtual environments | Gigabytes of packages get committed; breaks on any other machine |
.pytest_cache/ |
pytest's test cache | Test run artifacts get unnecessarily tracked |
.mypy_cache/ |
mypy type-checking cache | Type checker cache is machine-specific and large |
.ruff_cache/ |
Ruff linter cache | Linter artifacts don't belong in version control |
Misc Build Artifacts
| Entry | What it is | What happens without it |
|---|---|---|
*.tsbuildinfo |
TypeScript incremental build info | TS compiler state files get committed — they're machine-specific |
.cache/ |
Generic cache directories | Catch-all for tool caches that would otherwise bloat the repo |
The Three Rules Behind All of This
Every entry in this .gitignore falls into one of three categories:
1. Secrets — credentials, API keys, env files, private keys. These should never touch version control. A single leaked key can mean a compromised account, unexpected cloud bills, or a full security incident.
2. Runtime state — caches, sessions, logs, temp files. These are generated fresh each time you run your project. Committing them creates merge conflicts, repo bloat, and machine-specific files that break other people's setups.
3. Build artifacts — node_modules, dist, __pycache__, virtual environments. These are derived from your source code and can always be regenerated. They don't belong in git.
Notice what's not ignored: CLAUDE.md, .claude/settings.json, .claude/agents/, .claude/commands/, .claude/skills/, .claude/hooks/. These are the files meant to be shared — they define how Claude behaves for the whole team. The .gitignore draws a clear line between "yours alone" and "everyone's."
A good .gitignore is the quiet guardrail that keeps your repo clean, your secrets safe, and your team collaborating without friction.