Studio Overview
ExpressoTS Studio is a local developer experience platform that runs alongside your application during development. It records every HTTP request, captures every log line, snapshots your DI graph, scans your dependencies for vulnerabilities, and exposes everything through a single web UI.
Everything runs on your machine. Nothing is sent off the box.
Why Studio
In v3, the framework gave you a black-box app.listen(). In v4, the framework already exposes a richer runtime (AppContainer.introspect(), lifecycle hooks, structured logger, interceptors). Studio is the interactive surface for all of that runtime data.
| Without Studio | With Studio |
|---|---|
console.log until you find the failing request | Click a request in the Timeline, see the full trace, body, headers, and stack |
Run npm audit once a sprint | Live security dashboard with reachability scoring and one-click fixes |
| Guess which routes are slow | Per-route P50/P95/P99, throughput, and slowest-endpoint highlights from real traffic |
Mentally rebuild the DI graph from provide() calls | Architecture Map auto-generated from AppContainer.introspect() |
Reproduce a bug with curl and a notes file | Replay any recorded request and diff the new response |
| Open coverage HTML in the browser after every run | Git-aware diff coverage, annotated source, and one-click test runs in Studio |
Architecture
Studio is split into two publishable packages plus a local database so production builds stay lean. The CLI boots the UI; the agent lives inside your app and streams data over WebSocket; recordings persist to SQLite on disk.

| Package | Where it runs | What it does |
|---|---|---|
@expressots/studio | Standalone dev process | Boots the Web UI, probes the agent, opens the browser, owns the CLI. |
@expressots/studio-agent | Inside your app process | Instrumentation middleware, SQLite recorder, log capture, DI snapshot, security engine, WebSocket server. |
@expressots/adapter-express dynamically imports @expressots/studio-agent only when it is installed and NODE_ENV=development, so production deployments never load the agent code and never pay the runtime cost.
Features
Studio opens at http://localhost:3333 once you run npx expressots-studio with your app already in dev mode. The sidebar groups every capability below. All views update live over Socket.IO while traffic flows through your app.
Each view is documented on its own page under Features:

| View | Summary |
|---|---|
| Status | At-a-glance health: uptime, memory, slow routes, error rates, security grade. |
| Requests | Live HTTP timeline with trace detail, replay, and export. |
| Logs | Streamed framework and app logs with level and route filters. |
| API Client | Built-in HTTP client for smoke-testing endpoints. |
| Container | DI binding table and interactive dependency graph. |
| Architecture | Read-only map from AppContainer.introspect(). |
| Database | Read-only browser for the v4 in-memory DB provider. |
| Metrics | Throughput, per-route latency percentiles, slowest endpoints, memory, and system health. |
| Replay | Batch re-run recorded exchanges with side-by-side diffs. |
| Security | Supply-chain advisories with reachability scoring and OWASP runtime posture. |
| Coverage | Git-aware code coverage, diff coverage, annotated source, and in-Studio test runs. |
Open Settings from the sidebar footer to tune theme, retention limits, replay diff ignore rules, and keyboard shortcuts (? toggles the shortcuts overlay).
Performance posture
Studio is built to disappear in production and stay out of the hot path in development:
- Production builds: the studio-agent module is never imported because
NODE_ENV !== "development". There is zero overhead, zero added port, zero file I/O. - Recording: writes to a local SQLite file (
.studio/studio.db) via prepared statements; writes are batched and never block the request thread. - Security scans:
npm auditruns as an async child process; results are cached on disk; the engine re-runs only when the lockfile changes or a fix completes. - Logs / metrics: kept in a bounded in-memory ring buffer; oldest entries are dropped first.
- UI broadcasts: every frame is debounced and only emitted when at least one client is connected.
See Installation to add Studio to an existing project.