fln
v1.2.0
Published
Feed your entire codebase to any LLM in one shot. No attachment limits, no upload hassles.
Maintainers
Readme
🥞 fln
Your entire codebase → one AI-ready file.
Stop wrestling with file pickers and attachment limits — feed your whole project to any LLM in one shot.
npx flnWorks with Claude, ChatGPT, Gemini, Grok, Cursor, Copilot, and any AI tool.
fln (short for flatten) is language-agnostic by design: TypeScript, Python, Rust, Go, Java, mixed monorepos — it treats everything as plain text, auto-detects project metadata from ecosystem manifests, respects .gitignore, and skips binaries automatically.
Why fln exists
If you use LLMs for real projects, you've hit these limits:
- Context windows — large projects don't fit
- Upload friction — selecting dozens of files for every session
- Partial understanding — AI sees fragments, not the architecture
- Manual prep — repeating the same setup context again and again
fln removes that overhead.
It turns your project into a single, structured snapshot that LLMs can actually reason about.
What fln enables
→ Full-context refactoring
Ask architectural questions impossible file-by-file:
"Where is the real coupling here?"
"What should be split into modules?"
→ Instant onboarding
One Markdown file instead of "start by opening these 12 folders." Perfect for reading code on a tablet or onboarding new developers without an IDE.
→ Project-level code reviews
Detect patterns, inconsistencies, and risks across the entire codebase at once.
→ Auditable snapshots
A single, clean artifact of your codebase state for security reviews, compliance audits, or legal records — without granting full repo access.
→ Dataset preparation
Generate clean, formatted data for RAG pipelines and fine-tuning custom models.
→ LLM-friendly diffs
Flatten → commit → flatten again. See how the whole project changed structurally.
Instant clipboard
fln --stdout | pbcopy # macOS
fln --stdout | wl-copy # Linux (Wayland)
fln --stdout | xclip -selection clipboard # Linux (X11)One command — your entire codebase is in the clipboard. Open any AI chat, paste, ask.
Pipe directly to a CLI LLM tool
fln --stdout | llm "What are the biggest architecture issues here?"
fln --stdout | aichat "Write a CHANGELOG entry for the latest changes"
fln --stdout | sgpt "Suggest a refactoring plan for this codebase"Only changed files — perfect for code review
# Everything changed since the last commit
fln --since HEAD~1
# Everything that differs from main
fln --since main
# Only changed TypeScript files (intersection, not union)
fln --since main --ext ts,tsx--since calls git diff --name-only under the hood. Zero config.
Only the file types you care about
fln --ext ts,tsx # TypeScript only — dramatically reduces token count
fln --ext py # Python only
fln --ext rs # Rust only
fln --ext go # Go onlyEmbed a custom prompt right into the snapshot
Put your system prompt in a file — it will be prepended to the output and excluded from the directory tree:
fln --banner-file .prompt.md<!-- .prompt.md -->
You are a senior engineer reviewing a production codebase.
Identify architecture issues, suggest improvements, point out any bugs.Or inline:
fln --banner "Review this codebase for security vulnerabilities."Same for footers: --footer-file / --footer.
Built for real projects
- ⚡ Fast parallel scanning — thousands of files in seconds
- 🎯 Smart filtering — respects
.gitignore, skips binaries and lock files, configurable size limits - 📁 Intentional file order —
README, entry points, and configs first;LICENSE,CHANGELOGlast. LLMs see the most important context first - 📊 Token count upfront — every run reports estimated tokens so you know what you're sending before you hit send
- 🔍 Extension breakdown —
--verboseshows token distribution by file type, so you know exactly what's eating your context window - 🔄 Self-aware — skips files previously generated by
fln, never recurses into its own output - 🛡️ Backtick-safe — if a file contains
```, fln automatically uses longer fences so the Markdown never breaks - 📐 Deterministic output — same input → same snapshot
- 🧠 Project metadata detection — output named
my-app-1.2.0.mdautomatically frompackage.json,Cargo.toml,pyproject.toml,pom.xml,go.mod,vcpkg.json,CMakeLists.txt - 🛠️ Two output formats —
mdfor humans,jsonfor tooling - 🔒 Fully local — zero telemetry, zero network calls, no data leaves your machine
Install
npm / Bun
npx fln # run once without installing
bunx fln
npm install -g fln
bun add -g flnmacOS / Linux — native binary, no Node.js required
curl -fsSL https://fln.nesvet.dev/install | shWindows — native binary, no Node.js required
powershell -c "irm fln.nesvet.dev/install.ps1 | iex"Pin a specific version or install to a custom directory (macOS/Linux):
curl -fsSL https://fln.nesvet.dev/install | FLN_VERSION="<version>" INSTALL_DIR="$HOME/.local/bin" shWindows PowerShell:
$env:FLN_VERSION = "<version>"
$env:INSTALL_DIR = "$env:LOCALAPPDATA\fln\bin"
powershell -c "irm fln.nesvet.dev/install.ps1 | iex"Manual download from GitHub Releases:
curl -L "https://github.com/nesvet/fln/releases/latest/download/fln-macos-x64.tar.gz" | tar -xz -C /usr/local/bin
chmod +x /usr/local/bin/flnUsage
fln [directory] [...flags]
fln init [--overwrite]# Flatten the current directory → my-app-1.2.0.md
fln
# Specify input and output
fln . -o context.md
# Scan src/, save output to the project root
fln src -o .
# Source files only — no tests, no fixtures
fln -e "*.test.ts" -e "*.spec.ts" -e "fixtures/"
# Include all source files but exclude markdown — except README
fln -e "*.md" -e '!README.md'
# TypeScript source only
fln --ext ts,tsx
# Changed files since last commit
fln --since HEAD~1
# Tree only — no file contents
fln --no-contents
# Force-include a file that's in .gitignore
fln -i "src/generated/schema.ts"
# Preview what would be included, with per-extension breakdown
fln --dry-run --verbose
# Overwrite instead of creating codebase-1.md
fln -o codebase.md -w
# JSON output for programmatic use
fln --format json -o snapshot.jsonOutput
| Flag | Description |
|---|---|
| -o, --output <path> | Output file or directory. Adds .md/.json if no extension given. Default: <n>-<version>.md |
| -w, --overwrite | Overwrite instead of adding numeric suffix |
| --stdout | Write to stdout instead of file (implies --quiet) |
| --format <md\|json> | Output format (default: md) |
| --dry-run | Scan and report without writing anything |
Filtering
| Flag | Description |
|---|---|
| -e, --exclude <glob> | Exclude pattern — repeatable |
| -i, --include <glob> | Whitelist mode — only matching files are included, repeatable |
| --ext <ext> | Include only these extensions, e.g. ts,tsx,js |
| --since <ref> | Only files changed since git ref, e.g. HEAD~1, main |
| --include-hidden | Include hidden files and directories |
| --no-gitignore | Ignore .gitignore rules |
| --max-size <size> | Max individual file size, e.g. 10mb, 512kb |
| --max-total-size <size> | Max total size of all included files |
| --follow-symlinks | Follow symlinks while scanning |
Content
| Flag | Description |
|---|---|
| --no-contents | Exclude file contents (tree only) |
| --no-tree | Exclude directory tree |
| --banner <text> | Prepend text after the header |
| --banner-file <path> | Prepend file contents — relative to input, excluded from tree |
| --footer <text> | Append text at the end |
| --footer-file <path> | Append file contents — relative to input, excluded from tree |
| --date <YYYY-MM-DD HH:mm> | Fix the Generated date (useful for reproducible output) |
Logging & other
| Flag | Description |
|---|---|
| -q, --quiet | Minimal output |
| -V, --verbose | Verbose output with per-extension token breakdown |
| --debug | Debug output with full file list |
| --no-ansi | Disable colors |
| --no-sponsor-message | Hide support message (also: FLN_NO_SPONSOR=1) |
| -v, --version | Show version |
| -h, --help | Show help |
Note: Quote glob patterns to prevent shell expansion —
"*.test.ts", not*.test.ts.
To un-exclude a specific file, use negation in--exclude:-e "*.md" -e '!README.md'.
Config file
fln initGenerates .fln.json with full IntelliSense support in VS Code, WebStorm, and any editor with JSON Schema — autocomplete and validation out of the box, no extensions needed.
{
"$schema": "https://fln.nesvet.dev/schema",
"output": "snapshot.md",
"overwrite": false,
"excludePatterns": [ "dist/", "**/*.snap" ],
"includePatterns": [],
"includeHidden": false,
"gitignore": true,
"maxFileSize": "10mb",
"maxTotalSize": "0",
"includeTree": true,
"includeContents": true,
"format": "md",
"followSymlinks": false,
"logLevel": "normal",
"date": "2026-02-20 12:00",
"banner": "You are reviewing a production codebase.",
"bannerFile": ".prompt.md",
"footer": "End of snapshot.",
"footerFile": "docs/footer.md"
}Pattern format: gitignore-style globs relative to the input directory. Leading ./ is normalized. Use ! for negation (*.log + !important.log). Trailing slash src/ matches directories only. CLI flags always override the config file.
CI/CD & Automation
GitHub Actions — auto-generate snapshots
Fresh codebase.md on every push. Download it anytime to chat with LLMs about the exact state of your main branch or a specific PR:
# .github/workflows/codebase-snapshot.yaml
name: Snapshot Codebase
on:
push:
branches: [ "main" ]
pull_request:
jobs:
snapshot:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Generate snapshot
run: npx fln . -o codebase.md -w --no-ansi
- uses: actions/upload-artifact@v6
with:
name: codebase-snapshot
path: codebase.md
retention-days: 7Pre-commit context guard
Fail the commit if the flattened codebase exceeds a size limit — ensures the project always fits in LLM context windows:
# .husky/pre-commit
npx fln . --dry-run --max-total-size 5mbAPI
npm install flnimport { fln } from "fln";
const result = await fln({
input: "./src",
output: "snapshot.md",
excludePatterns: [ "*.test.ts", "fixtures/" ],
onProgress: (current, total) => {
process.stdout.write(`\r${current}/${total} files`);
}
});
console.log(`${result.files} files → ${result.outputPath}`);
console.log(`~${result.outputTokenCount.toLocaleString()} tokens`);Options
| Option | Type | Default | Description |
|---|---|---|---|
| input | string | process.cwd() | Directory to flatten |
| output | string | auto | Output file path or directory. "-" for stdout |
| overwrite | boolean | false | Overwrite instead of numeric suffix |
| excludePatterns | string[] | [] | Glob patterns to exclude |
| includePatterns | string[] | [] | Glob patterns to force include |
| includeHidden | boolean | false | Include hidden files/dirs |
| gitignore | boolean | true | Respect .gitignore rules |
| maxFileSize | number \| string | "10mb" | Max individual file size |
| maxTotalSize | number \| string | 0 | Max total size (0 = unlimited) |
| includeContents | boolean | true | Include file contents |
| includeTree | boolean | true | Include directory tree |
| format | "md" \| "json" | "md" | Output format |
| followSymlinks | boolean | false | Follow symlinks |
| date | string | current | Fixed YYYY-MM-DD HH:mm for Generated header |
| banner | string | — | Text prepended after header |
| bannerFile | string | — | File prepended (relative to input) |
| footer | string | — | Text appended at end |
| footerFile | string | — | File appended (relative to input) |
| logLevel | "silent" \| "normal" \| "verbose" \| "debug" | "silent" | Log level |
| ansi | boolean | false | ANSI colors in log output |
| onProgress | (current, total) => void | — | Progress callback |
Result
type FlnResult = {
projectName: string; // from package.json, pom.xml, Cargo.toml, etc.
files: number; // files included
directories: number; // directories scanned
binary: number; // binary files (shown as [BINARY FILE: X kb] in output)
skipped: number; // skipped — too large, generated by fln, or read errors
errors: number; // read errors
totalSizeBytes: number; // total input size
outputSizeBytes: number; // output file size
outputTokenCount: number; // estimated token count
outputPath: string; // absolute path ("-" for stdout)
};Preview
Real outputs from examples/:
Node.js — requires >=18.3.0, ESM-only ("type": "module"). Install via npm i -g fln or run with npx.
Bun — requires >=1.0.0. Install via bun add -g fln or run with bunx.
Standalone binary — no runtime required. Install via the curl / PowerShell one-liner above.
Support this project
fln is free, open-source, and maintained by one developer.
If it saves you time or improves your AI workflow:
- ⭐️ Star the repo — it genuinely helps discoverability
- 💙 Support on Patreon — keeps development going
Contributing
PRs and issues are welcome. See CONTRIBUTING.md for setup and guidelines.
License
MIT © Eugene Nesvetaev
