Skip to content

Studio

The visual companion. Reads Nwire primitives natively — no instrumentation, no agents, no second model of your system.

Boot it

bash
# Option 1 — Studio as a standalone process
pnpm dlx @nwire/studio
# opens http://localhost:7777
bash
# Option 2 — from the framework repo
cd packages/nwire-studio
pnpm dev

By 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)

                                                              external

Columns 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:

  1. .nwire/manifest.json — built by nwire cache from your apps. Static metadata: persona, SLO, schema, journeys, owners. Served by Studio's Vite middleware at /__nwire/manifest.json.

  2. /_nwire/* — runtime endpoints from the wire's httpInterface({ 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

bash
nwire cache       # rebuilds .nwire/manifest.json

Run 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

FeatureLocal OSSHosted 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:

KindColorTailwind
Personabrownbg-amber-800
Externalpinkbg-pink-500
Commandbluebg-blue-600
Aggregateyellowbg-yellow-400
Eventorangebg-orange-500 (biggest)
Policypurplebg-purple-500
Read Modelgreenbg-emerald-500
Querytealbg-teal-500

See also

MIT licensed.