Paste an ASCII directory tree, get real folders and files in seconds.
Copy a tree-style listing from a README, an AI answer, or your own notes —
tree2dir turns it into an actual directory structure on disk.
my-app/
├── src/
│ ├── main.rs
│ └── config.rs
├── tests/
│ └── integration_test.rs
├── .gitignore
└── README.md
↓
$ tree2dir --file structure.txt
✔ Successfully generated structure!
├── 📁 my-app
├── 📁 src
├── 📄 main.rs
├── 📄 config.rs
├── 📁 tests
├── 📄 integration_test.rs
├── 📄 .gitignore
├── 📄 README.md
Done in 2.5ms. Created 3 directories and 4 files.Русская версия: README.ru.md
- Three input modes — interactive TUI, Unix pipe, or
--file. - Any indentation style — box-drawing characters (
│├└─), plain spaces, tabs, or output straight from thetreecommand. Depth is measured in Unicode scalar values, not bytes, so mixed indentation styles at the same visual depth are handled correctly. - Smart directory detection — a trailing
/, or simply having nested children in the tree, is enough; no need to annotate every folder. - Safe by default — refuses to write outside the target directory
(path-traversal guard), skips existing files unless
--forceis passed, and supports--dry-runto preview without touching disk. - Fast — typical trees build in single-digit milliseconds.
cargo install tree2dirOr download a prebuilt binary from the Releases page for Linux, macOS, or Windows.
Run with no arguments inside a real terminal:
tree2dirPaste or type your tree, then press Enter to build it in the current directory.
cat structure.txt | tree2dirtree2dir --file structure.txt --output ./my-project| Flag | Description |
|---|---|
-f, --file <PATH> |
Read the tree from a file instead of stdin/TUI |
-o, --output <DIR> |
Target directory (default: current directory) |
--dry-run |
Show what would be created, without touching disk |
--force |
Overwrite files that already exist |
-y, --yes |
Skip the confirmation prompt |
--no-tui |
Never launch the TUI, even in an interactive terminal |
| Key | Action |
|---|---|
Enter |
Confirm and build the structure |
Shift+Enter / Alt+Enter |
Insert a newline while editing |
Ctrl+V |
Paste from the system clipboard |
Ctrl+E |
Load the built-in example tree |
Ctrl+R |
Clear the input buffer |
Esc / Ctrl+C |
Quit without writing anything to disk |
Arrow keys, Home, End |
Move the cursor |
Backspace, Delete |
Edit text |
Indentation is measured by counting Unicode scalar values
(.chars().count()) in the leading whitespace/box-drawing prefix of each
line — not raw bytes. This matters because │ is 3 bytes in UTF-8 while a
space is 1 byte; byte-length comparisons would misjudge depth. Counting
scalars instead means a │-based prefix and an equivalent-width
space-based prefix are always treated as the same depth, regardless of
locale or terminal font.
A line is classified as a directory if either:
- its name ends with
/, or - the next non-blank line in the input is indented one level deeper (i.e. it has children).
Otherwise it's treated as a file. This means trailing slashes are
optional — raw tree command output (which usually omits them) parses
correctly out of the box.
Before writing anything to disk, every resolved path is checked against
the output root: entries can't use .., an absolute path, or a Windows
drive prefix to escape the target directory. This is checked both on the
raw path segment and on the final joined path, so it holds even if a
segment slips past the first check.
git clone https://github.com/NiZaMinius/tree2dir.git
cd tree2dir
cargo build --release
cargo testIssues and pull requests are welcome — see Discussions
for questions or ideas before opening a PR. Please run cargo fmt and
cargo clippy -- -D warnings before submitting.
Licensed under either of Apache License, Version 2.0 or MIT license at your option.