HAP robot wearing safari outfit and pith helmet looking through binoculars
Exploring hidden files in the wild.

Every project has files that shouldn’t be shared. Some contain secrets. Some are too large. Some are generated automatically.

The .gitignore file tells Git which files to ignore.

Why some files shouldn’t be tracked

Privacy and security

Some files contain information that should never be public:

  • API keys and passwords (.env files)
  • Database credentials
  • Personal configuration files
  • AI conversation logs

If these get pushed to GitHub, anyone with access can see them. Removing them from Git history is painful—and you’ll never know who already copied them.

Generated files waste space

Some files are created automatically:

  • node_modules/ — thousands of files, but npm install regenerates them
  • Build output (dist/, build/)
  • Cache and log files

Uploading these wastes storage and slows cloning. Since they can be regenerated, there’s no reason to track them.

How it works

Basic syntax:

  • One pattern per line
  • folder/ ignores a folder and everything in it
  • *.log ignores all files ending in .log
  • !important.log — the ! means “don’t ignore this one”
  • Lines starting with # are comments

Example:

# Dependencies - regenerated by npm install
node_modules/
# Environment variables - contains secrets
.env
.env.local
# AI conversation logs - private
.specstory/
.claude/
# Build output - regenerated by build command
dist/

The node_modules problem

Why node_modules is always ignored:

  • A typical project has hundreds or thousands of dependency files
  • These are defined in package.json and package-lock.json
  • Running npm install downloads them all
  • No need to upload what can be downloaded

Common beginner mistake: Accidentally committing node_modules/. This can add thousands of files to your repository and make it extremely slow to clone.

If you see node_modules in your staged changes, stop and check your .gitignore.

What about empty folders?

Git doesn’t track empty folders. If you need one in your repo (like a logs/ folder), add an empty file called .gitkeep.

.gitkeep is just a convention—an empty file whose presence makes Git track the folder.

Quick reference

.env

Secrets

security

node_modules/

Dependencies

too largeregenerated

dist/

Build output

regenerated

.specstory/

AI logs

privacy

.DS_Store

OS files

irrelevant

Your starter repositories already include a configured .gitignore. Don’t remove entries unless you understand what they do.