peep

A colorful breakdown of any codebase — languages, files, and lines, in GitHub's own colors.

peep walks a directory (respecting .gitignore), detects every file's language from its name and extension, and prints a per-language report: a proportional color bar with byte, file, and line counts. Point it at a single file and it reports that file's language, size, and code/blank breakdown instead.
One static binary, one dependency, 700+ languages.
Install
go install github.com/rxxuzi/peep/cmd/peep@latest
Or build from source (Go 1.22+):
git clone https://github.com/rxxuzi/peep
cd peep
go build -o peep ./cmd/peep
Then put the binary somewhere on your PATH.
Usage
peep [options] [path]
path defaults to the current directory and may be a directory or a single file. Flags may come before or after it.
| Flag |
Description |
Default |
-v, --verbose |
Show a per-file detail list |
off |
-a, --all |
Include hidden files and default-excluded dirs (.git, node_modules, …) |
off |
-i, --ignore PATTERN |
Ignore a glob pattern (repeatable) |
— |
-x, --exclude LANG |
Exclude a language from the report (repeatable) |
— |
--no-gitignore |
Skip .gitignore rules |
off |
-s, --sort KEY |
Primary metric: bytes, lines, code, files, or name — drives the order, the % column, and the bar |
bytes |
-r, --reverse |
Reverse the sort order |
off |
-n, --top N |
Show the top N languages (0 = all) |
10 |
-w, --bar-width N |
Width of the color bar |
50 |
--color MODE |
auto, truecolor, 256, or off |
auto |
Bare directory names passed to -i (e.g. -i node_modules) match at any depth; patterns with glob characters or slashes are matched like .gitignore entries.
--sort picks the metric the whole report is viewed through: row order, percentages, and the color bar all follow it, so the table stays consistent. Numeric keys sort descending, name ascends (and only reorders — percentages stay bytes-based); -r flips either.
How it works
.gitignore aware. A built-in matcher reads .gitignore files as it descends, supporting negation (!), anchored (/foo), directory-only (dir/), and ** patterns. Disable with --no-gitignore.
- 700+ languages, detected by extension or by special filename (
Dockerfile, Makefile, go.mod, …). Definitions and colors come from github-linguist.
- Linguist colors wherever linguist defines one — including config/doc formats (Markdown, JSON, YAML, TOML, …); color-less types (plain Text, …) render in white.
- Hidden files are skipped, except well-known dotfiles (
.env, .editorconfig, .gitignore, …). Common noise directories (.git, .svn, .hg, node_modules, bower_components, __pycache__, .venv, venv, .mypy_cache, .pytest_cache, .gradle, .idea, .vscode, .cache) are excluded by default; -a/--all scans them too (.gitignore rules still apply — combine with --no-gitignore for truly everything).
- Lines are classified as code or blank; non-UTF-8 (binary) files are counted by size only.
- Parallel. Files are processed by a worker pool (one worker per CPU) while the tree is walked; line counting streams files in fixed-size chunks, so memory stays flat no matter the file size.
- Cross-platform — Linux, macOS, and Windows, where virtual-terminal processing is enabled automatically so colors render in the console.
- Colors turn off when stdout isn't a terminal, so piped output stays clean. Override with
--color.
License
MIT License - see LICENSE file for details