---
title: "Introduction"
description: "Understand what happened in your app with evlog: structured logging, wide events, and errors that explain what went wrong and how to fix it."
canonical_url: "https://www.evlog.dev/start/introduction"
---
# Introduction

> Understand what happened in your app with evlog: structured logging, wide events, and errors that explain what went wrong and how to fix it.

**evlog** is a TypeScript logging library that helps you understand what happened in your app. Start with structured logs, bring a request’s context together in one wide event, and turn failures into errors that explain what went wrong and how to fix it.

New to structured logging in Node.js? [Structured logging in Node.js](https://www.evlog.dev/use-cases/structured-logging-nodejs) walks through it end to end.

Use it in your next project or introduce it alongside your existing logger. The [Quick Start](https://www.evlog.dev/start/quick-start) gets you going; the [migration examples](https://www.evlog.dev/learn/simple-logging) show how to bring familiar logging patterns to evlog.

Inspired by [Logging Sucks](https://loggingsucks.com/) by [Boris Tane](https://x.com/boristane). The separate [evlog CLI](https://www.evlog.dev/cli/overview) helps you explore your logs and spot missing logging patterns with static checks.

## Philosophy

Traditional logging is broken. Your logs are scattered across dozens of files. Each request generates 10+ log lines. When something goes wrong, you're left grep-ing through noise hoping to find signal.

**evlog** takes a different approach:

<card-group>
<card icon="i-lucide-terminal" title="Structured Logging">

Replace `console.log` with typed, structured events that flow through a drain pipeline. Same level filtering, redaction, and pretty/JSON output as pino or consola.

</card>

<card icon="i-lucide-layers" title="Wide Events">

Accumulate context over any unit of work (a request, script, or job) and emit once. The two modes coexist, and neither is an upgrade of the other.

</card>

<card icon="i-lucide-shield-alert" title="Structured Errors">

Errors that explain why they occurred and how to fix them.

</card>

<card icon="i-lucide-palette" title="Pretty for Dev">

Human-readable in development, machine-parseable JSON in production.

</card>
</card-group>

<callout color="info" icon="i-lucide-globe">

Not running an HTTP framework? See [Standalone TypeScript](https://www.evlog.dev/integrate/frameworks/standalone) for scripts, workers, and CLIs, and [Cloudflare Workers](https://www.evlog.dev/integrate/frameworks/cloudflare-workers) for the edge runtime.

</callout>

## Why evlog over pino, winston, or consola

evlog is a fully-featured general-purpose logger that happens to also do wide events. Concretely:

- **Zero runtime dependencies in the core package.** Start with the logger and add integrations as you need them. See [Performance](https://www.evlog.dev/reference/performance) for bundle sizes and benchmarks.
- **Same API in every context**: scripts, frameworks, edge runtimes, browser, library code. No `pino-http` vs `pino` split, no separate `consola` reporters per environment.
- **Structured errors with why / fix / link built in**: your error toast finally tells users what went wrong and what to do, your on-call stops reverse-engineering stack traces.
- **Wide events as a free upgrade path**: when you need to correlate context across an operation, the same logger gives you `log.set` + `log.emit` instead of stitching log lines together later.

See the full [feature comparison](https://www.evlog.dev/reference/vs-other-loggers) (parity matrix, honest gaps, and migration snippets) for a side-by-side with pino, winston, and consola.

## Pick one of three ways to log

evlog provides three APIs for different contexts. You can use all three in the same project.

### Simple Logging

Fire-and-forget structured logs. Replace `console.log`, consola, or pino:

```typescript [src/index.ts]
import { log } from 'evlog'

log.info('auth', 'User logged in')
log.error({ action: 'payment', error: 'card_declined', userId: 42 })
```

### Wide Events

Accumulate context progressively over any operation, then emit a single comprehensive event:

<code-group>

```typescript [scripts/sync-job.ts]
import { createLogger } from 'evlog'

const log = createLogger({ jobId: 'sync-001', queue: 'emails' })
log.set({ batch: { size: 50, processed: 50 } })
log.emit()
```

```typescript [src/worker.ts]
import { createRequestLogger } from 'evlog'

const log = createRequestLogger({ method: 'POST', path: '/api/checkout' })
log.set({ user: { id: 1, plan: 'pro' } })
log.emit()
```

</code-group>

With a framework integration, the logger is created when the request starts and emitted when the response ends. A handler only adds what it learns:

<framework-tabs>

```typescript [Nuxt]server/api/checkout.post.ts
import { useLogger } from 'evlog'

export default defineEventHandler(async (event) => {
  const log = useLogger(event)

  log.set({ user: { id: 1, plan: 'pro' } })
  return { success: true }
  // auto-emitted on response end
})
```

```typescript [Nitro]routes/api/checkout.post.ts
import { defineHandler } from 'nitro/h3'
import { useLogger } from 'evlog/nitro/v3'

export default defineHandler(async (event) => {
  const log = useLogger(event)

  log.set({ user: { id: 1, plan: 'pro' } })
  return { success: true }
  // auto-emitted on response end
})
```

```typescript [Next.js]app/api/checkout/route.ts
import { withEvlog, useLogger } from '@/lib/evlog'

export const POST = withEvlog(async () => {
  const log = useLogger()

  log.set({ user: { id: 1, plan: 'pro' } })
  return Response.json({ success: true })
  // auto-emitted on response end
})
```

```typescript [Hono]src/index.ts
app.post('/api/checkout', async (c) => {
  const log = c.get('log')

  log.set({ user: { id: 1, plan: 'pro' } })
  return c.json({ success: true })
  // auto-emitted on response end
})
```

```typescript [Express]src/index.ts
app.post('/api/checkout', async (req, res) => {
  const log = req.log

  log.set({ user: { id: 1, plan: 'pro' } })
  return res.json({ success: true })
  // auto-emitted on response end
})
```

</framework-tabs>

One log, all context. Everything you need to understand what happened.

### Structured Errors

Errors with actionable context: `why` it happened, how to `fix` it, and a `link` to docs:

<code-group>

```typescript [services/checkout.ts]
import { createError } from 'evlog'

throw createError({
  message: 'Payment failed',
  status: 402,
  why: 'Card declined by issuer (insufficient funds)',
  fix: 'Try a different payment method or contact your bank',
  link: 'https://docs.example.com/payments/declined',
})
```

```json [Response]
{
  "statusCode": 402,
  "message": "Payment failed",
  "data": {
    "why": "Card declined by issuer (insufficient funds)",
    "fix": "Try a different payment method or contact your bank",
    "link": "https://docs.example.com/payments/declined"
  }
}
```

</code-group>

## Why one event beats ten lines

We're entering an era where AI agents build, debug, and maintain applications. These agents need **structured context** to work effectively:

- **why**: The root cause, so the agent understands what went wrong
- **fix**: An actionable solution the agent can suggest or apply
- **link**: Documentation for complex issues

Traditional `console.log` and generic `throw new Error()` provide no actionable context. evlog's structured output is designed for both humans and AI to parse and act on.

## Next Steps

- **Try evlog:** follow [Installation](https://www.evlog.dev/start/installation) and the [Quick Start](https://www.evlog.dev/start/quick-start).
- **Decide whether it fits your project:** read [Choosing a TypeScript Logger](https://www.evlog.dev/start/typescript-logging-library), or [Why start with evlog](https://www.evlog.dev/start/why-evlog) for a new application.
- **Explore the concepts:** the [Logging Overview](https://www.evlog.dev/learn/overview) connects simple logs, wide events, and structured errors.

---

- [Quick Start](https://www.evlog.dev/start/quick-start)
- [GitHub](https://github.com/evloghq/evlog)


## Sitemap

See the full [sitemap](https://www.evlog.dev/sitemap.md) for all pages.
