ctxstash
v0.1.0
Published
Pack a codebase into one LLM-ready Markdown file with a file tree and token estimate. Zero dependencies, no server.
Maintainers
Readme
ctxstash
Pack a codebase into one LLM-ready Markdown file — with a file tree and a token estimate. Zero dependencies, no server, no telemetry.
You're feeding code to ChatGPT / Claude / Cursor and you keep doing the same dance: open file, copy, paste, label it, repeat — then guess whether it'll blow the context window. ctxstash does it in one command: walk a directory, skip the junk (node_modules, lockfiles, binaries), and emit a single tidy Markdown document with every file fenced and language-tagged, prefixed by a tree overview and an approximate token count.
npx ctxstash src > context.md✓ packed 23 files · 142.3 KB · ~38,210 tokensThere's a matching, behavior-identical Python version: pip install ctxstash.
Install
npm install -g ctxstash # then: ctxstash ...
# or just run it without installing:
npx ctxstash .Requires Node ≥ 18. No dependencies.
Usage
ctxstash [paths...] [options]ctxstash . # pack the current dir to stdout
ctxstash src test > context.md # pack two dirs, redirect to a file
ctxstash . -o context.md # ...or write the file directly
ctxstash . -i "*.ts,*.tsx" # only TypeScript
ctxstash . -e "*.test.js,*.snap" # drop tests and snapshots
ctxstash . --estimate # just tell me the token cost
ctxstash src --tree # just the file treeOptions
| Option | Description |
| --- | --- |
| -o, --out <file> | Write to a file instead of stdout |
| -i, --include <globs> | Only include matching files (comma-separated, e.g. "*.js,*.ts") |
| -e, --exclude <globs> | Exclude matching files (comma-separated) |
| --tree | Print only the file tree (no contents) |
| --no-tree | Omit the file-tree overview from the packed output |
| --estimate | Print only stats (files, size, ~tokens) — pack nothing |
| --max-size <size> | Skip files larger than this (e.g. 256kb, 1mb; default: no limit) |
| --no-default-ignore | Don't auto-skip node_modules / .git / dist / lockfiles / etc. |
| --no-color | Disable colored stderr |
| -h, --help · -v, --version | |
Globs support * (within a path segment), ** (across segments), and ?. A
slash-less pattern like *.js matches at any depth.
What you get
# Repository context
> Packed by ctxstash — 3 files, 4.1 KB, ~1,040 tokens (estimate).
## File tree
```
src/
core.js
cli.js
README.md
```
## Files
### src/core.js
```javascript
...file contents...
```The summary line always goes to stderr, so ctxstash > context.md keeps the
file clean while you still see the count in your terminal.
Notes & limits
- Binary files are skipped automatically (NUL-byte / control-byte sniff), so images and compiled artifacts never end up in your context.
- Token counts are an estimate (~4 characters per token, OpenAI's rule of thumb) — tokenizer-agnostic and good enough for "will this fit?", not exact billing. For precise counts, run the output through a real tokenizer.
- Fences are collision-safe: if a file contains a
```run, ctxstash wraps it in a longer fence so the Markdown stays valid. - Symlinks are not followed (avoids loops).
License
MIT
