The satsu-analytics package

satsu-analytics is the MIT-licensed npm package that installs Satsu in your code: a component per framework, a typed track() for custom events, and the CLI that sets it all up. Sessions are derived from a daily-rotating fingerprint that cannot be linked across days; raw IP addresses and user agents are never written to the analytics database and pass through our message queue only until they are processed, at most 24 hours; no cookies, no persistent visitor IDs.

npm install satsu-analytics

Or let init do it. Per-framework walkthroughs start at Install the tracker.

Components

Each component loads the tracker once, follows client-side navigation and renders nothing. Props: site (the site ID) and debug (log instead of loading the tracker).

FrameworkImportGuide
Next.jsimport { Satsu } from "satsu-analytics/next"Next.js
React (Vite)import { Satsu } from "satsu-analytics/react"React
Vue 3import { Satsu } from "satsu-analytics/vue"Vue and Nuxt
Nuxtmodules: ["satsu-analytics/nuxt"]Vue and Nuxt
Astroimport Satsu from "satsu-analytics/astro"Astro
SvelteKitimport Satsu from "satsu-analytics/svelte"SvelteKit
Remix / React Routerimport { Satsu } from "satsu-analytics/remix"Remix

Environment variables

When you don't pass site, the component reads the site ID from the variable of your framework:

FrameworkVariableFile
Next.jsNEXT_PUBLIC_SATSU_SITE.env.local
React (Vite), Vue (Vite)VITE_SATSU_SITE.env.local
Remix / React RouterVITE_SATSU_SITE.env
NuxtNUXT_PUBLIC_SATSU_SITE.env
Astro, SvelteKitPUBLIC_SATSU_SITE.env

The ID is public (it ends up in the page HTML). Using one variable per environment lets staging and production report to different sites without code changes.

On localhost the tracker is not loaded. The component sends one dev ping per page load so init can confirm the setup. It carries only the site ID and the local origin and path, and is never written to the analytics database, counted, billed or shown in your stats.

track

track(name, props?) sends a custom event. It queues until the tracker has loaded and is a no-op on the server. On localhost and with debug it only logs to the console.

ts
import { track } from "satsu-analytics";
 
track("signup", { plan: "pro" });

Props are flat: strings, numbers and booleans.

Typed events

Declare your event names once and track only accepts those, with the props you declared:

ts
// satsu-events.d.ts
import "satsu-analytics";
 
declare module "satsu-analytics" {
  interface Events {
    signup: { plan: string };
    newsletter: undefined;
  }
}
ts
track("signup", { plan: "pro" }); // ok
track("signup"); // type error: props missing
track("singup", { plan: "pro" }); // type error: unknown event

Don't want to write it by hand? satsu-analytics types generates the file from your goals.

  • CLI: init, login, logout, types.
  • MCP server: ask your coding agent about your traffic.