Typed observability primitives for TypeScript apps. Bring your own catalog; Spectra handles the rest.
📚 Docs: https://rachelallyson.github.io/spectra/
Spectra is a tiny library for app-wide observability built around the
Capital One Stratum-Observability
patterns: a typed catalog as the single source of truth, runtime-validated
emit(), and publisher fan-out to whatever vendors you use. No runtime
dependencies (zod is a peer); ~1.7k lines of TypeScript; full IDE
autocomplete on every event.
import { defineCatalog, consolePublisher } from '@rachelallyson/spectra'
import { z } from 'zod'
const catalog = defineCatalog({
'app.started': z.object({ env: z.string(), version: z.string() }),
'guest.created': z.object({ tenantId: z.string(), guestId: z.string() }),
})
catalog.setPublishers([consolePublisher()])
catalog.emit('app.started', { env: 'production', version: '1.0.0' })
// ^ TypeScript and Zod both validate thisMost observability is unstructured console.log plus whatever Sentry sees.
That works until it doesn't — and when it doesn't, you spend an hour
grepping logs for the one signal that would have closed the case in
seconds.
The Stratum pattern fixes this by making every observable behavior a named, typed entry in a catalog. The catalog becomes the contract: every emit validates against it, tests assert sequences against it, and a coverage report flags which catalog entries no test ever exercises.
Spectra ships the patterns, not the framework. No runtime dependencies; full type safety; small enough to read in one sitting.
- OpenTelemetry — OTel is the right answer for distributed traces and vendor-portable metrics. It is not a great fit for "here are the 60 named business events our app cares about, with typed payloads." Spectra sits above OTel: catalog-defined events, validated at the edge, fanned out to whatever sinks you already use.
- pino / winston — log lines, not events. No catalog, no schema, no test-time coverage report telling you which events are unreachable.
- PostHog / Segment / Amplitude SDKs — vendor-specific. Spectra is
vendor-neutral by construction: write a 20-line
Publisherand any vendor becomes a fan-out target. Use as many as you want. - Stratum-Observability (Capital One) — same patterns. Spectra is the small, isomorphic, zero-dep TypeScript take, with first-class test harness and browser support.
- Typed catalog factory —
defineCatalog(schemas)returns a fully- typed emitter. TS rejects bad event names; Zod validates payloads at runtime. - Publishers —
console,memory(for tests),http(browser → server fan-out, withsendBeaconon unload),fileSink(Node-only durable JSONL). Bring your own for Sentry / Axiom / PostHog. - Coverage —
coveragePublisher()tallies hit counts in memory on either side of the wire;mergeCoveragecombines a browser snapshot with a server snapshot;formatCoverageSummary(report)returnsCoverage: 12/15 (80%) — missed: foo, bar, …for CI annotations. - Request context —
createContext<T>()returns an AsyncLocalStorage store generic over your app's shape. Set once at the edge, read anywhere. - Error pathway —
captureErroris intentionally separate fromemit(). Events describe things that happened; errors describe things that went wrong. Sentry is the right place for the latter. - Lifecycle wrappers —
createWrappers({ catalog, procedure, job })emitsstarted/succeeded/failedaround any async function. Drop one middleware on tRPC, wrap your Inngest handlers, get uniform signal. - Test harness —
expectSequence(['a.started', 'a.succeeded'])for flow tests;assertFullCoverage([...])for catalog backstop. - Coverage report — Vitest globalTeardown reads a JSONL event log and
writes
obs-coverage.mdso PR diffs surface drift. - Browser-safe core — root entry,
/publishers,/coverage,/catalog,/errors,/wrappersship withoutnode:imports. Node-only sinks live behind explicit subpaths (/publishers/node,/coverage-report,/context,/test-harness).
pnpm add @rachelallyson/spectra zod
# or: npm install @rachelallyson/spectra zodNode 18+. Zod 3 or 4 works.
- Getting Started — install + first events
- Concepts — catalog, publishers, context, error pathway
- Recipes — tRPC, Inngest, Vitest setup, vendor adapters
- API Reference — every export with signatures
- Examples — runnable sample apps
- Capital One's Stratum-Observability for the catalog + publisher patterns.
- OpenTelemetry for the request-context discipline.
Spectra deliberately doesn't try to replace OpenTelemetry — it's the typed-events-and-business-state layer that sits above OTel traces and metrics.