Skip to main content

CodeToTxt

CodeToTxt is a small Python tool that flattens a codebase into a single text file. It's built for feeding code into LLMs, but it works just as well for code review, documentation, or just having a searchable snapshot of a project.

Features

  • Convert an entire directory of code into one text file
  • Optional directory tree at the top of the output
  • Respects .gitignore automatically (including parent directories)
  • Filter files by extension or glob pattern
  • Custom separators and output formatting
  • Copy straight to the clipboard instead of (or in addition to) writing a file
  • Dry-run and stats modes to see what you're about to process before you commit to it
  • Config file support so you don't have to repeat the same flags every time
  • Token estimate in the output, since that's usually what people actually care about

Installation

pip install code-to-txt

Or with Poetry:

poetry add code-to-txt

Quick start

# Show version
code-to-txt --version

# Convert everything in the current directory, with a timestamped filename
code-to-txt -t

# See what would be processed without writing anything
code-to-txt --dry-run

# Get a quick summary of the codebase
code-to-txt --stats

# Convert a specific directory
code-to-txt ./my-project -o project.txt

# Skip the file and just copy the result to the clipboard
code-to-txt --clipboard-only

Choosing file types

# Multiple extensions (space or comma separated, both work)
code-to-txt -e ".py .js .ts"
code-to-txt -e ".py,.js,.ts"

# Or use glob patterns instead
code-to-txt -g "*.py" -g "src/**/*.js"

More options

# Skip files above a certain size (handy for staying under token limits)
code-to-txt --max-file-size 500

# Exclude specific patterns
code-to-txt -x "tests/*" -x "*.test.js"

# Ignore .gitignore entirely
code-to-txt --no-gitignore

# Leave out the directory tree
code-to-txt --no-tree

# Use a different separator between files
code-to-txt --separator "---"

# Combine whatever you need
code-to-txt -t -c -e ".py .js" -x "tests/*"

Configuration file

Rather than typing the same flags every time, you can generate a config file:

code-to-txt --init-config

This creates .code-to-txt.yml:

# Output file name
output: code-to-txt.txt

# File extensions to include (null = use defaults)
extensions: null

# Patterns to exclude
exclude:
  - "tests/*"
  - "*.test.js"
  - "*.test.ts"
  - "*.spec.js"
  - "*.spec.ts"
  - "node_modules/*"
  - "__pycache__/*"
  - "*.pyc"

# Glob patterns (alternative to extensions)
glob: []

# Options
no_gitignore: false
no_tree: false
separator: "================"
clipboard: false
clipboard_only: false
timestamp: true
max_file_size: null

Then point the CLI at it:

code-to-txt --config .code-to-txt.yml

Any CLI flag you pass will override the matching setting in the config file.

A few example configs

Python project:

extensions: [ .py ]
exclude: [ "tests/*", "*.pyc", "__pycache__/*", "venv/*", ".venv/*" ]
timestamp: true
max_file_size: 500

JavaScript/TypeScript project:

extensions: [ .js, .ts, .jsx, .tsx ]
exclude: [ "node_modules/*", "dist/*", "build/*", "*.test.js", "*.spec.ts" ]
no_tree: false
max_file_size: 1000

Tuned for LLM input:

extensions: [ .py, .js, .md ]
exclude: [ "tests/*", "*.test.*", "node_modules/*", "dist/*", "build/*" ]
timestamp: true
clipboard: true
max_file_size: 200
no_tree: false

Command line options

Usage: code-to-txt [OPTIONS] [PATH]

Arguments:
  PATH                    Directory to scan (default: current directory)

Options:
  -o, --output PATH       Output file path (default: codetotxt_YYYYMMDD_HHMMSS.txt)
  -e, --extensions TEXT   File extensions to include (space or comma separated)
  -x, --exclude TEXT      Patterns to exclude (can be used multiple times)
  -g, --glob TEXT         Glob patterns to include (can be used multiple times)
  --no-gitignore          Don't respect .gitignore files
  --no-tree               Don't include directory tree in output
  --separator TEXT        Separator between files
  -c, --clipboard         Copy output to clipboard in addition to file
  --clipboard-only        Copy to clipboard only (don't save file)
  --config PATH           Path to config file (.yml or .yaml)
  --init-config           Create default configuration file
  -t, --timestamp         Add timestamp to output filename
  -v, --version           Show version and exit
  --dry-run               Show which files would be processed
  --stats                 Show detailed statistics
  --max-file-size INT     Skip files larger than N KB
  --help                  Show this message and exit

Using it as a library

You don't need the CLI. Everything is available directly from the CodeToText class.

Basic conversion

from code_to_txt import CodeToText

code_to_txt = CodeToText(
    root_path="./my-project",
    output_file="output.txt",
    include_extensions={".py", ".js"},
)

num_files = code_to_txt.convert(add_tree=True)
print(f"Processed {num_files} files")

Generating content without writing to disk

from code_to_txt import CodeToText
import pyperclip

code_to_txt = CodeToText(
    root_path="./my-project",
    output_file=None,
    include_extensions={".py"},
)

content = code_to_txt.generate_content(add_tree=True)
pyperclip.copy(content)

Getting statistics

from code_to_txt import CodeToText

code_to_txt = CodeToText(
    root_path="./my-project",
    output_file=None,
    max_file_size_kb=500,
)

stats = code_to_txt.calculate_statistics()
print(f"Total files: {stats['total_files']}")
print(f"Total size: {stats['total_size_bytes'] / 1024 / 1024:.2f} MB")
print(f"Total lines: {stats['total_lines']:,}")

Using glob patterns

from code_to_txt import CodeToText

code_to_txt = CodeToText(
    root_path="./my-project",
    output_file="output.txt",
    glob_patterns=["*.py", "src/**/*.js", "**/*.md"],
)

num_files = code_to_txt.convert()

Default file extensions

If you don't specify extensions or glob patterns, CodeToTxt includes these by default:

  • Python: .py
  • JavaScript/TypeScript: .js, .ts, .jsx, .tsx
  • Systems languages: .c, .cpp, .h, .hpp, .java, .cs, .go, .rs
  • Web: .html, .css, .scss
  • Config: .yaml, .yml, .json, .toml, .xml
  • Docs: .md, .txt, .rst
  • Scripts: .sh, .bash, .zsh
  • Other: .rb, .php, .swift, .kt, .scala, .r, .sql

Default ignore patterns

These are excluded automatically, on top of whatever's in your .gitignore (parent directories included, up to five levels up):

  • __pycache__, *.pyc, *.pyo, *.pyd
  • .git, .svn, .hg
  • node_modules
  • .venv, venv, .env
  • *.egg-info, dist, build
  • .pytest_cache, .mypy_cache, .ruff_cache
  • *.so, *.dylib, *.dll

Output format

The generated file has three parts:

  1. A header with the source directory and total file count
  2. An optional directory tree
  3. Each file's contents, labeled with its relative path

For example:

Code Export from: /path/to/project
Total files: 4
================================================================================

DIRECTORY TREE:
================================================================================
my-project/
├── src/
│   ├── main.py
│   └── utils.py
├── tests/
│   └── test_main.py
└── README.md

================================================================================

FILE 1/4: src/main.py
================================================================================
def main():
    print("Hello, World!")

if __name__ == "__main__":
    main()

================================================================================
...

Where this is useful

  • Sharing a whole codebase with someone in one file, for review
  • Feeding a project into ChatGPT, Claude, or another AI assistant
  • Generating a quick reference document for a project
  • Doing plain-text search across an entire codebase at once
  • Producing input for other code analysis tools
  • Keeping a simple, flat backup of a project's source

Tips

Preparing input for an LLM

# See what you're dealing with first
code-to-txt --stats

# Preview with a size cap
code-to-txt --dry-run --max-file-size 200

# Then copy it straight to the clipboard
code-to-txt --clipboard-only --max-file-size 200 -e ".py .md"

Working with large projects

# Narrow it down to the extensions you actually care about
code-to-txt -e ".py" -t --max-file-size 500

# Cut out the usual heavy directories
code-to-txt -x "node_modules/*" -x "venv/*" -x "dist/*"

# Check the size before generating anything
code-to-txt --stats --max-file-size 300

Debugging what's being skipped

# See exactly which files are excluded and why
code-to-txt --dry-run

# Compare with .gitignore turned off
code-to-txt --dry-run --no-gitignore

Requirements

  • Python 3.10+
  • Dependencies: click, gitpython, pathspec, pyperclip, pyyaml

Development

# Clone the repository
git clone https://github.com/AndriiSonsiadlo/code-to-txt.git
cd code-to-txt

# Install with Poetry
poetry install

# Run tests
poetry run pytest

# Run linting
poetry run ruff check .
poetry run mypy src/

Contributing

Contributions are welcome. Feel free to open a pull request.

License

MIT License. See the LICENSE file for details.

Changelog

See CHANGELOG.md for the full history of changes.

Author

Created by Andrii Sonsiadlo.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

code_to_txt-0.3.1.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

code_to_txt-0.3.1-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file code_to_txt-0.3.1.tar.gz.

File metadata

  • Download URL: code_to_txt-0.3.1.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.10.20 Linux/6.17.0-1020-azure

File hashes

Hashes for code_to_txt-0.3.1.tar.gz
Algorithm Hash digest
SHA256 dcd561cd919fc8413204aadb4d2acf56226faa0f3aeca18b8c24c38a82c199bc
MD5 6e9f9a857d33c178d698e0bbd93d6640
BLAKE2b-256 2702e10c7889916a10fdb49186fd57d3f82535209d73d81b336755d56f96dd9e

See more details on using hashes here.

File details

Details for the file code_to_txt-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: code_to_txt-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.10.20 Linux/6.17.0-1020-azure

File hashes

Hashes for code_to_txt-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 50ff008d37ec69bb3b81e08d2bbdde3c4cdc6f60484608c4436c25ff8d79f61e
MD5 207409aff6df3326e5b60f26f4db7676
BLAKE2b-256 4440eeefe8847459e2a458f38b02d58804bc83cc677e5ff42dc813d987c60480

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page