Why Vision?
Real debugging scenarios that show why Vision changes how you build APIs
Why Vision?
TL;DR: Vision shows you exactly what happened when something breaks. No more guessing, no more console.log archaeology.
The Problem Vision Solves
You're building an API. A request fails. What do you do?
Without Vision:
# Add console.log everywhere
console.log('1. Got request', req.body)
console.log('2. User found', user)
console.log('3. About to query DB')
console.log('4. DB result', result)
# Run request again, scroll through terminal
# Still confused? Add more logs
# Repeat until you find the bug
# Delete all the console.logs (or forget to)With Vision:
- Open dashboard at
localhost:9500 - Click the failed request
- See the waterfall: exactly which step failed and why
- Fix it
That's it. No code changes, no restarts, no cleanup.
Real Debugging Scenarios
Scenario 1: "Why is this endpoint slow?"
Your /users/:id endpoint takes 2 seconds. Something's wrong.
Without Vision: Add timing logs around every operation. Rebuild. Test. Analyze logs. Repeat.
With Vision:
GET /users/123 (2.1s) ← You see this is slow
├── middleware.auth (3ms) ← This is fast
├── handler (2.09s) ← Problem is here
│ ├── db.select.users (45ms) ← DB is fine
│ ├── db.select.orders (1.8s) ← N+1 query! 50 separate queries
│ └── cache.set (200ms) ← Redis slow too
└── response (5ms)The answer is obvious: You have N+1 queries in the orders lookup. Vision shows you the exact operation and its duration.
Scenario 2: "The request body is wrong somehow"
Validation fails but you're not sure why.
With Vision:
Click the failed trace. See:
- Request body: Exactly what was sent (not what you think was sent)
- Validation error:
"email" must be a valid email - Schema: The Zod schema that rejected it
{
"request": {
"body": {
"name": "John",
"email": "john@" // ← There's your problem
}
},
"error": {
"field": "email",
"message": "Invalid email format",
"received": "john@"
}
}Scenario 3: "It works locally but fails in staging"
The eternal mystery. Same code, different behavior.
With Vision:
Compare traces side by side:
- Local: All spans complete successfully
- Staging: The
external.api.paymentspan fails with timeout
Staging trace:
├── handler (30.1s) ← Timeout!
│ └── external.api.payment (30s → TIMEOUT)
│ └── attributes: { url: "https://api.stripe.com/...", error: "ETIMEDOUT" }The answer: Payment API isn't accessible from staging network. Not a code bug.
Scenario 4: "Who called this endpoint with wrong params?"
Your logs show errors but you don't know the context.
With Vision:
Every trace captures:
- Full request headers (including
X-Request-ID, auth tokens) - Client IP, User-Agent
- Full request/response bodies
- Timing for every operation
- Associated
console.logcalls
One click shows you everything about that request.
Scenario 5: "The database query is correct but returns nothing"
You've checked the SQL, it looks right.
With Vision:
See the actual query parameters:
Span: db.select.users
├── db.table: "users"
├── db.operation: "SELECT"
├── query.params: { "id": "123" } // ← It's a string!
└── result.rows: 0
// Your database has id as INTEGER
// You're querying with "123" (string) not 123 (number)What Makes Vision Different
vs DataDog / NewRelic / Sentry
- Free and open source - No $50/month minimum, no usage limits
- Runs locally - Your data stays on your machine during development
- Zero config - Works in 2 lines of code, not 2 hours of setup
- Developer-focused - Built for debugging, not enterprise dashboards
vs console.log
- No code changes - Everything is captured automatically
- Structured data - Search, filter, correlate
- Waterfall view - See timing and nesting at a glance
- Persists - Traces survive restarts during dev
vs Postman / Insomnia
- Live tracing - See what happened inside your server, not just response
- Auto-discovery - All routes appear automatically
- Schema-aware - Generates request templates from Zod schemas
- Integrated - Testing + debugging in one tool
vs OpenTelemetry
- Beautiful UI included - Not just a data format
- Batteries included - Dashboard, API explorer, service catalog
- Zero boilerplate - No instrumentation code to write
- Dev-focused - Optimized for local development, not production APM
The "Aha" Moment
Most developers get Vision in about 5 minutes:
- Install:
npm install @getvision/adapter-hono(or your framework) - Add 2 lines:
app.use('*', visionAdapter()) enableAutoDiscovery(app) - Make a request to your API
- Open localhost:9500
- Click the trace
- See everything: The full waterfall, timing, request/response data, any DB queries
That's the moment. You realize you're not guessing anymore. You're seeing.
When to Use Vision
Use Vision when:
- Building APIs (REST, will support GraphQL/tRPC/MCP)
- You want to understand what's happening inside your server
- Debugging slow endpoints, validation errors, weird behavior
- Working locally or in staging
- Testing your API without switching to Postman
Don't use Vision when:
- You need production APM with alerting → Use DataDog/NewRelic
- You're building a frontend-only app → Vision is for backend APIs
- You need distributed tracing across microservices → Vision is single-service (for now)
Quick Start
Existing App (Hono/Express/Fastify)
npm install @getvision/adapter-hono # or adapter-express, adapter-fastifyimport { visionAdapter, enableAutoDiscovery } from '@getvision/adapter-hono'
app.use('*', visionAdapter())
enableAutoDiscovery(app)Dashboard: http://localhost:9500
New Project
npm install @getvision/serverimport { Vision } from '@getvision/server'
const app = new Vision({ service: { name: 'My API' } })
app.service('users')
.endpoint('GET', '/users/:id', { input, output }, handler)
app.start(3000)Dashboard: http://localhost:9500
Next Steps
- Quickstart - Full setup in 5 minutes
- Tracing Deep Dive - Understanding waterfall visualization
- Debugging Workflows - Step-by-step debugging guides