| Crates.io | loctok |
| lib.rs | loctok |
| version | 0.2.0 |
| created_at | 2025-08-12 17:05:38.186239+00 |
| updated_at | 2025-08-13 04:11:34.353995+00 |
| description | Count LOC (lines of code) & TOK (LLM tokens), fast. |
| homepage | |
| repository | https://github.com/zxch3n/loctok |
| max_upload_size | |
| id | 1792237 |
| size | 109,038 |
Count LOC (lines of code) & TOK (LLM tokens), fast.
.gitignore, global gitignore, and git excludes)o200k_base (default), cl100k_base, p50k_base, p50k_edit, r50k_base--ext rs,py,ts (case-insensitive, no leading dots)--hiddenOption 1: via npm (prebuilt binary)
npx loctok # run directly
# or
npm i -g loctok # install globally
Option 2: build from source (Rust 1.70+ recommended)
# From crates.io (recommended)
cargo install loctok
# From Git (without publishing)
cargo install --git https://github.com/yourname/loctok --bin loctok
# From the project root (for local testing)
cargo install --path .
# Count tokens in current directory
loctok
# Count tokens in a given path
loctok path/to/dir
# JSON output
loctok --format json > counts.json
# File tree with per-node LOC and tokens
loctok --format tree
# Use a specific encoding
loctok --encoding cl100k_base
# Include only certain extensions (no dots)
loctok --ext rs,md,ts
# Include hidden files (dotfiles)
loctok --hidden
# Progress prints to stderr; to silence in scripts, redirect:
loctok --format json 2>/dev/null
# Concatenate filtered files and copy to clipboard
loctok copy # from current directory
loctok copy path/to/dir # from a given path
# Copy with filters and also print the content
loctok --ext rs,md --hidden copy --show
Run loctok --help to see all options.
The examples below were produced by running against tests/fixtures in this repo.
> loctok
595.171834ms (655.27 files/s)
╭────────────┬───────────────┬─────────────╮
│ Language │ lines of code │ token count │
├────────────┼───────────────┼─────────────┤
│ Rust │ 109,910 │ 894,106 │
│ Other │ 13,705 │ 174,612 │
│ YAML │ 4,668 │ 91,801 │
│ TypeScript │ 6,224 │ 53,639 │
│ Markdown │ 1,584 │ 17,791 │
│ TOML │ 1,260 │ 11,727 │
│ SVG │ 222 │ 10,950 │
│ JSON │ 261 │ 4,001 │
│ Vue │ 214 │ 1,524 │
│ Text │ 119 │ 1,296 │
│ CSS │ 69 │ 420 │
│ JavaScript │ 26 │ 277 │
│ HTML │ 13 │ 112 │
│ Shell │ 5 │ 29 │
│ SUM: │ 138,280 │ 1,262,285 │
╰────────────┴───────────────┴─────────────╯
> loctok --format tree
379.958459ms (21.05 files/s)
Name LOC TOK
--------------------------------------------
┌── lib.rs 332 3,213
├── main.rs 573 4,707
┌── src/ 905 7,920
│ ┌── kept2.txt 1 3
│ ┌── nested/ 1 3
│ ├── kept.txt 1 3
│ ┌── fixtures/ 2 6
│ ├── integration.rs 69 790
├── tests/ 71 796
├── Cargo.lock 877 10,198
├── Cargo.toml 26 201
├── README.md 110 1,174
./ 1,989 20,289
> loctok --format json
{
"by_language": [
{
"language": "Other",
"lines": 877,
"tokens": 10198
},
{
"language": "Rust",
"lines": 974,
"tokens": 8710
},
...
],
"encoding": "o200k_base",
"files": [
{
"lines": 26,
"path": "./Cargo.toml",
"tokens": 201
},
{
"lines": 1,
"path": "./tests/fixtures/nested/kept2.txt",
"tokens": 3
},
...
],
"total": 20431
}
Use copy to bundle filtered files into a single, structured payload that is copied to your clipboard. Optionally print it with --show.
loctok copy [PATH] [--show] [--ext rs,md] [--hidden]
What it does:
Copied 123 lines (22,333 tokens)Snippet of the format:
├── src
│ ├── lib.rs
│ └── main.rs
└── README.md
/src/lib.rs:
--------------------------------------------------------------------------------
1 | use anyhow::{Context, Result};
2 | // ...
/README.md:
--------------------------------------------------------------------------------
1 | # loctok
2 | Count LOC and tokens
.gitignore, global gitignore, and git excludes; also adds .gitignore as a custom ignore file in non-git contexts.MIT or Apache-2.0