currently building

analytics that ships with your code.

Product analytics configured in your repo, typed end-to-end, generated from conventions. No more dashboard maintenance, just better product decisions.

For technical founders and small product teams. No spam — just a heads up when it's ready.

Typed events

Tracking defined with strict contracts, reviewable in pull requests like any other code.

Versioned analytics

Product and analytics changes ship together. Every change inspectable with git diff.

No dashboard debt

Funnels, retention, and adoption generated from config. No charts to rebuild every sprint.

How it will look in code

Define events once, track with a typed client, compute product insights from those definitions. This is the API we're building toward.

dotyc/events.ts
import { defineEvent, d } from '@dotyc/core'
import { z } from 'zod'

export const signedUp = defineEvent('signed_up', {
  properties: {
    source: z.enum(['organic', 'referral', 'paid'])
  }
})

export const featureUsed = defineEvent('feature_used', {
  properties: {
    userId: d.entity('user'),
    feature: z.string()
  }
})

Define events with typed schemas and strict contracts your team reviews in pull requests.

app/api/export/route.ts
import { dotyc } from '@/lib/dotyc'

dotyc.track(ev => ev.featureUsed, {
  userId: session.userId,
  properties: { feature: 'export' }
}) // fully typesafe — properties are inferred from the config

Track usage with a fully typesafe client — properties inferred from your config.

dotyc/insights.ts
import { defineInsight, countUnique, count } from '@dotyc/core'
import { signedUp, featureUsed } from './events'
import { users } from './sources'

export const activationRate = defineInsight('activation-rate', {
  compute: ({ activated, signed }) => activated / signed,
  inputs: {
    activated: countUnique(featureUsed, users),
    signed: count(signedUp)
  }
})

Compute insights from event definitions. Funnels, retention, adoption — all from code.

dotyc/visualizations.ts
import { defineVisualization } from '@dotyc/core'
import { activationRate } from './insights'

export const activationChart = defineVisualization('activation', {
  insight: activationRate,
  type: 'line',
  options: {
    format: 'percent',
    showDelta: true
  }
})

Visualize with charts generated from your insights. No dashboard to maintain.

terminal
$

founder note

You're shipping features, fixes, and experiments fast. That's exactly what early teams should do.

Then someone asks: what are users actually doing?

The common setup works for a while, but product changes faster than tracking plans. Dashboards drift. Definitions get stale. Analytics debt builds quietly.

I'm building dotyc to fix this with a config-first approach: analytics that lives in your codebase, gets reviewed, and evolves with every feature.

The focus will be on the workflows early teams need most: funnels, retention, and feature adoption. Less surface area, more leverage.

Later: feature flags and A/B testing, same config-first way.

If this resonates, leave your email and I'll reach out when it's ready.

best,

quentin