Analyze repositories for lines of code, language breakdown, file counts, and code-vs-comment ratios using pygount.
pip install --break-system-packages pygount 2>/dev/null || pip install pygount
Get a full language breakdown with file counts, code lines, and comment lines:
cd /path/to/repo
pygount --format=summary \
--folders-to-skip=".git,node_modules,venv,.venv,__pycache__,.cache,dist,build,.next,.tox,.eggs,*.egg-info" \
.
IMPORTANT: Always use --folders-to-skip to exclude dependency/build directories, otherwise pygount will crawl them and take a very long time or hang.
Adjust based on the project type:
# Python projects
--folders-to-skip=".git,venv,.venv,__pycache__,.cache,dist,build,.tox,.eggs,.mypy_cache"
# JavaScript/TypeScript projects
--folders-to-skip=".git,node_modules,dist,build,.next,.cache,.turbo,coverage"
# General catch-all
--folders-to-skip=".git,node_modules,venv,.venv,__pycache__,.cache,dist,build,.next,.tox,vendor,third_party"
# Only count Python files
pygount --suffix=py --format=summary .
# Only count Python and YAML
pygount --suffix=py,yaml,yml --format=summary .
# Default format shows per-file breakdown
pygount --folders-to-skip=".git,node_modules,venv" .
# Sort by code lines (pipe through sort)
pygount --folders-to-skip=".git,node_modules,venv" . | sort -t$'\t' -k1 -nr | head -20
# Summary table (default recommendation)
pygount --format=summary .
# JSON output for programmatic use
pygount --format=json .
# Pipe-friendly: Language, file count, code, docs, empty, string
pygount --format=summary . 2>/dev/null
The summary table columns: - Language — detected programming language - Files — number of files of that language - Code — lines of actual code (executable/declarative) - Comment — lines that are comments or documentation - % — percentage of total
Special pseudo-languages:
- __empty__ — empty files
- __binary__ — binary files (images, compiled, etc.)
- __generated__ — auto-generated files (detected heuristically)
- __duplicate__ — files with identical content
- __unknown__ — unrecognized file types
pygount Is MissingIf pygount is unavailable and installing it is unnecessary or blocked, use a quick git-tracked source inventory instead of stopping. This is especially useful during repo triage/refactor planning:
python3 - <<'PY'
import os, subprocess
from pathlib import Path
root = Path.cwd()
files = subprocess.check_output(['git', 'ls-files'], text=True).splitlines()
print('tracked files', len(files))
for needle in ['node_modules/', '.env', 'firebase-adminsdk', ' copy', 'public copy']:
hits = [f for f in files if needle in f]
print(needle, len(hits), hits[:10])
skip_suffixes = ('.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg', '.ttf', '.woff', '.woff2', '.otf', '.lock')
total = 0
by_ext = {}
for f in files:
p = root / f
if not p.exists() or any(f.endswith(s) for s in skip_suffixes):
continue
try:
n = sum(1 for _ in p.open(errors='ignore'))
except Exception:
continue
total += n
by_ext[p.suffix or '[none]'] = by_ext.get(p.suffix or '[none]', 0) + n
print('text LOC-ish', total)
print('by extension', sorted(by_ext.items(), key=lambda x: -x[1])[:15])
PY
This is not a substitute for pygount language classification, but it reliably exposes hygiene problems such as committed node_modules, committed secrets, copy-artifact sprawl, and approximate size.
--folders-to-skip, pygount will crawl everything and may take minutes or hang on large dependency trees.wc -l directly.--suffix to target specific languages rather than scanning everything.