Studio
The visual companion. Reads Nwire primitives natively — no instrumentation, no agents, no second model of your system.
Boot it
# Option 1 — Studio as a standalone process
pnpm dlx @nwire/studio
# opens http://localhost:7777# Option 2 — from the framework repo
cd packages/nwire-studio
pnpm devBy default Studio's /_nwire/* proxy points at localhost:3000. Set NWIRE_INSPECT_URL=http://localhost:3001 to aim elsewhere, or use the Run page (below) to spawn the wire from inside Studio.
The pages
Overview
Stat cards: apps, BCs, actions, events, actors, projections, queries. Per-app module breakdown. Top of mind: "what does this system contain?"
Topology
Bird's-eye view. Each app is a colored swimlane. Modules sit on the lane. Cross-app event-graph edges animate in purple. Filter "Cross-service only" to focus on the actual coupling.
EventStorm — the DDD canvas
Three reading levels with a switcher:
L1 — Big Picture. Events only, on a causal timeline. Read the system in one breath.
L2 — Process Flow (default). Pick a journey step (J3-submit, etc.) from the dropdown. Stickies lay out on a strict 7-row grid:
persona ──▶ command ──▶ aggregate ──▶ event ──▶ policy ──▶ readModel
(yellow) (orange) (purple) (green)
▼
externalColumns are causal step indices assigned by BFS from entry actions. No elkjs at L2 — the grid IS the layout, it cannot tangle.
L3 — Software Design. Full canvas of one app, elk-laid-out with a mini-map. Nodes draggable.
Play Trace ▶
The flagship DX feature. Fetches /_nwire/telemetry/recent?limit=200, groups by correlationId, walks each story chronologically, lights up stickies with an amber glow as the corresponding event/action fires.
- 1× / 2× / 4× / 8× playback speed
- Pause between correlation chains so different stories feel separated
- Click Stop to interrupt; canvas resets
Watch the system tell its own story
Fire some real dispatches via the Dispatch page (or curl), then hit Play Trace. You're watching a player-piano rendition of your domain. Bugs jump out — "wait, why did THAT reaction fire?"
Selection + hover
- Click any sticky → fades everything outside its 1-hop neighborhood
- Hover → bottom-left tooltip shows kind + name + subtitle + persona + SLO + observed count
- Stats bar in the header:
<declared> declared · <fired> fired · <drift> drift
Modules
One card per BC. Shows provides + needs + per-kind counts. Click into the card for the BC's full inventory.
Actions
Searchable list. Click an action for its detail panel:
- Full zod schema, rendered as a tree
- Retry / policy / persona / journeyStep / SLO badges
- Inline-handler vs separated-handler flag
- Description (the persona narrative)
- Producing module + app
Events
Catalog with public / internal badges. Per-event detail shows:
- Producer (module + app)
- Consumers tagged via reaction / projection / actor / external
- Schema
Routes
Filterable table. Every HTTP route across every wire — method, path, target action/query, owning module/app.
Dispatch
Pick any action from a filterable list. Right panel:
- Tenant + userId fields (optional)
- Input form scaffolded from the action's zod schema — defaults from
.default(), type-based fallbacks otherwise - "Dispatch" button POSTs to
/_nwire/dispatch - Result panel: success shows
messageId+correlationId+ result; failure shows the error
Useful for: smoke-testing actions during dev without writing curl commands, generating telemetry to feed Play Trace, debugging schema validation.
Live
Real-time event stream over SSE. Each row shows event name + correlation short id + tenant/userId tags + timestamp.
- Click an event → right column renders the causation trace tree for that correlationId (
msg X ← caused by Y) - Pause / resume / clear / reconnect controls
- Filter by event name / messageId / correlationId / tenant / user
- In-process vs external events colored differently (emerald / purple)
Run
The process supervisor. Three columns:
- Topology picker — dropdown listing
apps/topologies/*.topology.ts - Processes — running children with status dot (running / starting / stopping / crashed / exited), pid, age, errors
- Live stdout — SSE-streamed stdout/stderr from the selected process; stdout/stderr filter; auto-scroll toggle; Stop / Clear buttons
Click Start → Studio spawns pnpm exec vite-node apps/run.ts with NWIRE_TOPOLOGY=<name> and PORT=<port>. Health check polls /_nwire/manifest until ready, then flips status to running. Studio's /_nwire/* proxy auto-routes to the spawned port — Live + Dispatch + EventStorm light up automatically.
One window, full loop
Pick a topology → Start → flip to Dispatch → fire an action → flip to EventStorm → Play Trace. Whole cycle in one Studio.
Data sources
Studio reads from two places:
.nwire/manifest.json— built bynwire cachefrom your apps. Static metadata: persona, SLO, schema, journeys, owners. Served by Studio's Vite middleware at/__nwire/manifest.json./_nwire/*— runtime endpoints from the wire'shttpInterface({ inspect: true }). Live state: events, telemetry, actor state, projection state, DLQ, dispatch.
The dynamic /_nwire/* proxy in Studio's Vite middleware picks the most-recently-started managed process. Falls back to NWIRE_INSPECT_URL if no process is up.
Refreshing the static cache
nwire cache # rebuilds .nwire/manifest.jsonRun after adding/renaming actions, modules, journeys. Studio's "↻ reload manifest" button in the bottom-left re-fetches the JSON without a full page reload.
OSS / Cloud split
| Feature | Local OSS | Hosted Cloud (future) |
|---|---|---|
| Live event stream | ✓ | ✓ + retained history |
| Actor / projection browser | ✓ | ✓ + multi-deploy |
| EventStorm canvas | ✓ | ✓ + collaboration + sync to code |
| Play Trace | ✓ | ✓ + historical traces |
| Dispatch UI | ✓ | ✓ |
| Run / process supervisor | ✓ | ✓ + Cloud-managed processes |
| Distributed traces | ✓ (single process) | ✓ + cross-service correlation |
| Multi-environment | — | ✓ |
| Team / sharing | — | ✓ |
| Alerts | — | ✓ |
| AI debug | — | ✓ |
OSS = the local experience. Cloud = persistence, multi-deploy, team features. Same UI, same concepts, same muscle memory — the upgrade is flipping endpoint: 'https://studio.nwire.dev' in the plugin.
Theming
Studio's color palette is the canonical EventStorming palette:
| Kind | Color | Tailwind |
|---|---|---|
| Persona | brown | bg-amber-800 |
| External | pink | bg-pink-500 |
| Command | blue | bg-blue-600 |
| Aggregate | yellow | bg-yellow-400 |
| Event | orange | bg-orange-500 (biggest) |
| Policy | purple | bg-purple-500 |
| Read Model | green | bg-emerald-500 |
| Query | teal | bg-teal-500 |
See also
- Concepts → Studio — what it is, conceptually
- Telemetry kinds reference — what Studio consumes
- @nwire/kernel — the shared core (process supervisor, event bus, command router) Studio's Run page dispatches through