Generate a bird's-eye view of your codebase with all the important symbols (functions, classes, methods) shown inline. Perfect for documentation, code reviews, or understanding new projects.
$ stubtree --root ./src --lang ts
src/
├── index.ts
│ ├── class FileProcessor
│ │ ├── constructor(options: ProcessorOptions)
│ │ ├── processDirectory(dirPath: string): Promise<TreeNode>
│ │ └── shouldIgnoreFile(filePath: string): boolean
├── parser.ts
│ ├── parseTags(input: string): Promise<Tag[]>
│ └── interface Tag
│ ├── name: string
│ ├── path: string
│ └── kind: string
└── renderer.ts
├── renderTree(node: TreeNode, options?: RenderOptions): string
└── formatSymbol(tag: Tag): string
stubtree is a CLI tool that combines the power of ctags with a clean tree visualization to help you quickly understand any codebase. Unlike regular tree commands that only show files and folders, stubtree extracts and displays the actual code structure - classes, methods, functions, and more - giving you instant insight into how a project is organized.
Perfect for AI coding assistants: Tools like Claude, GitHub Copilot, and Cursor can better understand your codebase when provided with stubtree's structured output, leading to more accurate suggestions and refactoring.
# Install globally
npm install -g @zapier/stubtree
# Or with yarn
yarn global add @zapier/stubtree
# Or use directly with npx
npx @zapier/stubtree
stubtree requires ctags
:
# macOS
brew install ctags
# Ubuntu/Debian
sudo apt-get install ctags
# Scan current directory
stubtree
# Scan specific directory with TypeScript files
stubtree --root ./src --lang ts,tsx
# Limit depth for large projects
stubtree --depth 3
# Export as JSON for processing
stubtree --json > structure.json
--root <dir>
- Root directory to scan (default: current directory)--lang <globs>
- Comma-separated file extensions to include (e.g.,py,ts,tsx
)--depth <n>
- Maximum directory depth to traverse--json
- Output raw JSON instead of ASCII tree
stubtree --root ./src --lang ts,tsx,js,jsx
Output:
src/
├── main.ts
│ ├── init_app() -> void
│ └── class Service
│ ├── start() -> Promise<void>
│ └── stop() -> Promise<void>
└── utils/
└── io.ts
├── read(path: string) -> string
└── write(path: string, data: string) -> void
stubtree --root ./myproject --lang py --depth 2
stubtree --json > project-structure.json
- Fast parsing using ctags JSON output with advanced pattern extraction
- Extracts function signatures, return types, and async modifiers
- Shows class inheritance and property type annotations
- Respects file order as encountered (no sorting)
- Colorized output when outputting to TTY
- Ignores common directories (.git, node_modules, etc.) and test files
- Supports multiple programming languages through ctags
- Smart filtering to show only relevant symbols (classes, functions, methods, not internal variables)
stubtree combines the power of ctags with Node.js's streaming capabilities to efficiently parse and render your codebase:
-
Symbol Extraction: We spawn
ctags
as a child process with specific flags:ctags --output-format=json --fields=+neKStr --extras=+q --sort=no -R .
--output-format=json
: Outputs newline-delimited JSON, one symbol per line--fields=+neKStr
: Includes line numbers, end lines, kind info, scope, type refs, and roles--extras=+q
: Includes extra tag information like signatures--sort=no
: Preserves file discovery order-R
: Recursively scans directories
-
Streaming JSON Parser: Instead of loading all ctags output into memory, we use Node's
readline
interface to process the JSON stream line-by-line. Each line contains a symbol like:{"name":"readFile","path":"/project/src/io.ts","kind":"function","signature":"(path: string): Promise<string>"}
-
Tree Building: We build the tree structure in two passes:
- First, we group all tags by their file paths
- Then, we walk the actual filesystem to build the directory structure, attaching the relevant tags to each file node
-
Smart Filtering:
- Language filtering happens at the tag parsing stage based on file extensions
- Directory traversal respects
--depth
limits and ignores common non-source directories - Empty directories are automatically pruned from the output
-
ASCII Rendering: The tree renderer uses a recursive algorithm with careful prefix tracking:
├──
for non-last items└──
for last items│
for continuation lines- Tags are indented one level deeper than their containing file
-
Color Support: We detect TTY output using Node's
isatty()
and apply colors via chalk:- Blue for directories
- Green for files
- Gray for symbols
- Streaming: We never load the entire ctags output into memory
- Lazy Directory Walking: We only traverse directories that contain matching files
- Early Filtering: Language filters are applied during tag parsing, not after
- Minimal Dependencies: Just
commander
for CLI parsing andchalk
for colors
stubtree is designed to be fast, typically scanning and rendering a project tree in under 1 second on a typical laptop.
- Symbol information is limited to what ctags provides
- No language-specific type inference beyond ctags capabilities
- Requires ctags to be installed separately
# Install dependencies
npm install
# Run in development mode
npm run dev
# Run tests
npm test
# Build
npm run build
# Lint
npm run lint
# Type check
npm run typecheck
- The tool gracefully handles broken symlinks and files that can't be accessed by skipping them during directory traversal
MIT