shell-history-stats
v1.0.0
Published
π¨ Analyze your local shell history (fish, zsh, bash) and build statistics of the most used commands, subcommands and flags
Downloads
139
Maintainers
Readme
shell-history-stats
π¨ Analyze your local shell history and find out which commands, subcommands and flags you actually use - and which options you never touch.
npx shell-history-stats
Features β¨
- π Reads fish, zsh and bash history, together or one at a time
- π Expands your aliases, so
gccounts asgit commitand still shows which shorthand you typed - π Ranks your most used aliases, with the share of your typing they cover and the characters they save
- π© Reports the flags you actually use per command, with the share of runs that had no flags at all
- π³ Breaks multitools into subcommands (
git commit,npm run,docker build) - π§΅ Splits pipelines, so
ls | grep foocounts as two invocations rather than one - π© Sees through wrappers -
sudo apt installcounts towardsapt, notsudo - π°οΈ Shows when you work by hour, weekday and month, and says how many entries lacked a timestamp
- π Ranks the directories you work in (fish records them)
- π©Ί Flags likely typos and long commands that deserve an alias
- π‘οΈ Masks anything that looks like a secret before it reaches the report
- π Prints tables, or writes Markdown, JSON and a self-contained HTML page
- π¦ Zero runtime dependencies
Installation π¦
npm install --global shell-history-statsOr run it without installing:
npx shell-history-statsUsage π
# every history file found on this machine
shell-history-stats
# one shell, longer rankings
shell-history-stats --shell fish --top 30
# a Markdown report for your notes
shell-history-stats --format markdown --out stats.md
# JSON and HTML from the last 90 days
shell-history-stats --format json,html --out report --since 90dOptions
| Option | Description |
| :-- | :-- |
| --shell <name> | Limit to one shell: fish, zsh or bash. Repeatable. |
| --file <path> | Read this history file instead of the discovered ones. Repeatable. |
| --format <list> | terminal, markdown, json, html. Comma separated. |
| --out <path> | Write to a file. With several formats it is used as a prefix. |
| --top <n> | Entries per ranking. Default 20. |
| --since <date> | Only entries at or after 2026-01-01, or a span like 30d, 6m. |
| --no-redact | Do not mask values that look like secrets. |
| --no-aliases | Do not expand shell aliases into their target command. |
| -h, --help | Show help. |
| -v, --version | Show the version. |
Example output π
An excerpt from a run over a sample history - your own report also covers flags, working hours, directories and hygiene.
Entries: 1360 Invocations: 1377 Unique commands: 26
Ran without any flag: 894 of 1377 (64.9%)
Shells
βββββββββ¬ββββββββββ¬ββββββββββββββ¬βββββββββ
β Shell β Entries β Invocations β Share β
βββββββββΌββββββββββΌββββββββββββββΌβββββββββ€
β fish β 1360 β 1377 β 100.0% β
βββββββββ΄ββββββββββ΄ββββββββββββββ΄βββββββββ
Top commands
βββββ¬ββββββββββ¬ββββββββ¬ββββββββ¬βββββββββββ¬βββββββββββββββββββββ
β # β Command β Count β Share β No flags β Via alias β
βββββΌββββββββββΌββββββββΌββββββββΌβββββββββββΌβββββββββββββββββββββ€
β 1 β git β 585 β 42.5% β 54.2% β gst (62), gp (28) β
β 2 β npm β 257 β 18.7% β 100.0% β nrb (17), nrt (13) β
β 3 β ls β 158 β 11.5% β 44.3% β ll (34) β
β 4 β cd β 60 β 4.4% β 100.0% β β
β 5 β docker β 59 β 4.3% β 23.7% β dc (9) β
βββββ΄ββββββββββ΄ββββββββ΄ββββββββ΄βββββββββββ΄βββββββββββββββββββββ
Most used aliases
227 of 1377 invocations (16.5%) were typed as an alias
βββββ¬ββββββββ¬βββββββββββββ¬ββββββββ¬βββββββββββββ¬ββββββββββββββ
β # β Alias β Expands to β Count β Of aliases β Chars saved β
βββββΌββββββββΌβββββββββββββΌββββββββΌβββββββββββββΌββββββββββββββ€
β 1 β gst β git status β 62 β 27.3% β 434 β
β 2 β ll β ls β 34 β 15.0% β 136 β
β 3 β gp β git push β 28 β 12.3% β 168 β
β 4 β gd β git diff β 24 β 10.6% β 144 β
β 5 β gcm β git commit β 21 β 9.3% β 210 β
βββββ΄ββββββββ΄βββββββββββββ΄ββββββββ΄βββββββββββββ΄ββββββββββββββHow it reads your history π
Each shell stores history differently, and the parser handles each one on its own terms.
| Shell | Format | Timestamps |
| :-- | :-- | :-- |
| fish | YAML-like, with optional paths: per entry | Always |
| zsh | : <started>:<elapsed>;<command> | With EXTENDED_HISTORY |
| bash | One command per line | Only with HISTTIMEFORMAT |
Sections that need a timestamp say how many entries they had to skip, so a bash-heavy machine never silently reports a partial picture.
[!NOTE] Aliases are read by asking your shell for its own alias table, because plugin frameworks like oh-my-zsh define most aliases at load time rather than in a file. Use
--no-aliasesto skip that step.
Privacy π‘οΈ
Everything runs locally - no network access, no telemetry. Values that look like credentials are masked before they reach any output, so a report is safe to paste into notes or an issue: API tokens, --password and -pSecret, user:password pairs in an argument or a connection URI, secrets carried by a header, and long opaque strings. Your home directory is shortened to ~, so a report does not name your account. Counts are computed before masking, so the numbers stay correct. Pass --no-redact if you want the raw text.
API π
The package can also be used as a library:
import {
discoverHistorySources,
readHistorySources,
parseEntries,
buildReport,
renderMarkdown,
} from "shell-history-stats";
const entries = readHistorySources(discoverHistorySources());
const report = buildReport(entries, parseEntries(entries), {
top: 20,
redactSecrets: true,
});
console.log(renderMarkdown(report));Development π οΈ
npm install
npm test
npm run buildThe landing page in site/ is static. npm run site:build copies the recorded demo next to it and renders site/report.html from demo/history.fish - a synthetic history kept in the repository so the sample report never contains anyone's real commands. Both generated files are ignored by git.
Known limitations π§
- The contents of command substitutions (
$(...), backticks) are counted as one opaque argument rather than analysed. - Typo detection is a heuristic: a rare command one edit away from a frequent one. Real tools with short names occasionally show up.
- Only fish records working directories, so the directory ranking covers a subset of your history.
License π
The MIT License @ 2026
