🌐 Language: English · Español
Paste code, get an interactive call graph to understand what it does — across multiple languages, powered by Tree-sitter.
Weftmap turns source code into a navigable diagram of which functions call which. The differentiator is a pluggable, multi-language architecture: the backend adapts the analysis per language, and adding a new one takes only a few lines. No existing free tool does this well across several languages at once.
Status: MVP. Supports Python, JavaScript/TypeScript, Go, Rust and SQL. Diagram types: call graph (functions as nodes, calls as arrows) and, for SQL, entity-relationship (tables as nodes, foreign keys as edges).
- Features
- How it works
- Tech stack
- Getting started
- Available scripts
- Adding a language
- Project structure
- Roadmap
- Contributing
- License
- Multi-language — one parsing engine (Tree-sitter) for every language.
- Pluggable — a language is a single
LangSpec+ two Tree-sitter queries. - Interactive diagram — pan, zoom and drag nodes (React Flow + dagre layout).
- Internal call graph — shows calls between functions defined in your code; calls to builtins/libraries are filtered out to keep the graph meaningful.
- No build step for the user — paste a snippet and hit Analyze.
┌──────────┐ POST /api/analyze ┌─────────────────────┐ Graph JSON ┌─────────────┐
│ Browser │ ────────────────────▶ │ Tree-sitter (WASM) │ ─────────────▶ │ React Flow │
│ (textarea)│ { code, language } │ per-language module │ {nodes,edges} │ (dagre) │
└──────────┘ └─────────────────────┘ └─────────────┘
- You paste code and pick a language.
- The backend (
src/app/api/analyze/route.ts) validates the input, parses the code with the matching Tree-sitter grammar, and walks the syntax tree to build a normalized graph{ nodes, edges }. - The frontend lays it out with dagre and renders it interactively with React Flow.
The call graph is extracted with declarative Tree-sitter queries (one for function definitions, one for calls) instead of hand-walking the AST — less code, easier to maintain, and the same approach works for every language.
| Layer | Choice | Why |
|---|---|---|
| Framework | Next.js (App Router) | Frontend + backend in one project and one deploy |
| Language | TypeScript | Type safety across the whole stack |
| Parsing | Tree-sitter via web-tree-sitter (WASM) |
One API for ~40 languages |
| Grammars | tree-sitter-wasms |
Prebuilt grammar binaries |
| Diagram | React Flow + dagre | Interactive nodes, hierarchical layout |
| Tests | Vitest | Fast unit tests for the analyzers |
| Package manager | pnpm | Fast, disk-efficient installs |
Requirements: Node 20+ and pnpm.
# 1. Install dependencies
pnpm install
# 2. Start the dev server
pnpm dev
# open http://localhost:3000Paste a snippet, choose python or javascript, and click Analyze.
| Command | What it does |
|---|---|
pnpm dev |
Start the development server |
pnpm build |
Production build |
pnpm start |
Run the production build |
pnpm test |
Run the analyzer tests (Vitest) |
pnpm typecheck |
Type-check with tsc --noEmit |
pnpm lint |
Lint with ESLint |
This is the most valuable kind of contribution. The architecture is pluggable: the backend adapts the analysis per language, and nothing else needs to change.
- Add the grammar. Copy
tree-sitter-<lang>.wasmintopublic/wasm/(available from thetree-sitter-wasmspackage). - Create the analyzer. Add
src/lib/analysis/analyzers/<lang>.tswith aLangSpec— two Tree-sitter queries (function definitions and calls) plus the set of node types that count as a function scope. Usepython.tsas a template. - Register it. Add one line to
src/lib/analysis/registry.ts. - Add the UI option. Add the language key to the
LANGUAGESarray insrc/app/page.tsx. - Add a test. Drop a snippet → expected nodes/edges check in
src/lib/analysis/analyzers/.
That's it.
src/
app/
page.tsx # UI: textarea + language selector + diagram
api/analyze/route.ts # backend: validates input, calls the analyzer
components/
CodeInput.tsx # textarea + selector + analyze button
Diagram.tsx # React Flow + dagre rendering
lib/analysis/
types.ts # Graph + LanguageAnalyzer contract
registry.ts # language registry (the only file that knows them all)
treesitter.ts # loads/caches the Tree-sitter runtime + grammars
analyzers/
shared.ts # common call-graph extraction logic
python.ts # Python LangSpec
javascript.ts # JS/TS LangSpec
analyzers.test.ts # analyzer tests
public/wasm/ # Tree-sitter runtime + grammar .wasm files
Got an idea? Open an issue.
Newcomer-friendly tasks are tagged good first issue.
Shipped
- Call graph for Python, JavaScript, TypeScript, Go and Rust
- SQL schema diagrams (ER / UML): tables, columns, PK/FK, relationships
- Pluggable per-language architecture (add a language in a few lines)
- Bilingual UI (en/es) with in-app docs
Next — help wanted
- More languages: Ruby (#13), Java (#14)
- Drive the Hero language chips from the registry (#15)
- Broaden analyzer test coverage (#16)
- Richer empty state when no functions are found (#17)
Later
- Project mode: analyze a whole folder as a single graph
- Node interaction: click to highlight callers/callees, function detail panel
- More diagram types: control-flow and module-dependency graphs
- Export the graph (PNG/SVG) and shareable permalinks
- More input methods: ZIP upload and GitHub repo URL
- Performance for large codebases
Contributions are welcome — especially new languages. Please read CONTRIBUTING.md and our Code of Conduct.
Quick rules: main is protected (open a PR, CI must pass, one review required),
and commits follow Conventional Commits.
MIT © DataDave-Dev