Event Schema
A portable, typed YAML format for declaring product analytics events — what events your app fires, what they carry, and what each one means. Codegen, validation, and agents read this file to understand your event schema without grepping source code.
Paste to your agent
Why declare a schema
Most product analytics tools treat event schema as tribal knowledge. Property names live in code comments, internal wikis, or Slack threads. AI agents asking “what does cta_click carry?” have to grep your codebase. Renames mean manual sweeps across hundreds of call sites. A declarative event-schema file fixes all three:
- Discoverable. Agents and humans read the file instead of grepping.
- Refactor-safe. Rename a property in one place, regenerate types, TypeScript surfaces every broken call site at build time.
- Durable. The intent of each event survives past the conversation that produced it — for new agents, new teammates, and the original author six months later.
Install
# One-off
npx @clamp-sh/event-schema generate
# Or as a dev dependency
npm install --save-dev @clamp-sh/event-schemaAuto-discovers event-schema.yaml from the current directory or any parent and writes the generated types alongside it. See Commands for output options.
Quick start
Author event-schema.yaml at your project root:
version: "0.1"
events:
signup_completed:
intent: |
Primary conversion event — account creation succeeded.
properties:
plan:
type: enum
values: [free, pro, growth]
required: true
method:
type: enum
values: [email, github]
required: true
cta_click:
intent: |
Top-of-funnel engagement signal — which CTA earned the click.
properties:
location:
type: string
required: true
examples: [hero_primary, nav_signup, final_cta]
destination:
type: string
required: trueGenerate types:
npx event-schema generateWrites event-schema.d.tsnext to the source. Use it with the SDK’s typed-events generic:
import { track } from "@clamp-sh/analytics";
import type { AnalyticsEvents } from "./event-schema";
track<AnalyticsEvents>("signup_completed", { plan: "pro", method: "email" });
// ^ event name + properties type-checked at compile timeTypeScript will catch typo’d event names, missing required properties, wrong property names, and wrong value types — all at build time, before any event ever fires.
Format
Top-level fields are version and events. Each event has an optional intent(one sentence on what it’s for) and a required properties object.
| Property type | TypeScript output |
|---|---|
string | string |
number | number |
boolean | boolean |
enum with values: [...] | String union of the values |
money | { amount: number; currency: string } |
Each property may also declare required: true (defaults to false), description (carried into the generated JSDoc), and examples: [...] (sample values, surfaced as @example in the JSDoc — purely informational, not validated).
Full format definition lives in the spec on GitHub.
Commands
event-schema validate
event-schema generatevalidatechecks the schema against the spec’s meta-schema and exits non-zero on errors. generate emits a TypeScript declaration. Both auto-discover event-schema.yaml (or .json) by walking up from the current directory; pass an explicit path to override.
Options for generate
| Flag | What it does | Default |
|---|---|---|
-o, --output <path> | Write to a different path. Pass - for stdout. | event-schema.d.ts next to the source |
--type-name <name> | Name of the exported events type | AnalyticsEvents |
Examples
The spec repo includes three canonical examples — minimal, SaaS-flavored, and ecommerce (with the money type) — each pairing the input YAML with the TypeScript the CLI produces:
- minimal — single event, single property
- saas — multi-event with empty-properties events and enums
- ecommerce — money type and quantities
Status
Spec version 0.1. The format is in active dogfood; the design may change before reaching 1.0. The reference CLI (@clamp-sh/event-schema) implements the full spec. Source and the spec itself live at github.com/clamp-sh/event-schema.