Draw your systems the way you think about them. Fork. Comment. Review. Ship.
ArchFlow is an open-source alternative to IcePanel β a collaborative, real-time workspace for modeling software architecture using the C4 model.
Unlike Figma-for-architecture tools that end at "pretty boxes", ArchFlow treats your architecture as a first-class data model: every object has a type (system, container, component, actorβ¦), a lifecycle status, relationships, drafts, version history, and team-level access control. Drill from a system landscape all the way down to components β the model stays consistent at every zoom level.
L1 System Landscape βββΆ System Context
β
L2 Container
β
L3 Component
- React Flow-powered editor with snap-to-group, smart containment, and edge routing.
- Live cursors, presence roster, and selection sync β see your teammates edit in real time.
- Optimistic drag & resize β zero snap-back, WebSocket cache patching under the hood.
- Comments on the canvas β question pins, inaccuracy flags, ideas, notes.
- Per-user undo / redo with
Cmd/Ctrl+Zβ server-backed stack scoped to your own actions, separate per diagram and per draft. History popover lets you undo to a specific past action.
- Objects (
system/external_system/actor/app/store/component/group) with status, technology, tags, owner team. - Per-diagram positions β the same object can live on L1, L2, L3 with different coordinates on each canvas.
- C4-aware quick-create: place the right types for the level you're on, but also allow cross-level references.
- ~170 built-in technologies (Python, PostgreSQL, Kafka, Figma, gRPC, Kubernetesβ¦) with Iconify-backed logos and brand colors.
- Picker in the object sidebar (multi-select) and edge sidebar (single-select, filtered to protocols) β results group by category with fuzzy search over name / slug / aliases.
- Canvas renders the primary technology as a corner badge on every node and resolves protocol icons onto edge labels.
- Create workspace-level custom technologies β pick any Iconify icon for the logo, set your own name / slug / color / aliases.
- Dedicated
/technologiesmanagement page lists built-in + custom entries with scope + category filters.
- Fork any diagram into a draft that lives in isolation from live data.
- Edit the fork freely β compare diffs, resolve conflicts with the live model, then merge.
- Full version snapshots with revert-to-version.
- Multi-workspace with per-workspace roles (
owner/admin/editor/viewer). - Per-diagram ACL via teams β grant a team
read/edit/manageaccess on individual diagrams. - Pending-approval invite flow (invitee accepts; owner/admin approves).
- Notification inbox for mentions, invites, and activity.
- Packs β group diagrams into logical collections (like folders, but reorderable).
- Pinned / Recent on the Overview dashboard.
- Full-text search across all objects and diagrams (βK / Ctrl+K).
- Multi-agent supervisor orchestrating specialized sub-agents (planner, researcher, diagram, critic) over a LangGraph state machine β handles "describe this", "build me X", "review this design" inside the chat panel.
- GitHub Repo Researcher β link any Container/System to a GitHub URL and a read-only sub-agent fetches code, READMEs, issues, PRs, commits, and diffs to ground its answers in the actual implementation. Per-workspace GitHub PAT (encrypted at rest); 9 tools with per-turn LRU cache.
- Diagram Explainer β one-click natural-language summary of any object or connection, with inline popovers.
- Provider-agnostic LLMs via LiteLLM β pick OpenAI, Anthropic, OpenRouter, or any OpenAI-compatible endpoint per workspace; model + base URL stored encrypted.
- Tool-call streaming UI β live tool icons, sub-agent transitions, applied-change pills, and full transcripts that survive page reloads.
- Optional Langfuse tracing β per-workspace consent (
off/errors_only/full).
- REST API (OpenAPI / Swagger UI at
/docs) + orval-generated TypeScript client. - API keys with prefix-based detection (
ak_β¦), first-class citizens alongside JWT. - Webhooks for
object.*,connection.*,diagram.*, and more. - JSON export / import for migration or CI snapshotting.
- One workspace-level WebSocket firehose + per-diagram channels.
- Keeps React Query cache in sync across tabs / users / browsers β no manual refresh.
| Backend | Frontend | Infra |
|
|
|
One-time bootstrap (installs deps, spins up Postgres/Redis, runs migrations):
make setupThen any time you want to code:
make devThat launches, in parallel:
| Service | URL |
|---|---|
| Backend (FastAPI) | http://localhost:8000 |
| API docs | http://localhost:8000/docs |
| Frontend (Vite) | http://localhost:5173 |
| Postgres | localhost:5432 |
| Redis | localhost:6379 |
One Ctrl+C tears both app processes down. Infra keeps running β make down stops the containers.
| Command | What it does |
|---|---|
make dev |
Deps β infra β migrations β backend + frontend in parallel |
make dev-deps |
uv sync backend, npm install frontend |
make dev-infra |
Start Postgres + Redis via docker compose |
make dev-backend |
Backend only (uvicorn --reload) |
make dev-frontend |
Frontend only (vite) |
| Command | What it does |
|---|---|
make db-upgrade |
Apply all pending migrations |
make db-migrate msg="..." |
Generate a new Alembic migration from model diff |
make db-downgrade |
Roll back the last migration |
| Command | What it does |
|---|---|
make test |
Backend pytest + frontend tests |
make test-backend |
Backend only |
make test-frontend |
Frontend only |
make lint |
ruff check + ruff format --check + npm run lint |
make api-codegen |
Regenerate the typed frontend client from OpenAPI (run after schema changes) |
| Command | What it does |
|---|---|
make build |
Build prod docker images |
make up |
Start the prod stack |
make down |
Stop the prod stack |
ArchFlow/
βββ backend/ FastAPI app
β βββ app/
β β βββ api/v1/ REST endpoints (one router per resource)
β β βββ models/ SQLAlchemy 2.0 models
β β βββ schemas/ Pydantic request/response schemas
β β βββ services/ Business logic layer
β β βββ realtime/ WebSocket manager + Redis fanout
β β βββ core/ Config, DB, security
β βββ alembic/ Migrations
β βββ tests/ Pytest suite
βββ frontend/ Vite + React SPA
β βββ src/
β βββ pages/ Top-level routes
β βββ components/ Canvas, sidebar, toolbar, modalsβ¦
β βββ hooks/ React Query hooks + WebSocket client
β βββ stores/ Zustand stores (auth, canvas, workspace)
β βββ lib/ Shared axios client (auth + workspace + 401 β /login)
β βββ types/ Shared TypeScript models
βββ docker/ docker-compose.dev.yml + docker-compose.yml
βββ charts/archflow/ Helm chart
βββ docs/architecture/ ADRs + design notes
Workspace β your org's top-level container. Everything (diagrams, objects, teams, packs) belongs to exactly one workspace.
Diagram β a single C4-level canvas. Has a type (system_landscape Β· system_context Β· container Β· component Β· custom) and an optional scope_object_id linking it to its parent in the drill-down hierarchy.
ModelObject β a piece of your architecture (system, container, component, actorβ¦). Lives in a workspace; can appear on many diagrams via a DiagramObject junction that stores per-diagram coordinates and size.
Connection β a directed or bidirectional edge between two ModelObjects. Rendered on any diagram that contains both endpoints.
Draft β a forked universe of a diagram + its objects + its connections. Changes stay isolated until you merge back into live.
Pack β a named collection of diagrams within a workspace, for organizing large architectures.
Config lives in .env at the repo root (copied from .env.example on first make setup). Knobs you'll touch most:
DATABASE_URL=postgresql+asyncpg://archflow:archflow@localhost:5432/archflow
JWT_SECRET=change-me-in-production
BACKEND_CORS_ORIGINS=http://localhost:5173
# Optional β Langfuse tracing for agent calls (per-workspace consent gates each call).
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
LANGFUSE_HOST= # canonical, matches LiteLLM/Langfuse SDK
# LANGFUSE_BASE_URL= # accepted as alias for LANGFUSE_HOSTIf you want the AI agent features (supervisor, repo researcher, diagram explainer) to work, you must set AGENTS_SECRET_KEY in .env. It's the symmetric Fernet key that encrypts every workspace's stored LLM provider API key and GitHub PAT at rest.
Without it:
- Saving a workspace LLM key β 500 error β no agent can reach an LLM
- Saving a GitHub PAT β 500 error β repo researcher can't read repos
Generate once per deployment and store like any other secret:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"π Don't rotate it after secrets are saved. There's no automatic re-encryption β losing this key locks every workspace's LLM and GitHub credentials forever. Back it up alongside
JWT_SECRET.
LLM provider keys (OpenAI / Anthropic / OpenRouter / β¦) and the GitHub PAT for the repo-researcher are stored per-workspace in the database (encrypted by AGENTS_SECRET_KEY) β not in .env. Configure them from the workspace Settings page.
Port 8000 or 5173 already in use
lsof -ti tcp:8000 | xargs kill # or tcp:5173Migrations out of sync after pulling
make db-upgradeStale frontend types after changing API
make api-codegenNuke Postgres (wipes the volume β you'll lose all data)
docker compose -f docker/docker-compose.dev.yml down -v
make dev-infra && make db-upgrade- C4 canvas with drill-down (L1 β L2 β L3)
- Real-time collaboration (presence, cursors, selection, optimistic CRUD)
- Drafts + diffs + conflict resolution
- Version history with revert
- Team-level per-diagram ACL
- API keys + webhooks
- Packs, pinned, search
- Per-user undo & redo (Phase 1)
- Per-user undo β stale-detection (Phase 2)
- Import from Structurizr DSL
- Export to Mermaid / PlantUML
- SSO (OIDC)
- Deployment diagrams (C4 L4)
See docs/architecture/ for ADRs and ongoing design.
PRs welcome β bug fixes, features, docs, everything. Full workflow in CONTRIBUTING.md.
TL;DR:
-
mainis protected. Branch off:git switch -c feat/my-thing. -
Small, focused commits. Conventional prefixes:
feat/,fix/,refactor/,docs/,chore/,test/. -
Before pushing:
make lint make test -
Open a PR targeting
main. CI runsbuild-backendandbuild-frontendβ both must be green to merge. -
Squash merge keeps
mainlinear.
Bugs β GitHub issues. Security issues β private advisories.
AGPL-3.0 β free to use, modify, and self-host. If you run a modified version as a network service, you must offer the source under the same license.