mytart
v0.3.0
Published
Multi-Yield Tracking & Analytics Relay Tool — framework-agnostic analytics for any project
Maintainers
Readme
mytart
Multi-Yield Tracking & Analytics Relay Tool — framework-agnostic analytics for any ESM JavaScript/TypeScript project.
mytart makes direct HTTP calls to analytics provider endpoints via axios — no bloated SDK wrappers, no global state, no lock-in.
Features
- 🔌 6 providers out of the box: Google Analytics 4, Mixpanel, Segment, Amplitude, Plausible, PostHog
- 🌐 Universal: works in Node.js, browsers, and any JS framework (Next.js, Remix, Astro, SvelteKit, etc.)
- 🔷 TypeScript-first: precise typings, object-parameter style for great DX
- 📦 Dual ESM/CJS output: works with
importandrequire - 🪶 Lightweight: direct HTTP via axios, no SDK overhead
- ✅ Node.js ≥ 18
Installation
npm install mytart
# or
pnpm add mytart
# or
yarn add mytartQuick Start
import { Mytart } from 'mytart';
const analytics = new Mytart({
providers: [
{ provider: 'segment', writeKey: 'YOUR_WRITE_KEY' },
{ provider: 'posthog', apiKey: 'phc_YOUR_KEY' },
],
defaultUserId: 'user_123',
});
// Track an event
await analytics.track({ event: 'signup', properties: { plan: 'pro' } });
// Identify a user
await analytics.identify({ userId: 'user_123', traits: { name: 'Alice', email: '[email protected]' } });
// Track a page view
await analytics.page({ url: 'https://example.com/pricing', name: 'Pricing' });Providers
Google Analytics 4
GA4 supports two modes via the appType option:
Server mode (default)
Uses the GA4 Measurement Protocol — direct HTTP calls, no browser APIs. Use this for Node.js, API routes, serverless functions, etc.
{
provider: 'google-analytics',
measurementId: 'G-XXXXXXXXXX',
apiSecret: 'YOUR_SECRET',
enabled: true,
// appType defaults to 'server'
}Browser mode
Injects Google's official gtag.js snippet into the page. Use this for client-side tracking in any framework (React, Vue, Svelte, plain HTML, etc.). No apiSecret needed.
{
provider: 'google-analytics',
measurementId: 'G-XXXXXXXXXX',
appType: 'browser',
enabled: true,
}When appType: 'browser' is set:
- The gtag.js script is loaded once on the first
track(),identify(), orpage()call - All calls use the standard
gtag()API — compatible with Google Tag Tester and Tag Assistant - SSR-safe: silently succeeds when
windowis undefined (e.g. during server-side rendering) apiSecretis not required (and not used)
Mixpanel
{ provider: 'mixpanel', token: 'YOUR_TOKEN', apiUrl?: string }Segment
{ provider: 'segment', writeKey: 'YOUR_WRITE_KEY', apiUrl?: string }Amplitude
{ provider: 'amplitude', apiKey: 'YOUR_API_KEY', apiUrl?: string }Plausible
{ provider: 'plausible', domain: 'example.com', apiUrl?: string, userAgent?: string, xForwardedFor?: string }Note: Plausible does not support
identify()— it returns an error result.
PostHog
{ provider: 'posthog', apiKey: 'phc_YOUR_KEY', apiUrl?: string }API Reference
new Mytart(config: MytartConfig)
interface MytartConfig {
providers: ProviderConfig[];
defaultUserId?: string; // applied to every track/page call if no userId given
defaultAnonymousId?: string; // applied to every track/page call if no anonymousId given
debug?: boolean;
}Every provider config accepts an enabled field. Providers are off by default — you must set enabled: true to activate a provider:
const analytics = new Mytart({
providers: [
{ provider: 'segment', writeKey: 'YOUR_KEY', enabled: true }, // active
{ provider: 'mixpanel', token: 'YOUR_TOKEN' }, // skipped (off by default)
],
});analytics.track(options: TrackOptions): Promise<TrackResult[]>
interface TrackOptions {
event: string;
properties?: Record<string, unknown>;
userId?: string;
anonymousId?: string;
timestamp?: Date;
context?: EventContext;
}analytics.identify(options: IdentifyOptions): Promise<TrackResult[]>
interface IdentifyOptions {
userId: string;
traits?: Record<string, unknown>;
anonymousId?: string;
timestamp?: Date;
}analytics.page(options: PageOptions): Promise<TrackResult[]>
interface PageOptions {
url: string;
name?: string;
referrer?: string;
properties?: Record<string, unknown>;
userId?: string;
anonymousId?: string;
timestamp?: Date;
}analytics.addProvider(config: ProviderConfig): void
Dynamically add a provider at runtime.
analytics.removeProvider(name: string): void
Remove a provider by name.
analytics.getProviders(): string[]
Returns the list of active provider names.
TrackResult
Every method returns Promise<TrackResult[]> — one result per provider:
interface TrackResult {
provider: string;
success: boolean;
statusCode?: number;
error?: MytartError;
}
interface MytartError {
message: string;
code: string;
provider: string;
originalError?: unknown;
}TypeScript
All types are exported:
import type {
MytartConfig, BaseProviderConfig, ProviderConfig, TrackOptions, IdentifyOptions, PageOptions,
TrackResult, MytartError, EventContext, ProviderName, GoogleAnalyticsAppType,
GoogleAnalyticsConfig, MixpanelConfig, SegmentConfig,
AmplitudeConfig, PlausibleConfig, PostHogConfig,
} from 'mytart';Custom Providers
Extend BaseProvider to create your own:
import { BaseProvider, TrackOptions, IdentifyOptions, PageOptions, TrackResult } from 'mytart';
export class MyProvider extends BaseProvider {
readonly name = 'my-provider';
async track(options: TrackOptions): Promise<TrackResult> {
// your HTTP call here
return this.buildSuccess(200);
}
async identify(options: IdentifyOptions): Promise<TrackResult> {
return this.buildSuccess(200);
}
async page(options: PageOptions): Promise<TrackResult> {
return this.buildSuccess(200);
}
}License
MIT
