A CLI that turns text trees into real folder and file structures. It supports:
- ASCII trees like
treewith│ ├ └ ─ - Space-indented lists
- Path lines like
.github/workflows/ci.ymlorsrc/index.ts
No runtime dependencies, TypeScript only for build.
# (optional) pin pnpm via Corepack and use the frozen lockfile (same as CI)
corepack enable
corepack prepare pnpm@9 --activate
pnpm i --frozen-lockfile
pnpm build
pnpm testpnpm i
pnpm build
node dist/cli.js --helpor run with ts-node
pnpm dev -- --helpInput comes from --from or stdin.
node dist/cli.js --root . --infer-root --gitkeep --from tree.txt
# or
cat tree.txt | node dist/cli.js --root . --infer-rootAfter npm i -g structforge:
# Linux/macOS
structforge --root /tmp/out --infer-root --from ./tree.txt
# or piping inline text
cat <<'EOF' | structforge --root /tmp/out --infer-root --verbose
my-app/
src/
index.ts
package.json
EOF# Windows PowerShell
structforge --root "D:\out" --infer-root --from .\tree.txt
@"
my-app/
src/
index.ts
package.json
"@ | structforge --root "D:\out" --infer-root --verbosepnpm i && pnpm build
node dist/cli.js --root /tmp/out --infer-root --from ./tree.txt
# or
cat tree.txt | node dist/cli.js --root /tmp/out --infer-rootpnpm i
pnpm dev -- --root /tmp/out --infer-root --from ./tree.txt
# or
cat tree.txt | pnpm dev -- --root /tmp/out --infer-rootTips:
-
Preview first:
structforge --root /tmp/out --infer-root --dry-run --from ./tree.txt
-
Create placeholders for empty dirs: add
--gitkeep. -
Increase logs: add
--verbose.
-
Do not add comments or annotations in the structure. Only list directories and files.
- ❌ Don’t use trailing notes like
# ...or(optional ...).
- ❌ Don’t use trailing notes like
-
Directories must end with
/to be recognized as folders. -
Files can have an extension (e.g.
index.ts) or not (e.g.Dockerfile,LICENSE).
Correct
example-api/
├─ app/
│ ├─ main.py
│ └─core/
│ ├─ settings.py
│ └─ logging.py
├─ Dockerfile
└─ README.md
Incorrect
example-api/
├─ app/
│ ├─ main.py
│ └─core/
│ ├─ settings.py # global settings
│ └─ logging.py ------> any other comments
├─ Dockerfile (optional)
└─ README.md
Key options:
--root <dir>output root directory, default.--infer-rootuses the first line that ends with/as sub root, for examplemy-project/--gitkeepcreates.gitkeepinside empty directories--dry-runprints the plan and does not create anything--verboselogs each created item--from <file>read input from a file, otherwise read stdin
my-project/
src/
index.ts
app.ts
utils.ts
test/
app.test.ts
package.json
tsconfig.json
README.md
example-api/
├─ app/
│ ├─ main.py
│ ├─ core/
│ │ ├─ settings.py
│ │ └─ logging.py
│ ├─ api/
│ │ ├─ routers/
│ │ │ ├─ users.py
│ │ │ └─ items.py
│ │ └─ errors.py
│ └─ utils/
│ └─ http.py
├─ requirements.txt
├─ .env.example
├─ Dockerfile
└─ README.md
ui-library/
package.json
tsconfig.json
.eslintrc.cjs
.prettierrc
.gitignore
LICENSE
README.md
src/
index.ts
components/Button.tsx
components/Card.tsx
hooks/useToggle.ts
internal/createClassName.ts
tests/
button.test.tsx
.github/workflows/ci.yml
examples/
Target branch for pull requests: dev. The main branch is protected and represents the latest stable version.
- Fork the repo or create a feature branch from
dev. - Branch name format:
feat/<short-topic>orfix/<short-topic>. - Make changes and add tests when applicable.
- Run
pnpm buildandpnpm testlocally. - Open a PR to
dev. Fill the PR template. - After approval, squash and merge into
dev. - Release to
mainby opening a PRdev -> main.
Use clear, present-tense messages. Conventional Commits is recommended, for example:
feat(parser): support dashed bulletsfix(cli): handle empty stdin
- TypeScript strict mode
- No runtime dependencies
- Keep public API stable in
src/index.ts
- Node test runner
- Add minimal parser cases for new syntaxes
CI runs on pushes and PRs to dev and main. The status badges above use ci-dev.yml and ci-main.yml.
- Merge
devintomainwith a PR. - Create a GitHub Release with semantic version. Tag format
vX.Y.Z.
- Blocks
..to prevent traversal - Normalizes cross-platform paths
- Skips overwriting existing files
MIT, see LICENSE file.
pnpm test