A web service for analysing the dependency graph of JavaScript/TypeScript projects. Upload a zip archive of your sources and get an interactive import graph, a list of circular dependencies, an impact assessment for any file, and module coupling metrics.
In a mature frontend codebase the connections between modules quickly stop fitting in your head. That leads to questions which are hard to answer without tooling:
- What breaks if I change this file?
- Are there circular dependencies in the project, and where exactly?
- Which modules have quietly become coupling hubs that too much of the codebase depends on?
This service answers them through static analysis, without executing the code.
- AST-based import parsing.
@babel/parser+@babel/traverse, supporting.js,.jsx,.ts, and.tsx. Service directories such as.gitand.nextare skipped during the scan. - Path resolution. Relative imports, directory index files, and aliases are resolved to actual project files.
- Dependency graph construction with an explicit set of nodes and edges.
- Circular dependency detection — finds every cycle in the graph.
- Impact analysis. For a selected file, returns two sets: modules that depend on it directly, and modules affected transitively.
- Coupling metrics. Fan-in and fan-out per file, plus the top N most depended-upon and most dependency-heavy modules.
- Interactive visualisation of the graph with d3.
| Layer | Technologies |
|---|---|
Analysis core (core) |
TypeScript 5, @babel/parser 8, @babel/traverse 8 |
API (api) |
Node.js 20+, Express 4, multer, adm-zip |
Web client (web) |
React 19, Vite 5, Tailwind CSS 3, shadcn/ui + Radix UI, d3 7, TanStack Query, wouter, react-hook-form + zod |
| Tests | vitest 1.6 with @vitest/coverage-v8 |
| Monorepo | pnpm workspaces |
zip archive
│
▼
api ──── unpacking (adm-zip), storage of analysis results
│
▼
core ─── FileScanner ─→ ImportParser ─→ PathResolver ─→ GraphBuilder
│
┌─────────────────────────────┼──────────────────────┐
▼ ▼ ▼
CycleDetector ImpactAnalyzer MetricsCalculator
│ │ │
└─────────────────────────────┴──────────────────────┘
│
▼
web ─── d3 visualisation
core is transport-agnostic and can be consumed as a plain library — its entire public surface is exported from packages/core/src/index.ts.
Requires Node.js 20+ and pnpm 9+.
git clone https://github.com/NaXy9/Code-Dependency-Analyzer
cd Code-Dependency-Analyzer
pnpm install
# build the core first — both api and web depend on its build output
pnpm --filter @dep-analyzer/core build
# terminal 1
pnpm dev:api # http://localhost:3001
# terminal 2
pnpm dev:web # http://localhost:5173The Vite dev server proxies /api to port 3001, so no separate CORS setup is needed for local development. The API port can be overridden with the PORT environment variable.
To verify the backend is up:
curl http://localhost:3001/health
# {"status":"ok"}pnpm build # built for the / base path
pnpm build:prod # built for deployment under the /cda/ subdirectorypnpm test # core unit tests
pnpm test:coverage # with a coverage reportEvery core module is covered: FileScanner, ImportParser, PathResolver, GraphBuilder, CycleDetector, ImpactAnalyzer, and MetricsCalculator.
packages/
├── core/ # analysis; independent of Express and React
│ └── src/scanner/ # FileScanner, ImportParser, PathResolver,
│ # GraphBuilder, CycleDetector,
│ # ImpactAnalyzer, MetricsCalculator + tests
├── api/
│ └── src/
│ ├── index.ts # Express app and routes
│ ├── persistence.ts # persistence of analysis results
│ ├── serializer.ts # graph serialisation
│ └── store.ts # in-memory store
└── web/ # React client and d3 visualisation
- Only static imports are analysed; a dynamic
import()with a computed path cannot be resolved in principle. - Aliases are resolved by convention — arbitrary
pathsentries fromtsconfig.jsonare not parsed. - Analysis results live in process memory and do not survive a restart.