{"id":46928880,"url":"https://github.com/mathematic-inc/alyt","last_synced_at":"2026-07-06T03:00:28.240Z","repository":{"id":341102778,"uuid":"1168947006","full_name":"mathematic-inc/alyt","owner":"mathematic-inc","description":"All-in-one analytics SDK for TypeScript — unified API for GA, PostHog, Mixpanel, Amplitude, Plausible, and Vercel Analytics with YAML codegen and React bindings","archived":false,"fork":false,"pushed_at":"2026-03-11T04:38:27.000Z","size":311,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T03:38:34.596Z","etag":null,"topics":["amplitude","analytics","codegen","google-analytics","mixpanel","plausible","posthog","react","sdk","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathematic-inc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"mathematic-inc"}},"created_at":"2026-02-28T01:21:13.000Z","updated_at":"2026-03-11T04:38:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mathematic-inc/alyt","commit_stats":null,"previous_names":["jrandolf/alyt","mathematic-inc/alyt"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/mathematic-inc/alyt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathematic-inc%2Falyt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathematic-inc%2Falyt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathematic-inc%2Falyt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathematic-inc%2Falyt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathematic-inc","download_url":"https://codeload.github.com/mathematic-inc/alyt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathematic-inc%2Falyt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35176125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-06T02:00:07.184Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amplitude","analytics","codegen","google-analytics","mixpanel","plausible","posthog","react","sdk","typescript"],"created_at":"2026-03-11T04:07:49.815Z","updated_at":"2026-07-06T03:00:28.214Z","avatar_url":"https://github.com/mathematic-inc.png","language":"TypeScript","funding_links":["https://github.com/sponsors/mathematic-inc"],"categories":[],"sub_categories":[],"readme":"# alyt\n\nAll-in-one Analytics SDK.\n\nDefine your analytics events in a YAML schema and get a fully typed TypeScript tracker — no more typos in event names or missing properties. alyt sends events to Google Analytics, PostHog, Mixpanel, Amplitude, Plausible, and Vercel Analytics through a single API, and lets you add or remove providers at runtime for consent flows.\n\n## Install\n\n```bash\n# core\npnpm add @alyt/core\n\n# plugins (pick what you use)\npnpm add @alyt/plugin-ga\npnpm add @alyt/plugin-posthog\npnpm add @alyt/plugin-mixpanel\npnpm add @alyt/plugin-amplitude\npnpm add @alyt/plugin-plausible\npnpm add @alyt/plugin-vercel\n\n# react bindings\npnpm add @alyt/react\n\n# codegen (dev dependency)\npnpm add -D @alyt/codegen\n```\n\n## Quick Start\n\n```typescript\nimport { createAnalytics } from \"@alyt/core\";\nimport { googleAnalytics } from \"@alyt/plugin-ga\";\nimport { posthog } from \"@alyt/plugin-posthog\";\n\nconst analytics = createAnalytics({\n  plugins: [\n    googleAnalytics({ measurementId: \"G-XXXXXXXXXX\" }),\n    posthog({ apiKey: \"phc_XXXXXXXXXX\" }),\n  ],\n});\n\nanalytics.track(\"button_clicked\", { label: \"Sign Up\" });\nanalytics.identify(\"user_123\", { plan: \"pro\" });\nanalytics.page(\"Home\");\n```\n\nEvery call fans out to all registered plugins. Plugins that don't implement a method (e.g. Plausible has no `identify`) are silently skipped.\n\n## Plugins\n\n| Plugin | Package | Factory | Required Options |\n| --- | --- | --- | --- |\n| Google Analytics | `@alyt/plugin-ga` | `googleAnalytics()` | `measurementId: string` |\n| PostHog | `@alyt/plugin-posthog` | `posthog()` | `apiKey: string` |\n| Mixpanel | `@alyt/plugin-mixpanel` | `mixpanel()` | `token: string` |\n| Amplitude | `@alyt/plugin-amplitude` | `amplitude()` | `apiKey: string` |\n| Plausible | `@alyt/plugin-plausible` | `plausible()` | `domain: string` |\n| Vercel Analytics | `@alyt/plugin-vercel` | `vercelAnalytics()` | _(none)_ |\n\nEach plugin also accepts an optional `client` property to inject an SDK instance (useful for testing or SSR).\n\n### Script Loaders (React / Next.js)\n\nPlugins that need a `\u003cscript\u003e` tag provide a React component under a `/react` subpath:\n\n```tsx\nimport { GAScript } from \"@alyt/plugin-ga/react\";\nimport { VercelAnalytics } from \"@alyt/plugin-vercel/react\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    \u003chtml\u003e\n      \u003cbody\u003e\n        \u003cGAScript measurementId=\"G-XXXXXXXXXX\" /\u003e\n        \u003cVercelAnalytics /\u003e\n        {children}\n      \u003c/body\u003e\n    \u003c/html\u003e\n  );\n}\n```\n\n| Package | Component | Props |\n| --- | --- | --- |\n| `@alyt/plugin-ga/react` | `GAScript` | `measurementId?: string` (falls back to `NEXT_PUBLIC_GA_MEASUREMENT_ID`) |\n| `@alyt/plugin-posthog/react` | `PostHogScript` | `apiKey: string`, `apiHost?: string` |\n| `@alyt/plugin-mixpanel/react` | `MixpanelScript` | `token: string` |\n| `@alyt/plugin-amplitude/react` | `AmplitudeScript` | `apiKey: string` |\n| `@alyt/plugin-plausible/react` | `PlausibleScript` | `domain: string`, `apiHost?: string` |\n| `@alyt/plugin-vercel/react` | `VercelAnalytics` | _(re-export of `@vercel/analytics/react`)_ |\n\n## React\n\nWrap your app with `AnalyticsProvider` and use the `useAnalytics` hook in any component:\n\n```tsx\nimport { createAnalytics } from \"@alyt/core\";\nimport { AnalyticsProvider, useAnalytics } from \"@alyt/react\";\nimport { googleAnalytics } from \"@alyt/plugin-ga\";\n\nconst client = createAnalytics({\n  plugins: [googleAnalytics({ measurementId: \"G-XXXXXXXXXX\" })],\n});\n\n// In your root layout\nfunction App() {\n  return (\n    \u003cAnalyticsProvider client={client}\u003e\n      \u003cDashboard /\u003e\n    \u003c/AnalyticsProvider\u003e\n  );\n}\n\n// In any component\nfunction Dashboard() {\n  const analytics = useAnalytics();\n\n  return (\n    \u003cbutton onClick={() =\u003e analytics.track(\"dashboard_clicked\")}\u003e\n      Go to Dashboard\n    \u003c/button\u003e\n  );\n}\n```\n\n`useAnalytics()` throws if used outside an `\u003cAnalyticsProvider\u003e`.\n\n## Codegen\n\nDefine your events in a YAML schema and generate a fully typed tracker.\n\n### 1. Define your schema\n\n```yaml\n# analytics.schema.yaml\nevents:\n  page_viewed:\n    description: Fired when a user views a page\n    params:\n      page_name: string\n  button_clicked:\n    description: Fired when a user clicks a button\n    params:\n      button_id: string\n      label: string\n  user_signed_up:\n    description: Fired when a new user completes registration\n```\n\nEvents with no parameters can omit `params`. The optional `description` field generates JSDoc comments in the output.\n\nParameters support a short form (`name: type`) and a full form for metadata:\n\n```yaml\nevents:\n  magic_link_requested:\n    params:\n      email:\n        type: string\n        hash: true\n```\n\n`hash: true` is only valid for `type: string`. The generated tracker method still accepts the raw string argument, but emits the same parameter key with the exact input string replaced by a lowercase SHA-256 hex digest from `globalThis.crypto.subtle`. Alyt does not trim, lowercase, salt, or rename hashed values. Generated methods with hashed params are `async`; generated methods without hashed params remain synchronous.\n\n### 2. Run the CLI\n\n```bash\nnpx alyt-codegen --schema analytics.schema.yaml --out lib/analytics\n```\n\n### 3. Use the generated tracker\n\nThe CLI generates two files:\n\n**`types.ts`** -- Event name union and parameter map:\n\n```typescript\nexport type AnalyticsEventName =\n  | \"page_viewed\"\n  | \"button_clicked\"\n  | \"user_signed_up\";\n\nexport interface AnalyticsEventMap {\n  /** Fired when a user views a page */\n  page_viewed: { page_name: string };\n  /** Fired when a user clicks a button */\n  button_clicked: { button_id: string; label: string };\n  /** Fired when a new user completes registration */\n  user_signed_up: Record\u003cstring, never\u003e;\n}\n```\n\n**`tracker.ts`** -- Typed methods that call `client.track()`:\n\n```typescript\nimport type { AnalyticsClient, TrackOptions } from \"@alyt/core\";\n\nexport function createTracker(client: AnalyticsClient) {\n  return {\n    /** Fired when a user views a page */\n    pageViewed(pageName: string, options?: TrackOptions) {\n      client.track(\"page_viewed\", { page_name: pageName }, options);\n    },\n    /** Fired when a user clicks a button */\n    buttonClicked(buttonId: string, label: string, options?: TrackOptions) {\n      client.track(\"button_clicked\", { button_id: buttonId, label: label }, options);\n    },\n    /** Fired when a new user completes registration */\n    userSignedUp(options?: TrackOptions) {\n      client.track(\"user_signed_up\", undefined, options);\n    },\n  };\n}\n```\n\nParameter names are converted from `snake_case` (YAML) to `camelCase` (TypeScript). Descriptions become JSDoc comments on both the type map and the tracker methods.\n\n## Selective Tracking\n\nSend an event to specific plugins only using `TrackOptions.only`:\n\n```typescript\n// Only send to Google Analytics, skip PostHog\nanalytics.track(\"internal_metric\", { value: 42 }, { only: [\"google-analytics\"] });\n```\n\nPlugin names are the `name` property returned by each factory:\n\n| Factory | Plugin Name |\n| --- | --- |\n| `googleAnalytics()` | `\"google-analytics\"` |\n| `posthog()` | `\"posthog\"` |\n| `mixpanel()` | `\"mixpanel\"` |\n| `amplitude()` | `\"amplitude\"` |\n| `plausible()` | `\"plausible\"` |\n| `vercelAnalytics()` | `\"vercel\"` |\n\nThe generated tracker also accepts `TrackOptions` as the last argument on every method.\n\n## Custom Client\n\nEvery plugin accepts a `client` option to pass your own SDK instance. This is useful when you've already initialized the SDK elsewhere, or for testing:\n\n```typescript\nimport { googleAnalytics } from \"@alyt/plugin-ga\";\n\n// Use your own gtag instance\nconst plugin = googleAnalytics({\n  measurementId: \"G-XXXXXXXXXX\",\n  client: myCustomGtag,\n});\n```\n\n## Dynamic Plugins\n\nAdd or remove plugins at runtime -- useful for cookie consent flows:\n\n```typescript\nimport { createAnalytics } from \"@alyt/core\";\nimport { googleAnalytics } from \"@alyt/plugin-ga\";\nimport { posthog } from \"@alyt/plugin-posthog\";\n\nconst analytics = createAnalytics(); // start with no plugins\n\n// User accepts analytics cookies\nanalytics.addPlugin(googleAnalytics({ measurementId: \"G-XXXXXXXXXX\" }));\nanalytics.addPlugin(posthog({ apiKey: \"phc_XXXXXXXXXX\" }));\n\n// User revokes consent\nanalytics.removePlugin(\"google-analytics\");\nanalytics.removePlugin(\"posthog\");\n```\n\nEvents tracked before any plugins are added are silently dropped.\n\n## Custom Plugins\n\nImplement the `AnalyticsPlugin` interface to write your own:\n\n```typescript\nimport type { AnalyticsPlugin } from \"@alyt/core\";\n\nexport function consoleAnalytics(): AnalyticsPlugin {\n  return {\n    name: \"console\",\n    track(event, params) {\n      console.log(\"[track]\", event, params);\n    },\n    identify(userId, traits) {\n      console.log(\"[identify]\", userId, traits);\n    },\n    page(name, params) {\n      console.log(\"[page]\", name, params);\n    },\n    reset() {\n      console.log(\"[reset]\");\n    },\n  };\n}\n```\n\nOnly `name` and `track` are required. The `identify`, `page`, and `reset` methods are optional.\n\n## Packages\n\n| Package | Description |\n| --- | --- |\n| [`@alyt/core`](packages/core) | `createAnalytics` client and plugin interface |\n| [`@alyt/react`](packages/react) | `AnalyticsProvider` and `useAnalytics` hook |\n| [`@alyt/codegen`](packages/codegen) | YAML-to-TypeScript event codegen CLI |\n| [`@alyt/plugin-ga`](packages/plugin-ga) | Google Analytics (gtag.js) |\n| [`@alyt/plugin-posthog`](packages/plugin-posthog) | PostHog |\n| [`@alyt/plugin-mixpanel`](packages/plugin-mixpanel) | Mixpanel |\n| [`@alyt/plugin-amplitude`](packages/plugin-amplitude) | Amplitude |\n| [`@alyt/plugin-plausible`](packages/plugin-plausible) | Plausible Analytics |\n| [`@alyt/plugin-vercel`](packages/plugin-vercel) | Vercel Analytics |\n\n## License\n\nApache-2.0\n\n\u003e This project is free and open-source work by a 501(c)(3) non-profit. If you find it useful, please consider [donating](https://github.com/sponsors/mathematic-inc).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathematic-inc%2Falyt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathematic-inc%2Falyt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathematic-inc%2Falyt/lists"}