Flatten is a CLI tool that takes a directory as input and outputs a flat representation of its contents to stdout. It recurses into subdirectories and collects every file (even large ones, if you enable that) in a single readable listing. It's handy for quick overviews, backups, or curious exploration.
You can toggle metadata details like last modified time, file permissions, sizes, checksums, and more. You can also include or exclude certain special files or directories with options like --include-git, --include-gitignore, or --include-bin if you want your binary files included.
--compress: Enable compression (equivalent to--compress-level 1).--compress-level: Choose how aggressively to compress the output.- Level 1 (default): compact whitespace (removes blank lines) + collapse consecutive repeated line blocks + extract large repeated blobs.
- Level 2: additionally removes comment-only lines (language-aware, best-effort) and uses more aggressive blob/repeat detection.
- Level 3 (most aggressive, lossy): additionally truncates very large blocks (e.g. long files/command outputs) with markers like
(...<<<omitted N lines>>>...)/(...<<<omitted N bytes>>>...). For large code files, it also injects an outline of top-level definitions from the omitted section. Extracted blobs may also be truncated.
Download the latest release from the GitHub Releases page. Binaries are available for:
- Linux (amd64, 386, arm64, arm)
- macOS/Darwin (amd64, arm64)
- Windows (amd64, 386, arm64)
- FreeBSD (amd64, 386, arm64)
Grab Go 1.21 or newer, clone this repository, then run:
go install github.com/agusx1211/flatten/cmd/flatten@latestOr build locally:
git clone https://github.com/agusx1211/flatten.git
cd flatten
make builddocker run --rm -v $(pwd):/workspace ghcr.io/agusx1211/flatten:latestmake build
# or
./build-local.shmake build-all
# or
./build.sh [version]make build- Build for current platformmake build-all- Build for all platformsmake test- Run testsmake clean- Clean build artifactsmake install- Install to GOPATH/bin
Just a recent version of Go. There are a few external libraries for CLI and .gitignore parsing, but they're fetched automatically when you build or install.
Flatten doesn't do partial merges or transformations, it just gathers files and prints them out. If your directory is massive, the output can get really big. If you skip binary files, that might miss some unusual ones.
If you run flatten . in a small project, you might see something like:
- Total files: 4
- Total size: 18368 bytes
- Dir tree:
.
├── .gitignore
├── cmd
│ └── flatten
│ ├── filter.go
│ └── main.go
└── go.mod
- path: .gitignore
- content:
/dist/
/node_modules/
And so on, with optional metadata if you enabled it.
Below is the help output for quick reference:
Usage:
flatten [directories]... [flags]
Flags:
-a, --all-metadata Show all metadata
--command stringArray Command to run after flattening (can be repeated)
--copy Copy output to the system clipboard
--compress Compress output by collapsing repeats and extracting large repeated blobs
--compress-level int Compression level (0=off, 1=default, 2=more, 3=most aggressive)
-d, --dry-run List all files that would be included without processing content
-E, --exclude strings Exclude files matching these patterns (e.g. '*.test.js')
-h, --help help for flatten
-I, --include strings Include only files matching these patterns (e.g. '*.go,*.js')
--include-bin Include binary files in the output
-g, --include-git Include .git directory
-i, --include-gitignore Include files normally ignored by .gitignore
--include-locks Include lock files (package-lock.json, yarn.lock, etc.)
-l, --last-updated Show last updated time for each file
--line-numbers Include line numbers in file and command output content
--markdown-delimiter string Markdown code block delimiter (auto, <3 backticks>, ~~~, <5 backticks>, ~~~~~, ~~~~~~~~~~~) (default "auto")
--no-dedup Disable file deduplication
--print Print output to stdout (default)
--prefix string Optional message printed before output, wrapped by --- lines
-p, --profile string Profile to use when reading .flatten files (default "default")
--set-default Persist the selected output mode to ~/.flatten
--silent Suppress token report output (useful with --copy/--ssh-copy)
--ssh-copy Copy output to the terminal clipboard over SSH using OSC 52
-c, --show-checksum Show SHA256 checksum of files
-M, --show-mime Show file MIME types
-m, --show-mode Show file permissions
-o, --show-owner Show file owner and group
-z, --show-size Show individual file sizes
-y, --show-symlinks Show symlink targets
-Z, --show-total-size Show total size of all files
--suffix string Optional message printed after output, wrapped by --- lines
--tcount Print token count of the full output (equivalent to: flatten | tcount)
--tcount-detailed Print token count and a breakdown of token usage by path/section
--tcount-model string Model to use for token-counting the full output (defaults to --tokens-model)
-t, --tokens Show token usage for each file/directory
--tokens-model string Model to use for --tokens (per-file token counting) (default "gpt-4o-mini")
-v, --version version for flatten
Note: --include (and any include rules from .flatten) still respect .gitignore by default. To include files that are ignored by .gitignore (like go.sum in this repo), pass --include-gitignore.
--command: Command to run after flattening (can be repeated). Each command runs in the current working directory, and its start/end time, duration, exit code, stdout, and stderr are appended to the end of the flatten output.
Examples:
flatten . --command "go test ./..." --command "git status --porcelain"flatten repoA repoB --command "ls -la"
Use --prefix and/or --suffix to add custom messages before/after the output. When either flag is provided, the main flatten output is wrapped by delimiter lines ---.
Example:
flatten . --prefix "Start of snapshot" --suffix "End of snapshot"
This prints:
Start of snapshot
---
...<flatten output here>...
---
End of snapshot
--print(default): write the flattened output to stdout.--copy: copy the full output to the system clipboard.--ssh-copy: copy the full output via OSC 52.
When using --copy or --ssh-copy, --tcount-detailed is printed to stdout automatically unless --silent is set.
To persist a default output mode, run flatten --copy --set-default (or --ssh-copy / --print). This stores output: copy in ~/.flatten.
If you want to estimate how many tokens the full output would be for an OpenAI model (without actually printing it), use:
--tcount: prints the total token count (equivalent toflatten | tcount)--tcount-detailed: prints the total plus a breakdown of the largest contributors (top-level, directories, files, and other sections)--tcount-model: sets the model used for counting (defaults to--tokens-model)
Examples:
flatten . --tcount
flatten . --tcount-detailed
flatten . --tcount --tcount-model gpt-4o-miniMIT License
Copyright (c) 2023
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.