plausible-tracker

A lightweight, dependency-free TypeScript client for sending custom events and page views to Plausible Analytics.

SDK
npm
v0.3.9
287stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance0
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture70
Code Quality85
Innovation80
Learning Curve60

plausible-tracker is a small TypeScript library for sending page views and custom events to a Plausible Analytics instance directly from application code, as an alternative to loading Plausible’s hosted tracking script. It wraps a single XMLHttpRequest call behind a typed API, exposing trackPageview, trackEvent, enableAutoPageviews, and enableAutoOutboundTracking helpers so single-page apps can drive analytics through JavaScript instead of a <script> tag.

The project has no runtime dependencies, compiles to both CommonJS and ES module builds, and ships full TypeScript typings. The repository is now archived by its maintainers, who point users toward the newer @plausible-analytics/tracker package as its replacement — this package still works and remains widely used in existing projects, but no further changes are expected.

What You Get

  • Typed trackEvent/trackPageview functions for sending analytics events directly from app code
  • An enableAutoPageviews helper that patches history.pushState and listens for popstate/hashchange to auto-track SPA navigation
  • An enableAutoOutboundTracking helper using a MutationObserver to detect and track clicks on outbound links, including dynamically added ones
  • Zero runtime dependencies and a sub-1kb bundle, with both CommonJS and ES module builds plus bundled .d.ts typings
  • Support for self-hosted Plausible instances via a configurable apiHost option

Common Use Cases

  • Tracking page views and route changes in single-page apps (React/Vue/Svelte) where the default Plausible script tag can’t observe client-side navigation
  • Recording custom conversion goals such as signups or downloads with attached properties
  • Tracking outbound link clicks (e.g. to a docs site or app store) without manually wiring click handlers
  • Sending analytics to a self-hosted Plausible deployment by overriding apiHost

Under The Hood

Architecture The library is two small modules re-exported from a single entry point: src/lib/tracker.ts holds the Plausible() factory and the two auto-tracking helpers, while src/lib/request.ts owns payload construction and the sole network call (sendEvent, via XMLHttpRequest). State lives in closures rather than a singleton — calling Plausible() returns four bound functions sharing a captured config object — and the only global mutation is patching window.plausible and (when auto-pageviews is enabled) history.pushState. Both auto-tracking helpers call back into the trackEvent/trackPageview functions produced by the same factory, so the whole surface would need to move together if the core factory’s shape changed. This is intentionally minimal rather than layered — there is no internal DI, routing, or state store to speak of.

Tech Stack Written in TypeScript and compiled twice — once via tsconfig.json for CommonJS and once via tsconfig.module.json for ES modules — so the published package works with both require and import consumers. It has zero runtime dependencies; everything in package.json (Jest/ts-jest, ESLint plus eslint-plugin-functional, Prettier, cspell, Typedoc, standard-version, nyc) is a devDependency for testing, linting, docs generation, and release tooling. It targets the browser directly with XMLHttpRequest, MutationObserver, history, and location rather than going through fetch or a bundler-specific runtime.

Code Quality Both modules have matching .spec.ts test files that mock XMLHttpRequest and browser globals (history, location, localStorage) via jest.spyOn, covering default/overridden config merging, the plausible_ignore opt-out, and callback firing. CI (.github/workflows/node.yml) runs the suite across multiple Node versions with coverage uploaded to Codecov. ESLint extends eslint:recommended and @typescript-eslint/recommended plus eslint-plugin-functional for immutability discipline, with narrowly-scoped eslint-disable comments where mutation is unavoidable (e.g. patching window.plausible). Every exported type carries JSDoc. Overall a well-tested, linted, typed codebase for its size.

API Design A single default-exported factory, Plausible(options), returns four named functions instead of requiring a class instance or lifecycle object, and both auto-tracking helpers return their own cleanup() closures rather than a separate teardown API. Defaults are sensible (domain/URL/referrer pulled from location/document), so a working setup is one line: Plausible().enableAutoPageviews(). The README documents every exported function with runnable examples, and editor tooltips surface the JSDoc directly. The approach isn’t conceptually novel — it sends the same request Plausible’s own script tag does — but the ergonomics are unusually polished for a package this size.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search