Repowise draws architecture from the dependency graph and your package manifests. No model draws or lays out any of it, so adding an API key changes the prose around a diagram, never the diagram.
There are three outputs:
| Output | Where you see it | What it shows |
|---|---|---|
| Architecture map | The Architecture diagram page in your documentation | A Mermaid diagram of the main modules and their dependencies |
| C4 views | The local server's REST API, as JSON or Mermaid | System context (level 1), containers (level 2), components (level 3) |
| Structurizr DSL | repowise export --format structurizr, and the export menu on the dashboard's Knowledge Graph | The same C4 model as a text file you commit and render in your own tools |
The dashboard itself draws the Knowledge Graph, a zoomable map of layers, groups, folders and files. It does not draw the C4 levels; it exports them.
The architecture map
Every index that renders documentation includes an Architecture diagram page
(--mode fast renders none). The Mermaid diagram is built
from the knowledge graph on both paths: without a key the page is the diagram,
and with a key a model writes the surrounding prose and the diagram is still the
graph-built one. When the graph cannot produce a diagram, the page draws the
highest-ranked dependency edges instead, and when there are too few resolved
dependencies it says so.
C4 views
The C4 model describes a system at three zoom levels. Repowise builds each from the index on request.
Level 1, system context. Your repository as one system, the people who use it, and the external services it depends on at runtime.
- People are derived from how the system is entered: a CLI, an API, a scheduler. When no entry point says, the view shows one generic user.
- External systems are dependencies classified as a service or a framework, declared in a non-dev section of a manifest the system itself owns. Plain libraries and dev tooling stay off this view, and so do dependencies declared only by test, example or docs manifests.
- Your own packages are never external systems. Dependencies on first-party
packages are dropped for every ecosystem: the root package names plus every
member declared by npm, pnpm or yarn workspaces, Cargo, uv or
go.work. - The system description is the root manifest's description, else the first prose paragraph of the README.
- When nothing qualifies, the view says "No external service dependencies detected".
Level 2, containers. Every directory holding a dependency manifest
(package.json, pyproject.toml, Cargo.toml, go.mod, Maven, NuGet, CMake
or Bazel files) is a container root; manifests under test or example trees are
left out. A repository with no manifests falls back to its top-level
directories. The view shows the dependency edges between containers, rolled up
and labelled, and the external systems at least one container actually uses.
Libraries appear here, unlike level 1.
Level 3, components. The directories inside one container, with their edges in and out.
Start repowise serve and read them from the API on port
7337. The repository id comes from GET /api/repos.
curl localhost:7337/api/graph/<repo_id>/c4/l1 # JSON, level 1
curl "localhost:7337/api/graph/<repo_id>/c4/mermaid?level=2" # Mermaid, level 2
curl "localhost:7337/api/graph/<repo_id>/c4/mermaid?level=3&container_id=<id>"The Mermaid text pastes into mermaid.live or into a markdown file.
Structurizr DSL export
Structurizr DSL is the C4 model as a text file. Repowise writes it on demand from the graph that is already there, with no model call and no change to indexing.
repowise export --format structurizr # a model fragment for your own workspace.dsl
repowise export --format structurizr --standalone -o arch/ # a complete workspace with default views| Repowise | Structurizr |
|---|---|
| The repository | softwareSystem |
| A workspace package or top-level directory | container |
| A directory inside a container | component, with --components |
| A third-party dependency | softwareSystem tagged External |
| How the system is entered (CLI, API, scheduler) | person |
Containers and components carry health as tags and properties: Hotspot when
the box holds a churn hotspot, Dead when it holds an unreachable file, and
Layer: <name> for each curated layer. Properties such as repowise.hotspots,
repowise.owner and repowise.minBusFactor are left out when unknown, never
written as zero.
The fragment holds only the model { ... } body, so you include it from a
workspace.dsl that keeps your own views and styles, and re-exporting never
touches what you wrote. --standalone writes a complete workspace, refuses to
overwrite a workspace.dsl it did not write, and takes --force to replace one
on purpose. Every flag is on Other commands.
From the dashboard, the Knowledge Graph's export menu downloads the same file, as a complete workspace or as a model fragment.
Limits
- Classification decides level 1. A dependency the classifier does not recognise as a service or framework counts as a library and stays off the system context, even if it is a runtime service in your deployment.
- Containers and components are directories. A component is a directory, not a grouping someone chose, which is why the component level is opt-in in the export.
- One way only. The export never reads your DSL back.
- One repository at a time. In a workspace, each repository exports its own model. The cross-repo picture is the System Map.
- Component views are capped at 20 boxes in
--standalone, and the file says so in a comment.