Skip to content

Appwire — Live App REPL for Node.js

Run code inside your running app. No restarts. No debug endpoints.

appwire(ipc:main.ts) > $users = await $app.get(UserService).findAll()
[{ id: 1, email: 'alice@example.com' }, ...] 18ms
appwire(ipc:main.ts) > $users[0].email
'alice@example.com' 0ms
appwire(ipc:main.ts) > .timeit 20 await $app.get(PrismaService).user.count()
42
runs: 20 avg: 4ms min: 3ms max: 8ms
appwire(ipc:main.ts) > .doc $app.get(AuthService)
AuthService
Methods:
login(dto)
logout(userId)
validateToken(token)

Inspect live state

Read env vars, in-memory caches, active connections, and feature flags while the app runs.

Call services directly

$app.get(UserService).findAll() returns the real service instance — no HTTP layer, no test harness.

Benchmark in context

.timeit 100 expr times anything against real data with real DI. Numbers reflect production conditions.

Save results as variables

$x = expr stores any result for the session. Tab-completes. Listed by .vars.


Appwire has two parts that meet at an IPC channel:

  • Bootstrap — a self-contained script injected into your app via --require. Opens an IPC channel, sets up a VM context ($app, $env, $fetch, $reload, require), and intercepts console.*.
  • REPL — the appwire binary connects over IPC, sends code to evaluate, and streams results and logs back.

Your app runs normally. Appwire sits alongside it.


Terminal window
npm install -g appwire
cd your-project
appwire

Appwire detects your entry point from package.json. If it can’t:

Terminal window
appwire --entry src/main.ts # explicit file
appwire --entry apps/backend/ # directory — entry detected inside

Or add a .appwirerc to your project root to avoid repeating --entry:

{ "entry": "src/main.ts" }

Adapters wire your framework’s DI container into $app. Without one, you still get $env, $fetch, and require.

app.module.ts
export class AppModule {}

$app.get(ServiceName) resolves any injectable. .services lists the full DI container.


Assign any result to a $-prefixed variable — it persists for the rest of the session:

appwire > $users = await $app.get(UserService).findAll()
[{ id: 1, email: 'alice@example.com' }, ...] 18ms
appwire > $users[0].email
'alice@example.com' 0ms
appwire > $svc = $app.get(UserService)
UserService {} 0ms
appwire > $svc.findById(1)
{ id: 1, email: 'alice@example.com' } 4ms

Variables tab-complete automatically and are listed by .vars.


  • Agent only activates under NODE_ENV=development. A no-op in production regardless of how the process starts.
  • IPC channel is process-local. Only the parent appwire process can send messages. No network exposure.

IPC mode

Entry detection, .appwirerc, TypeScript runtimes, auto-reconnect. → IPC mode guide

CLI reference

All dot-commands, flags, eval context variables, and session variables. → CLI reference