Sometimes the first thing I want from a repository is a rough map. Which languages are here? Which directories carry most of the source? What is generated noise, and what is worth opening first?
codelines answers a deliberately modest version of those questions. It counts physical lines in recognized source and text files, groups the results, and makes the same data available to a terminal reader or another program.
Start small enough to check the answer
This was a short learning and productization project. A useful command is one thing; a package with a predictable CLI, library API and published installation path is another.
python -m pip install codelines
codelines .
codelines . --format json > count.json
The documented miniature project contains three files: four Python lines, three JSON lines and three Markdown lines. Its expected total is ten. That is demonstration data you can inspect yourself, not a performance benchmark or a claim about a real codebase.
| Fixture file type | Physical lines |
|---|---|
| Python | 4 |
| JSON | 3 |
| Markdown | 3 |
| Total | 10 |
That small example also forces a precise definition. Blank lines and comments count. A final line without a trailing newline counts too. A file containing a NUL byte contributes zero. This is not a parser deciding how many meaningful statements a developer wrote.
The scanner is half the tool
Counting newline bytes is straightforward compared with choosing the files. The scanner recognizes common extensions and special filenames such as Dockerfile and Makefile. It skips dependency, build and version-control directories, and applies nested Git-style ignore rules.
Independent files can be counted through a thread pool. The counter reads bytes in chunks rather than requiring the whole file to become a decoded string first. All output formats then use the same aggregation.
The stdout boundary matters for scripts: JSON and CSV contain the report, while progress and diagnostics go to stderr. Limiting the terminal table with --top does not silently truncate a machine-readable export.
A count is useful because it stays small
The result is a published Python tool with a contract a reader can understand and verify. I would not use its totals to rank engineers, estimate the quality of a project or pretend a longer file represents more valuable work.
For me, it was a small route into the less glamorous parts of shipping a tool: choosing sensible defaults, testing edge cases, documenting output and making installation boring. Those lessons carry directly into safedump, where the surrounding package has a more demanding job.
Code & further reading
Written by Muneer Alam · Reviewed 1 November 2026