ArchLens turns a source tree into an architecture map you can actually use. One command finds local dependencies, circular dependency groups, change-risk hotspots, and the potential blast radius of a changed file across JavaScript, TypeScript, Python, and Go—then produces a private, self-contained interactive report.
No account. No upload. No background service. No runtime dependencies.
Explore the live interactive report →
Run ArchLens from any source repository. It writes one offline HTML file and opens it in your browser:
npx --yes github:mockingbird777/archlens . --open◈ ArchLens scanning /path/to/repository
✓ 30 files · 52 edges · 2 cycles
Report: /path/to/repository/archlens-report.html
Opened in your default browser.
Requires Node.js 20 or newer.
# Generate a report without opening it
npx --yes github:mockingbird777/archlens .
# Trace every importer that could be affected by a change
npx --yes github:mockingbird777/archlens . --impact src/config.ts --open
# Open the generated report
open archlens-report.html # macOS
xdg-open archlens-report.html # LinuxOr install the GitHub repository globally:
npm install --global github:mockingbird777/archlens
archlens ./your-repositoryThe install runs the repository's prepare script to compile TypeScript before the CLI starts. npm registry commands such as npx archlens are intentionally not documented until a package is published there.
Dependency graphs are often either too shallow to guide a refactor or locked behind a hosted platform. ArchLens aims for the useful middle: a fast, auditable local CLI with enough repository intelligence for code review, onboarding, and architectural cleanup.
- Find cycles before they harden. Tarjan's strongly connected components algorithm identifies complete circular dependency groups, including self-loops.
- Prioritize risky files. A transparent hotspot score combines unique fan-in, unique fan-out, file size, and cycle membership.
- Preview a change's blast radius. Reverse dependency tracing shows potentially affected importers, their distance, and a shortest witness path when it fits the documented report budget; repeat
--impactfor multi-file changes. - Understand polyglot repositories. Analyze JS/TS ESM, CommonJS, Python imports, and local Go module imports in one pass.
- Share a report, not your source. The HTML report contains graph metadata only and makes no network requests.
- Automate architecture checks. Stable JSON and Mermaid output are easy to consume in CI, pull requests, or docs.
- Trust the toolchain. ArchLens itself ships with zero runtime dependencies and uses only Node.js built-ins.
The default report is a single portable file with:
- live file search and language filters;
- cycle-only and hotspot-only focus modes;
- an impact-only focus mode with changed-file and affected-file markers;
- zoomable and pannable dependency graph;
- clickable node details with LOC, fan-in, fan-out, and cycle membership;
- hotspot ranking, cycle summaries, and an embedded machine-readable dataset;
- responsive layout and no CDN, analytics, fonts, or remote assets.
npx --yes github:mockingbird777/archlens . --title "Payments service architecture"Use the versioned schema for scripts and CI:
npx --yes github:mockingbird777/archlens . --format json --stdout > architecture.jsonThe document includes meta, summary, nodes, edges, unresolvedImports, cycles, hotspots, optional impact, and non-fatal warnings. Impact results always include complete reachability, distance, and changed-file origin data; deterministic shortest witness paths are included within the materialization budget described below. Paths are repository-relative; source contents and absolute paths are never emitted.
impact.witnesses records the witness materialization budget and its use. Complete paths are capped at 256 nodes each and 40,000 path nodes across a report so a deep or highly connected graph cannot create quadratic output. Reachability, distances, changed-file origins, and affected-file counts remain complete. If a path exceeds either budget, its witnessPath is [], witnessPathOmitted is true, impact.witnesses.omittedPaths is incremented, and a top-level warning explains the limit. HTML displays the warning and omission marker; the CLI mirrors warnings to stderr unless --quiet is set.
Keep a graph next to your technical documentation:
npx --yes github:mockingbird777/archlens ./packages/core --format mermaid --output docs/core-graph.mmdarchlens [path] [options]
-f, --format <type> html (default), json, or mermaid
-o, --output <file> Output path; use - for stdout
--stdout Write the report to stdout
--include <glob> Only scan matching files (repeatable)
--exclude <glob> Ignore matching paths (repeatable)
--impact <path> Trace potential importers of a changed path (repeatable)
--no-gitignore Do not read .gitignore files
--max-files <n> Safety limit (default: 20000)
--title <text> Custom HTML report title
--open Open the generated HTML report
-q, --quiet Suppress progress and summary
-h, --help Show help
-v, --version Show the version
Examples:
npx --yes github:mockingbird777/archlens . --exclude '**/*.test.ts' --exclude 'generated/**'
npx --yes github:mockingbird777/archlens . --include 'packages/**' --max-files 50000
npx --yes github:mockingbird777/archlens services/api -f json -o artifacts/api-architecture.json
npx --yes github:mockingbird777/archlens . --impact packages/core --impact src/config.ts --openArchLens always skips common generated or heavyweight directories such as .git, node_modules, dist, build, coverage, vendor, virtual environments, and language caches. It also evaluates common .gitignore rules, including wildcards, anchored paths, directory rules, and negation.
| Language | Recognized syntax | Local resolution |
|---|---|---|
| JavaScript / TypeScript | import, side-effect import, re-export, dynamic import(), require() |
relative files, extensionless files, directory indexes, TS source behind .js specifiers |
| Python | import, aliased/multiple imports, from … import, relative imports |
module files and package __init__.py from the source directory or repository root |
| Go | single, grouped, aliased, blank, and dot imports | packages under the module path declared by go.mod, plus relative imports |
External packages are counted but deliberately excluded from the local file graph. Imports that look local but cannot be resolved are reported separately so configuration gaps remain visible.
flowchart LR
A[Repository walker] --> B[Language import parsers]
B --> C[Local module resolver]
C --> D[Dependency graph]
D --> E[Tarjan SCC cycles]
D --> F[Hotspot metrics]
D --> H[Reverse impact tracing]
E --> G[HTML / JSON / Mermaid]
F --> G
H --> G
The implementation is intentionally layered:
src/
├── analyzers/ # Dependency extraction per language
├── core/ # Walking, ignores, resolution, SCC, metrics
├── reporters/ # Self-contained HTML, JSON, Mermaid
├── test/ # node:test unit and integration tests
├── cli.ts # Argument parsing and terminal UX
└── index.ts # Public programmatic API
Install from GitHub, then use it as a library:
npm install github:mockingbird777/archlensimport { analyzeRepository } from 'archlens';
const result = await analyzeRepository({
root: './my-repo',
exclude: ['generated/**'],
});
console.log(result.cycles);impact paths can name a scanned source file or a directory. ArchLens follows local import edges in reverse, keeps cycles bounded, and deterministically selects a shortest predecessor chain when several changed files can reach the same importer. Traversal stores those predecessors rather than copying whole paths; bounded witness materialization affects only the displayed path, never the reachability result. This is a structural “may be affected” signal—not a claim that every reachable file must change.
Scores are relative to the scanned repository and range from 0 to 100:
40% normalized fan-in
25% normalized fan-out
25% normalized LOC
10% circular-dependency membership
Log normalization keeps one generated mega-file from flattening every other signal. The score is a prioritization aid—not a claim about code quality.
ArchLens runs entirely on your machine. It does not make network calls, execute scanned code, evaluate configuration files, or include source text in reports. Reports contain relative file paths and import specifiers, which can still be sensitive; review them before sharing outside your organization.
See SECURITY.md for responsible disclosure and the threat model.
ArchLens favors predictable zero-configuration analysis over compiler-level completeness. It does not yet evaluate TypeScript path aliases, bundler aliases, Python environment/package metadata, Go workspaces, conditional imports, or computed import strings. Parser false positives and unresolved edges are possible in syntactically unusual code. Please open a small reproduction when you find one.
-
tsconfig.jsonand packageexportsresolution - configurable architecture boundaries and CI exit policies
- graph diffing between commits
- ownership and churn overlays from local Git history
- Rust and Java/Kotlin analyzers
- plugin API for organization-specific resolvers
Issues and pull requests are welcome. Start with CONTRIBUTING.md, follow the Code of Conduct, and run npm test before submitting a change. Good first contributions include focused parser fixtures, resolver edge cases, report accessibility, and performance profiles from large public repositories. Not ready to code? A small public repository that ArchLens misreads is an equally valuable bug report.
MIT © 2026 ArchLens contributors.