@lovelaces-io/storyteller

Your logs should tell a story

Collect notes as things happen. Emit one structured record when the story is complete. Zero dependencies.

$ npm install @lovelaces-io/storyteller
Get Started GitHub

Ever stared at scattered logs trying to figure out what happened?

Traditional logging gives you a pile of disconnected lines. Storyteller gives you one record that tells the whole story.

Before: scattered logs

console
[14:30:00] User clicked checkout
[14:30:00] Validating cart...
[14:30:01] Cart valid
[14:30:01] Charging card...
[14:30:03] ERROR: gateway timeout
[14:30:03] Retrying...
[14:30:04] Charge succeeded
[14:30:04] Order confirmed

After: one story

story record
{
  "level": "Warning",
  "title": "Payment retry succeeded",
  "durationMs": 4000,
  "notes": [
    { "timestamp": "14:30:00", "note": "User clicked checkout" },
    { "timestamp": "14:30:01", "note": "Cart validated" },
    { "timestamp": "14:30:03", "note": "Card declined",
      "error": { "message": "gateway timeout" } },
    { "timestamp": "14:30:04", "note": "Retry succeeded" }
  ]
}

How it works

Three steps. That's it.

1

Collect notes

Add timestamped notes as things happen. Attach context — who, what, where, errors.

2

Tell the story

Call tell(), warn(), or oops() when the operation is done.

3

One record, anywhere

Audiences hear the story — console prints it, database stores it, your custom handler does whatever you need.

See it in action

A real-world example: tracking a payment flow.

checkout.ts
import { Storyteller, dbAudience } from "@lovelaces-io/storyteller";

const story = new Storyteller({
  origin: { who: "checkout-service", where: { app: "web" } },
});

// Store warnings and errors in your database
story.audience.add(
  dbAudience(async (event) => await db.insert("logs", event))
);

// Collect notes as the operation progresses
story.note("User submitted payment", {
  who: { id: "user:413" },
  what: { amount: 49.99, currency: "USD" },
});

story.note("Charging card", { where: "stripe" });
story.note("Payment approved");

// Tell the story — one record, delivered to all audiences
story.tell("Payment completed");

Built for developers who care about their logs

Zero Dependencies

Nothing to install besides Storyteller. Lightweight by design, stays out of your way.

TypeScript-First

Full type safety, declaration files, and IntelliSense. Dual ESM + CJS builds.

One Record Per Story

Notes are collected and emitted as a single structured JSON record. Store it, search it, read it.

Pluggable Audiences

Console, database, Slack, custom — stories go where you need them. Add your own in 5 lines.

Three Levels

tell — all good. warn — heads up. oops — something broke.

AI-Friendly

Structured JSON output, clear types, llms.txt included. Built for humans and agents alike.

Ready to tell better stories?

Install and start logging in under a minute.

$ npm install @lovelaces-io/storyteller
Read the Docs View on GitHub