Open source · Java · Spring Boot · Angular

Read the layers of a codebase.

Stratigraph reads a large codebase and its git history and gives you the map nobody drew: the deployables and how they depend on each other, the data model, the HTTP API, and where the risk is. Every claim points at a file and line or a commit. Every view says how much of the code it was built from.

$ npx stratigraph scan .
Get started Star on GitHub

Apache 2.0 · runs locally · no code leaves your machine

Entity-relationship diagram of Spring PetClinic, read from its Flyway schema and JPA mappings: owners, pets, visits, vets, specialties and types with their keys and relationships
Spring PetClinic's schema, read from its migrations and JPA mappings — tables, columns, keys and foreign keys, each cited.
20public repositories benchmarked
100%JPA entity & table recall
99%HTTP endpoint recall
0lockfiles or tests ranked as “risky”

Nobody remembers why it is shaped like this.

You inherit a 300,000-line Spring monolith with an Angular front end. The architecture diagram on the wiki is four years old. The people who designed the data model have left. Every change is a guess about what else it touches.

Most tools either draw boxes that look confident and are wrong, or give you a thousand lint warnings. Stratigraph is built on one rule: static analysis produces the facts, and nothing is ever asserted without a citation. When it could not see something — no JDK, an unread module, a type from a jar — it says so on the page, and withholds a view rather than draw a partial one as if it were whole.

What you get

One command, a map you can defend.

Architecture that matches the build

C4 diagrams at context, container and component level. A container is a real deployable — a Spring Boot app, a WAR, an Angular or Nx application — proved by its build file or main class. Aggregator and BOM poms are grouping, not boxes. Test code is left out and counted.

The data model as the database has it

Tables, columns and foreign keys from Liquibase, Flyway and SQL DDL, overlaid with JPA mappings — default naming strategies, inheritance, embedded ids, @MappedSuperclass. Where the classes and the migrations disagree, that is a finding.

Who reads and writes each table

Spring Data repositories, JPQL and native @Query, and JDBC SQL become read/write edges, so “what touches orders?” has a cited answer.

The whole HTTP surface

Spring MVC, JAX-RS, custom meta-annotations, paths built from constants, API-first controllers joined to their OpenAPI spec, Koa and Express routes — and Angular calls linked to the endpoints they hit.

Risk from history, not size

Hotspots rank recent change in source files, scaled by complexity — never lockfiles or generated code. Co-change coupling finds files that move together with no dependency between them. Knowledge silos flag files one person owns that the rest of the code depends on.

Findings with evidence

Package cycles with the shortest path and the lines that close it, schema drift, hidden coupling, bus factor. Each finding cites the edges, files or commits it rests on; one that cannot is not shown.

Coverage on every view

“Built from 412 of 1,030 Java files; the Java extractor did not run: no JDK 17+.” Every diagram, ranking and answer states its coverage. Below 50%, a view is withheld with the reason instead of drawn.

An MCP server for AI agents

Point Claude Code or any MCP client at the fact store: what_breaks_if, who_knows, where_is_table_written, find_callers, check_cycle and more — each answer cited and carrying its coverage.

Fits in CI

--format json on every command, --fail-on severity gates, and stratigraph diff to fail a build only on findings that are new — the gate a repository with existing debt can switch on today.

The report

A static HTML report you can hand to anyone.

Self-contained, no server, no scripts, prints cleanly. These are real reports of public repositories, generated by stratigraph scan.

Report summary for Spring PetClinic: five first-hour answers — the parts, the data, the risk, what is changing, who holds the knowledge — each with its coverage
The first hour: the parts, the data, the risk, what is changing and who holds the knowledge — each with the coverage it rests on.

Use cases

For the first day on a system, and every day after.

Inheriting a monolith

Get the parts, the data model and the risky corners of a system you did not build in an hour, with every claim checkable at a file and line.

Planning a modernisation

Find the seams before you cut: package cycles, co-change clusters that ignore module boundaries, and the tables each part of the code writes.

Onboarding engineers

Hand new joiners a map that is regenerated from the code, not a wiki page that went stale the week after it was written.

Technical due diligence

Assess an acquisition or a vendor codebase with a scorecard of structure, risk and knowledge concentration — and an explicit statement of what could not be read.

Architecture reviews & ADRs

Compare the intended structure with the real one; clusters that cut across declared modules become ADR candidates with evidence attached.

Grounding AI coding agents

Give Claude Code or another MCP client structural answers it can cite — callers, impact, table writers — instead of letting it guess from grep.

How it works

Facts first. Interpretation is labelled.

  1. 1

    Extract

    Separate extractors parse Java/Kotlin (OpenRewrite), TypeScript/Angular (the TS compiler API) and migrations, emitting facts as NDJSON.

  2. 2

    Store

    Nodes and edges land in a local SQLite fact store, each with a file and line. Every file gets a role — source, test, generated, migration, lockfile.

  3. 3

    Mine history

    git log gives recent change, authorship and co-change, with bulk sweeps and .git-blame-ignore-revs left out.

  4. 4

    Analyse

    Cycles, clusters, hotspots, schema drift and coupling become findings with citations. An optional model may name clusters — marked as inference.

  5. 5

    Present

    HTML report, Mermaid and Structurizr diagrams, findings.md, JSON, and an MCP server — all projections of the same stored facts.

A confidently wrong dependency map is worse than no map. If a relationship cannot be cited, the answer is “no evidence found” — not a plausible guess.

For agents

Ask the codebase, get citations back.

Run stratigraph mcp and connect it to Claude Code, Cursor or any MCP client. Thirteen read-only tools answer structural questions from the stored facts — and every answer ends with the coverage of the view it came from, so the agent knows when an empty answer means “unknown”.

  • what_breaks_if — transitive dependents, the tests that reach them, the endpoints they serve
  • who_knows — authors, share and recency, from git
  • where_is_table_written — repositories, queries and SQL, cited
  • explain_hotspot — every number behind a file's rank

The answer shown is illustrative; its shape is the tool's.

# what_breaks_if com.acme.billing.InvoiceService
6 element(s) depend on it within 3 hop(s):
  [1] com.acme.billing.InvoiceController — injects
      (billing/web/InvoiceController.java:38)
  [1] com.acme.billing.DunningJob — calls issue(Invoice)
      (billing/jobs/DunningJob.java:71)
  [2] com.acme.api.AccountResource — injects DunningJob
      (api/AccountResource.java:22)
  …
2 HTTP endpoint(s) served by impacted code:
  POST /api/invoices — InvoiceController#create
  POST /api/accounts/{id}/dunning — AccountResource#dun

Coverage (architecture): Built from 1,204 of 1,230
main source files parsed (97%).

Upgrade agent

Spring Boot upgrades that know when to stop.

stratigraph upgrade run takes a Maven project from Boot 2.7 to 3.5, or from 3.x to 4.0. It runs OpenRewrite's recipe, then works through what the recipe leaves broken, on its own branch. Every change is rebuilt and kept only if the build gets further and no passing test turns red.

  • Baseline first: every test is compared with its own result before the upgrade, so "red" means passed before, fails now
  • Layered commits: the recipe, exact known fixes, and AI fixes from Claude Code (opt-in with --ai claude-code), each reviewable on its own
  • Hands back what is yours: an authorisation rule or an HTTP contract is never chosen for you; it is handed off with the options
  • Guardrails outside the model: a change that disables or deletes a test is rejected, and application code bent to pass a test is flagged for review
10 public Spring Boot appsOpenRewrite aloneStratigraph
Every test that passed before still passes, no human edits0 / 105 / 10
Stopped at a decision that is yours to make, with options—2 / 10
Time per app · AI cost per app—1–14 min · $0–2.54
9 more apps it had never seen: tests still passing—8 / 9

The benchmark, per app, with what is left for each → · the unseen apps, and how thin some of their test suites are →

$ stratigraph upgrade run --to 4.0 --ai claude-code
upgrade: baseline 183/183 tests pass
upgrade: running …boot4.UpgradeSpringBoot_4_0
upgrade: known fix kept: generate Jakarta API code
upgrade: AI attempt 2 on removed-spring-api (1 failure(s))
upgrade: needs-decision — see upgrade-report.md

## Needs your decision
### Two security filter chains match the same requests
Evidence: 118 tests fail to start a context
  (UnreachableFilterChainException)
Options:
1. Scope the API chain with securityMatcher("/api/**")
2. Merge the chains into one, rules made explicit
3. Keep one chain, if the other was dead config

Recipe · 1 known fix · 3 AI fixes (authored by a model)
Abridged from the spring-petclinic-reactjs run.

Measured, not asserted

Benchmarked on 20 public repositories.

stratigraph bench runs the full pipeline over a pinned corpus — Spring PetClinic and its variants, JHipster, eladmin, killbill, OpenMRS, nacos, Apache Dubbo, Spring Cloud Gateway, Spring Boot Admin, bitwarden/clients, analog and more — and scores it against ground truth labelled from the source, without the tool.

MetricTargetStratigraph 2.0
Non-source files (lockfiles, manifests, tests) in the hotspot top 2000
Hotspot top-10 overlap with a senior engineer's list≥ 60%66%
JPA entity recall, with the physical table name≥ 90%100% (146/146)
Table recall≥ 90%100% (274/274)
HTTP endpoint recall≥ 95%99% (519/520)
Dependency-injection edges resolved≥ 85%95% (215/226)
Deployables found as containers / containers that are deployables100%100% / 100%
Views rendered without a coverage statement00

Read the full scorecard — every miss is listed by name →

Get started

Five minutes to your first map.

# Node 18.18+; a JDK 17+ for Java code
npm install -g stratigraph
stratigraph doctor              # what this machine can analyse
stratigraph fetch-extractor     # the Java extractor, checksum-verified

# the whole pipeline, then open the report
stratigraph scan path/to/repo --no-llm
open stratigraph-report/index.html

# let your agent query it
stratigraph mcp --repo path/to/repo

Prefer containers? docker run --rm -v "$PWD:/repo:ro" ghcr.io/imashishsharma/stratigraph doctor

Questions

Does Stratigraph send my code anywhere?

No. Extraction and history mining run entirely on your machine with no network access. The optional interpretation layer sends structural metadata to a model API only if you configure a key, and never raw source unless you pass --send-source. Everything works with --no-llm. The upgrade agent's AI fixer is opt-in (--ai claude-code): it runs the Claude Code CLI on your machine, under your own Claude account, and says so before it starts.

Which languages and frameworks does it understand?

Java and Kotlin with Spring, Spring Boot, JPA/Hibernate, Spring Data and JAX-RS; Liquibase, Flyway and SQL DDL; TypeScript and Angular — NgModules, standalone components, routes and DI; OpenAPI specs; Koa and Express routes.

Do I need a JDK or a working build?

Only for the Java half, which needs a JDK 17+. Analysis never runs your build. If your Maven dependencies are already in the local cache it uses them offline for richer types; otherwise it reads source only — and says so in every view. stratigraph upgrade is the exception: upgrading means building, so it runs Maven (which downloads the new versions) on a branch of its own, and never pushes.

How does the upgrade agent decide what to fix and what to hand back?

It builds and tests the project before touching it, so every later failure is measured against that baseline. Each failure is sorted from its log: mechanical failures get an exact known fix; judgment calls can go to the AI fixer; decisions — an authorisation rule, an HTTP contract — are never attempted and come back with the options. A change is kept only if the build gets further and no passing test turns red.

How is this different from SonarQube or Structurizr?

SonarQube reports rule violations file by file; Structurizr draws the architecture you describe. Stratigraph derives the architecture, data model and API from the code and its history, cites every element, and tells you how much of the code each view covers.

Is it free?

Yes — open source under Apache 2.0, on npm and GitHub.