npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mytart

v0.3.0

Published

Multi-Yield Tracking & Analytics Relay Tool — framework-agnostic analytics for any project

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 import and require
  • 🪶 Lightweight: direct HTTP via axios, no SDK overhead
  • Node.js ≥ 18

Installation

npm install mytart
# or
pnpm add mytart
# or
yarn add mytart

Quick 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(), or page() call
  • All calls use the standard gtag() API — compatible with Google Tag Tester and Tag Assistant
  • SSR-safe: silently succeeds when window is undefined (e.g. during server-side rendering)
  • apiSecret is 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