You know the dance.
An endpoint is slow. So you open the handler and start sprinkling:
console.log("got here");
console.log("query done", Date.now() - t0);
console.log("still here??");
Then you squint at tail -f, mentally stitch the lines back into an order,
and try to remember which log came from which request, because three of them
are interleaved.
I did this for years. Then one day it hit me that the frontend solved this
fifteen years ago. You open DevTools, you get a Network tab, and you just
see it. Waterfall, timings, what fired when.
The backend never got that. So I built it.
Wevna
One line, at the top of whatever file boots your server:
// server.js / index.ts / main.ts, as early as you can
import { wevna } from "@wevna/sdk";
await wevna.start();
// ...your Express / Fastify / Nest app, completely unchanged
Open localhost:4123. Hit an endpoint. That's the entire setup: no
middleware to register, no context object to pass around, nothing else to
touch.
Every HTTP request, SQL query, Redis command, console.log and uncaught
exception, grouped under the request that caused it, automatically. No
context object to thread through your handlers. No config file. No agent.
The bit that made it worth finishing
I pointed it at a demo app with a deliberately dumb loop in it, and it said
this without being asked:
Repeated Query
The same query ran 4 times, taking 198ms in total:
select * from "orderitems" where "orderid" = ?
That's an N+1. It found it by noticing four queries with the same shape but
different values, which is what an N+1 actually looks like from the outside.
It won't tell you it's a bug, because sometimes it isn't. It just puts the
number in front of you.
The part I care about most
Nothing leaves your machine.
No account. No API key. No egress. The dashboard binds to localhost, the
data lives in memory in your own process, and I have no idea you're running
it. It's a devDependency in spirit, closer to DevTools than to Datadog.
It's also deliberately careful about what it captures:
- SQL parameter values are never read, only the query text
- Redis command arguments are never recorded: commands like
SET session:abc <token>carry secrets inline, so there's no safe subset -
console.logis stored as the formatted string, never the raw objects
What it can't do (yet)
Full honesty, since this is v1:
- Postgres and Redis only. MySQL and Mongo aren't there.
- Memory-bounded. Built for a debugging session, not to run for a week.
- The dashboard is unauthenticated. It's on localhost for that reason.
- It reports rather than diagnoses. It'll show you a repeated query; it won't claim to know why.
Where I'd like it to go
The thing I actually want is a time machine for backend bugs.
Recording and replay already work: you can dump a session to a JSON Lines
file and scrub through it later, at 0.25× to 8×, with no app running. Every
part of the UI works at whatever position you've scrubbed to.
So the shape of it is already there:
Prod does something weird at 3am. A recording lands in your repo. You open
it on your laptop next morning and watch it happen, step by step, like a
replay.
That's the version I'm building toward. Attaching a recording to a bug report
instead of pasting log fragments into Slack.
Try it
There's a runnable demo (no database or containers needed):
git clone https://github.com/wevna/wevna.git
cd wevna && pnpm install && pnpm build
pnpm --filter @wevna/example-express dev
Then curl localhost:3000/orders/42 and watch the dashboard. That endpoint
has the N+1 in it.
Or drop it into your own app:
npm install @wevna/sdk
GitHub: https://github.com/wevna/wevna
npm: https://www.npmjs.com/package/@wevna/sdk
MIT. Node 22+. Built over the last few months, ~900 tests, and genuinely used
by me to debug my own stuff.
I'd really like to know two things:
- Does it survive contact with your app? It's been tested by exactly one person so far, and that person is biased.
- What's the first thing you went looking for and couldn't find?
Issues, replies, whatever's easiest. I'm listening.

Top comments (0)