loc - Advanced Lines of Code Counter
A fast, feature-rich LOC tool written in Rust.
Author: kelexine
Features
- Fast project scanning: Counts text files across a target directory with optional Rayon-powered parallel processing.
- Code/comment/blank split: Classifies source lines using language-aware single-line and block-comment rules.
- Tree view: Renders a recursive project tree when
--treeis enabled, with optional binary-file display. - Function extraction: Uses Tree-sitter-backed extractors for Rust, Python, JavaScript/TypeScript, Go, C/C++, Java/Kotlin/C#/Scala, PHP, Swift, and Ruby.
- Complexity analysis: Reports function length and a branch-count cyclomatic complexity estimate.
- Git-aware discovery: Uses
git ls-filesin repositories and can attach last-modified dates fromgit log. - Agent mode auto-detection: Switches to token-efficient TSV output when run inside AI coding agents (Claude Code, Gemini CLI, etc.).
- Lockfile awareness: Automatically detects dependency lockfiles (Cargo.lock, package-lock.json, etc.), excluding them from line metrics to prevent skewed stats.
- Machine-readable outputs: Supports direct-to-stdout JSON (
--json), TSV (--format agent), and pipe-friendly raw path lists (-q). - Multi-format export: Writes JSON, JSONL, CSV, TSV, and HTML reports.
- Global configuration: Reads defaults from
~/.config/loc-rs/config.tomlthrough the platform config directory. - Size warnings: Flags files above a configured line threshold.
- BOM-aware binary detection: Treats UTF-16/UTF-32 files as text instead of false-positive binary files.
Installation
From crates.io
From source
Requires Rust 1.92.0 or newer.
The release binary is built at ./target/release/loc.
Quick Start
|
Documentation
- CONTRIBUTING: Local setup, test commands, and release workflow.
- Architecture Guide: Module layout and runtime flow.
- Release Guide: Step-by-step
cargo releasesequence. - Security Notes: Threat model and CI safety guidance.
- FAQ: Quick answers for common usage questions.
- Troubleshooting Guide: Common failure modes and fixes.
Generate Rust API docs locally:
Open docs in your browser:
Usage
loc [OPTIONS] [DIRECTORY]
DIRECTORY defaults to the current directory.
Common workflows
| Goal | Command |
|---|---|
| Scan the current directory | loc |
| Scan a specific directory | loc src/ |
| Show per-extension metrics | loc -d |
| Show a recursive tree | loc --tree |
| Include binary files in the tree | loc --tree -b |
| Extract functions and methods | loc -f |
| Show function complexity analysis | loc --func-analysis |
| Scan only selected languages | loc -t rust python typescript |
| Warn for files above 500 lines | loc --warn-size 500 |
| Use Git commit dates | loc --git-dates |
| Include hidden files and directories | loc --include-hidden |
| Disable parallel processing | loc --no-parallel |
Export examples
All Flags
| Flag | Short | Description |
|---|---|---|
--detailed |
-d |
Per-extension breakdown (Code, Comment, Blank) |
--tree |
Show recursive directory tree (hidden by default) | |
--binary |
-b |
Show binary files in tree |
--functions |
-f |
Extract functions, methods, classes |
--func-analysis |
Full analysis report (auto-enables -f) |
|
--type LANG... |
-t |
Filter by language(s) |
--export FILE |
-e |
Export results to .json, .jsonl, .csv, or .html |
--warn-size N |
Warn for files exceeding N lines | |
--git-dates |
Use git log for last-modified dates |
|
--include-hidden |
-H |
Include hidden files and directories |
--no-parallel |
Disable Rayon parallelism |
Configuration
You can persist defaults in ~/.config/loc-rs/config.toml on Linux, or the equivalent platform config directory returned by the OS.
= 500
= ["rust", "python"]
= true
.locignore (project root) is also supported for custom file and directory ignores:
# Ignore generated snapshots
snapshots
*.min.js
GitHub Action Integration
The repository includes a comprehensive composite GitHub Action for CI line-count and complexity checks. The action features sub-second installs via pre-built binaries, GitHub Step Summary integration, and automated artifact uploads.
steps:
- uses: actions/checkout@v4
- uses: kelexine/loc-rs/.github/actions/loc-rs@main
with:
target_dir: .
warn_size: 500
functions: true
fail_on_warn: true # Fails the build if any files exceed warn_size
export_html: true # Automatically uploads HTML report to artifacts
export_json: true # Automatically uploads JSON report to artifacts
version: latest # Uses pre-built binaries for instant execution
Use static workflow values for target_dir, warn_size, and args; do not pass untrusted pull request, issue, or comment text into shell-backed action inputs.
Supported Languages
| Name | Extensions |
|---|---|
c |
.c .h |
csharp |
.cs |
cpp |
.cpp .cc .cxx .hpp .hxx .h++ |
css |
.css .scss .sass .less |
elixir |
.ex .exs |
go |
.go |
haskell |
.hs .lhs |
html |
.html .htm |
java |
.java |
javascript |
.js .mjs .cjs |
json |
.json .jsonl .json5 |
jsx |
.jsx |
kotlin |
.kt .kts |
lua |
.lua |
markdown |
.md .markdown .mdx |
nim |
.nim .nims |
php |
.php .php3 .php4 .php5 .phtml |
python |
.py .pyw .pyi |
ruby |
.rb .rake .gemspec |
rust |
.rs |
scala |
.scala .sc |
shell |
.sh .bash .zsh .fish |
sql |
.sql |
svelte |
.svelte |
swift |
.swift |
toml |
.toml |
typescript |
.ts .tsx .mts |
vue |
.vue |
xml |
.xml .xsl .xslt |
yaml |
.yml .yaml |
zig |
.zig |
Language aliases are supported for common names such as py, js, ts, tsx, rs, rb, sh, bash, zsh, md, yml, kt, hs, c++, cxx, cc, and cs.
Function Extraction Support
Function extraction is available when -f or --func-analysis is enabled. The extractors return function names, line ranges, parameters where supported, async markers where supported, class/struct markers, docstrings where supported, decorators where supported, and a complexity estimate.
| Language | Functions | Methods | Classes/Structs | Async | Decorators | Docstrings |
|---|---|---|---|---|---|---|
| Rust | ✓ | ✓ | ✓ (struct/impl) | ✓ | pub flag | — |
| Python | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| JavaScript/TypeScript | ✓ | ✓ | ✓ | ✓ | — | — |
| Go | ✓ | ✓ | — | — | — | — |
| C/C++ | ✓ | ✓ | ✓ | — | — | — |
| Java/Kotlin/C#/Scala | ✓ | ✓ | ✓ | — | — | — |
| PHP | ✓ | ✓ | ✓ | — | — | — |
| Swift | ✓ | ✓ | ✓ | ✓ | — | — |
| Ruby | ✓ | ✓ | ✓ | — | — | — |
Export Formats
| Format | Extension | Contents |
|---|---|---|
| JSON | .json |
Metadata, extension breakdown, files, and optional function data |
| JSON Lines | .jsonl |
One file record per line |
| CSV | .csv |
File-level metrics, with optional function columns |
| HTML | .html, .htm |
Standalone visual report with charts and searchable file table |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Functions: 0 in summary |
Function extraction not enabled | Run with -f or --func-analysis |
Unknown language warning (for example dart) |
Language not in resolver map | Use a supported language or direct extension via -t .ext |
stream did not contain valid UTF-8 warning |
File is UTF-16/UTF-32 encoded | Convert to UTF-8; loc-rs current reader is UTF-8 only |
| Missing untracked files in output | Running inside a git repo with default git-based discovery | Check .gitignore, or run with --include-hidden / adjust ignore rules |
--git-dates appears slow |
Uses git log history traversal |
Omit --git-dates for faster scans |
| HTML report not opening as expected | Output path/extension mismatch | Export with .html or .htm extension |
License
MIT © kelexine