Local Folder to Text: Your Codebase Into One File, Without Uploading It
Point this at a folder on your machine and you get back a single text file: a directory tree at the top, then every file you selected, each one separated by a header with its path. Whatever you call it — combining a codebase into one file, concatenating source files, merging a directory into one document — that's the whole idea. It's the format an LLM handles best, because the model can see the shape of the project and the contents at the same time, and it can reason about how one file relates to another.
It's free, there's no sign-up, and there's nothing to install. Pick a folder, untick what the model doesn't need, and export the project as a single text file you can paste anywhere.
The part most people care about: nothing is uploaded. There is no server in this pipeline. Your files are read in the browser, assembled in memory, and handed back to you. If you've been avoiding online converters because the codebase belongs to a client, or is under NDA, or simply isn't yours to paste into a third-party service, that objection doesn't apply here — and the next section explains exactly why, because "trust us, it's secure" is not an answer anyone should accept.
How a Private Codebase to Text Converter Actually Works Without Uploading
Modern browsers can read files from disk without sending them anywhere. When you choose a folder, the
browser hands the page a list of file handles. Each one is read with the standard
FileReader API, which decodes the bytes into a string in the tab's own memory. The
directory tree, the token count, the concatenation — all of it happens in JavaScript running on your
machine. There is no fetch, no XHR, no API endpoint, no third-party analytics call
carrying file contents. Open your browser's network tab while you convert and you'll watch it stay
empty.
That mechanism has some useful side effects beyond privacy:
- It works offline. Once the page has loaded, pull the ethernet cable. Conversion still runs. Useful on an air-gapped machine or a locked-down corporate network.
- No upload limits or rate limits. There's no API quota to hit, because there's no API. The only ceiling is your browser's memory and your patience.
- It works on code that was never committed. A scratch branch, an untracked
experiment, a folder that has never seen a
git init— the GitHub repo to text converter can't touch any of those, because it reads from the GitHub API. This one reads from disk, so it doesn't care about your version control situation at all. - Nothing is retained. Close the tab and the state is gone — no history to purge, no account holding a copy of your source.
Three Ways to Get a Project In
Use the directory picker to browse to a folder, or drag the folder straight from Finder or Explorer onto the drop zone. Both walk the tree recursively, so you get the whole project including nested subdirectories, not just the top level.
You can also drop a ZIP archive and it gets unpacked in the browser — handy when someone emailed you a project, or you'd rather not extract it at all. One distinction worth knowing: use this page when the archive holds a code project, because you want the directory tree and per-file path headers. If it's a pile of documents — reports, spreadsheets, PDFs — ZIP to text or ZIP to Markdown fits better, since those pull the readable content out of each document instead of treating files as source.
Any IDE, Any Editor — It Only Wants a Folder
There's no plugin to install and no extension to approve, because this doesn't integrate with your editor at all. It takes a directory. Whether that directory happens to be a VS Code workspace, an IntelliJ IDEA or PyCharm project, a Visual Studio solution, an Android Studio module, an Xcode project, an Eclipse workspace, or a folder you've only ever opened in Neovim, it's the same set of files on the same disk. Point the picker at it and you're done.
Worth spelling out, because "export my VS Code project as a single TXT" and "export an IntelliJ project to one file" are questions people tend to ask their editor first. Editors are usually the wrong place to look. They export files, one at a time. A few have a marketplace extension that half-solves it, most don't, and each solves it differently, so an answer for one IDE is useless the moment you switch. The folder is the common denominator.
It's also a better move than zipping the project and sending it. An archive is fine developer to
developer, but a chat model wants text, not a container, and a reviewer has to extract it before
reading a line. A consolidated .txt is readable
inline: paste it into a conversation, attach it to a ticket, drop it in an email thread. And if
someone has already sent you a ZIP, you can drop that straight onto this page rather than
unpacking it first.
Prune Hard Before You Generate
This is the step people skip, and it's the one that decides whether the output is usable. Everything starts ticked in the checkbox tree, which means by default you're about to include a lot of things no model needs to see.
One thing works in your favour here. If the folder contains a .gitignore, it gets read and
its rules are applied — including nested ones deeper in the tree, scoped to their own directory, with
comment lines skipped. On a normal repo that quietly removes most of the worst offenders before you
touch anything, because the things that bloat a dump are usually the same things you already told git
to leave alone. The .git directory itself is always excluded.
Don't lean on it entirely, though. A folder with no .gitignore — an extracted ZIP, a
vendor handoff, a directory that was never a repo — gets none of that protection. And plenty of noisy
things are legitimately tracked in git. Scan the tree and untick these:
node_modules,vendor,.venv,site-packages. Dependency trees are enormous and none of it is your code. An unprunednode_modulesalone can be hundreds of thousands of tokens of other people's source. It will swamp the actual project and the model's answers will drift toward library internals.- Build output —
dist,build,.next,target,out, coverage reports. It's your own code, minified or transpiled, duplicated. Pure noise. - Lockfiles.
package-lock.json,yarn.lock,poetry.lock,Cargo.lock. Thousands of lines of hashes carrying almost no semantic information. Keep the manifest (package.json,pyproject.toml) — that's the part that tells the model what stack you're on. - Generated code and fixtures — protobuf output, GraphQL codegen, database migrations, large seed or snapshot files.
- Anything with secrets. Nothing is transmitted, but the output file is going into
a chat window eventually. Leave
.envout.
Binary files are handled for you: images, fonts, compiled artifacts and the like are filtered out by extension before they ever reach the tree, and anything that slips through gets caught by a null-byte scan and replaced with a short placeholder rather than dumped as garbage. Files over 1 MB get a placeholder noting the size too, which keeps one stray CSV from eating your entire context budget.
There's also a toggle for the directory tree at the top of the output: filtered shows
only what you selected, full shows the complete structure with your selections marked.
Full is the better choice when you're asking about architecture, because the model can see that a
tests/ directory exists even though you didn't include it. Filtered is better when you
want the model focused narrowly and nothing else.
Staying Inside the Context Window
The generated output comes with a real token count, produced by the gpt-tokenizer library
rather than a characters-divided-by-four guess. Check it against your model before you paste. It's a
far better workflow than pasting, waiting, and getting a length error back.
Rough guidance on how much to send. Send the whole project when it's small enough to fit comfortably and your question is architectural — "where does authentication actually get enforced", "what would break if I changed this interface", "explain the data flow from request to database". The model needs the full picture to answer those honestly, and a partial dump produces confident guesses about files it never saw.
Send a slice when the question is local — one module plus the tests that cover it, plus the two or three files it imports from. Smaller context means sharper answers and less drift, and you'll usually get better results from 5,000 well-chosen tokens than 200,000 indiscriminate ones.
Monorepos need a deliberate approach. Don't convert the repo root. Convert one package at a time, and if that package depends on a shared internal library, include that library's public surface alongside it. If you need cross-package context, a good trick is to run two passes: one full tree with almost no files selected — that gives the model a map — and then a second, file-heavy pass on the package you're actually working in.
Why Not Just Run cat or a Shell Script?
Fair question, and sometimes the honest answer is that you should. If you want three known files
joined together, cat auth.py models.py routes.py > out.txt is quicker than opening a
browser. Nobody is trying to talk you out of that.
Where it stops paying off is the moment you aim it at a whole project. Run
find . -type f -exec cat {} + on a real repo and here's what you get:
- Binaries in the middle of your source. PNGs, fonts, compiled objects, a stray SQLite fixture — all of it decoded as text, all of it mojibake. You then start maintaining an extension whitelist.
- The whole dependency tree.
node_modules,.venv,vendor,target, and the contents of.gititself. Excluding those means writing prune expressions and keeping them current for every project you work on. Here, your.gitignorealready describes exactly that, nested files included, and it gets applied for you. - No idea how big it is. Concatenation gives you bytes, not tokens, and dividing characters by four is a guess that's wrong in both directions. You find out it doesn't fit when the model refuses it.
- Selective control costs more script. "Everything under
srcexcept the generated API client, plus the two config files at the root" is another flag and another regex. A checkbox tree does that in about four clicks. - No map at the top. Raw concatenation is a wall of text with no structure header, so the model can't tell where one file ends and the next begins, or what the project's layout looks like. Path-delimited sections and a directory tree are most of what makes a dump legible.
All of it is buildable, and plenty of people have built it. It's an afternoon of scripting and then a small tool you maintain. The trade is whether you want the script or the output.
What People Actually Use This For
- The codebase you just inherited. Someone left, and now a 40,000-line service is yours. Convert it, paste it, and ask for the entry points, the main abstractions, and the three things that would most surprise a new maintainer. It's a faster orientation than any handover document you'll be given.
- Documentation from real source. READMEs rot because they're written once. Generate them from the code that exists right now — architecture overviews, module summaries, an accurate list of environment variables the app actually reads.
- Tests for untested code. Include the module plus one existing test file as a style reference. The model matches your framework, your naming, your fixture patterns, instead of inventing a testing convention you don't use.
- Migration and refactor planning. Class components to hooks, JavaScript to TypeScript, one ORM to another. A model that can see every call site gives you a real plan rather than a generic checklist.
- RAG and embeddings. A single clean text file with path-delimited sections is straightforward to chunk on those delimiters and push into a vector store.
When you're done, copy the output to the clipboard or download it as a .txt file — worth
keeping if you'll reuse the same context across several conversations.
Code Is Only Half the Context
Most real questions about a project also involve things that aren't source files. The spec lives in a PDF, the schema in a JSON file, the config in XML, the data in a CSV. Convert those separately and paste them alongside your codebase dump: PDF to Markdown for specs and vendor documentation, Word to Markdown for requirements docs, JSON to Markdown for API payloads and schemas, XML to Markdown for legacy config, CSV to Markdown for sample data, and HTML to Markdown for exported pages. If you'd rather not pick a format, File2Txt takes whatever you throw at it.
Frequently Asked Questions
How do I convert a folder to a text file?
Pick a directory above and you get its tree as a checkbox list. Tick the files you want and export a single text file — directory structure first, then each file under a header with its path. Free, no sign-up, nothing to install.
Is my code uploaded to a server?
No. There is no server in this pipeline at all. The folder is read in the browser, the output is assembled in the browser, and nothing crosses the network — you can open devtools and watch, or disconnect from the internet after the page loads and it still works. That is the difference between this and the GitHub converter, which has to call the API.
Is it safe to convert a company codebase online?
This page is the version that answers that question with mechanics rather than a promise: the files never leave the machine, so there is nothing to trust us about. What still matters is what you do next — pasting the output into a hosted model sends it to that provider, so check your organisation's policy and strip secrets before you do.
Can I convert a whole project including subfolders?
Yes, the entire tree is walked and every level is selectable. Deselecting a folder removes everything under it in one click, which is how you drop node_modules or .git without hunting through children. The token counter updates as you go so you can see the effect immediately.
Which browsers can pick a whole folder?
Folder selection uses the directory-upload attribute that Chrome, Edge, Firefox and Safari have all supported for years, so any current desktop browser works. Mobile browsers are the gap — neither iOS nor Android exposes a folder picker. On a phone, zip the directory and use ZIP to text instead.
What is the file size limit?
There is no upload, so there is no upload limit — the constraint is your machine's memory and how much text you can usefully paste anywhere afterwards. In practice the token counter becomes the real limit long before the browser does. A repository whose useful source is under a megabyte covers most projects once dependencies are deselected.
The Rest of the Toolkit
If the code is hosted rather than local, the GitHub to text converter and the GitLab to text converter do the same job against a remote repository, including private ones with a token. For documentation that only exists on the web, Web2Txt scrapes a URL into clean Markdown — pair a scraped API reference with your local source and a coding assistant can see both sides at once.
There's more written up on the blog if you want to go further: turning a codebase into an LLM-ready file, a walkthrough of the folder to text converter, a guide to feeding a whole repository into an AI, and the general file to text conversion guide for everything that isn't code.
Repo2Txt is built and maintained by v12hero, an independent developer building privacy-first native and web apps.