stubtree
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
What is stubtree?
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.
Installation
npm install -g @zapier/stubtree
yarn global add @zapier/stubtree
npx @zapier/stubtree
Prerequisites
stubtree requires ctags:
brew install ctags
sudo apt-get install ctags
Getting Started
stubtree
stubtree --root ./src --lang ts,tsx
stubtree --depth 3
stubtree --json > structure.json
Options
--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
Examples
TypeScript/JavaScript project
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
Python project with depth limit
stubtree --root ./myproject --lang py --depth 2
JSON output
stubtree --json > project-structure.json
Features
- 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)
How it Works
Behind the Scenes
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
Performance Optimizations
- 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 and chalk for colors
Performance
stubtree is designed to be fast, typically scanning and rendering a project tree in under 1 second on a typical laptop.
Limitations
- Symbol information is limited to what ctags provides
- No language-specific type inference beyond ctags capabilities
- Requires ctags to be installed separately
Development
npm install
npm run dev
npm test
npm run build
npm run lint
npm run typecheck
Known Issues
- The tool gracefully handles broken symlinks and files that can't be accessed by skipping them during directory traversal
License
MIT