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

@emitkit/js

v2.1.0

Published

Official TypeScript/JavaScript SDK for EmitKit API

Readme

@emitkit/js

Official TypeScript/JavaScript SDK for EmitKit API

npm version Bundle Size License: MIT

📦 Installation

npm install @emitkit/js
# or
pnpm add @emitkit/js
# or
yarn add @emitkit/js

🚀 Quick Start

import { EmitKit } from '@emitkit/js';

// Initialize the client
const client = new EmitKit('emitkit_xxxxxxxxxxxxxxxxxxxxx');

// Create an event
const result = await client.events.create({
  channelName: 'payments',
  title: 'Payment Received',
  description: 'User upgraded to Pro plan',
  icon: '💰',
  metadata: {
    amount: 99.99,
    currency: 'USD',
    plan: 'pro'
  }
});

console.log('Event created:', result.data.id);
console.log('Rate limit:', result.rateLimit);

📚 Features

  • Type-Safe: Full TypeScript support with auto-generated types
  • User Identity: Track users with custom properties and multiple aliases
  • Alias Resolution: Reference users by email, username, or any identifier
  • Rate Limiting: Automatic rate limit tracking and handling
  • Idempotency: Built-in idempotency key support for safe retries
  • Error Handling: Type-safe error classes (ValidationError, RateLimitError)
  • Zero Dependencies: No external runtime dependencies
  • Tree-Shakeable: Optimized bundle size with ES modules
  • Request IDs: Automatic request ID tracking for debugging

🎯 Usage

Basic Event Creation

const result = await client.events.create({
  channelName: 'general',
  title: 'Test Event',
  description: 'This is a test event',
  icon: '📝'
});

With Metadata

await client.events.create({
  channelName: 'user-signups',
  title: 'New User Registered',
  tags: ['signup', 'onboarding'],
  metadata: {
    email: '[email protected]',
    plan: 'free',
    source: 'organic'
  },
  userId: 'user_123',
  notify: true,
  displayAs: 'notification'
});

User Identity

Identify users with custom properties and aliases:

// Identify a user with properties
const result = await client.identify({
  user_id: 'user_123',
  properties: {
    email: '[email protected]',
    name: 'John Doe',
    plan: 'pro',
    signupDate: '2025-01-15'
  }
});

console.log('Identity ID:', result.data.id);
console.log('User ID:', result.data.userId);

User Aliases

Create aliases to reference users by multiple identifiers:

// Identify user with aliases
await client.identify({
  user_id: 'user_123',
  properties: {
    email: '[email protected]',
    name: 'John Doe'
  },
  aliases: [
    '[email protected]',      // Email
    'johndoe',                // Username
    '[email protected]',   // Work email
    'ext_12345'               // External system ID
  ]
});

// Use aliases in events - they're automatically resolved!
await client.events.create({
  channelName: 'user-activity',
  title: 'User Logged In',
  userId: '[email protected]',  // ← Alias works here!
  metadata: { ip: '192.168.1.1' }
});

Update User Properties

Properties are replaced on each identify call:

// Initial identify
await client.identify({
  user_id: 'user_123',
  properties: {
    email: '[email protected]',
    plan: 'free'
  }
});

// Update to pro plan (overwrites all properties)
await client.identify({
  user_id: 'user_123',
  properties: {
    email: '[email protected]',
    plan: 'pro',
    upgradeDate: '2025-01-20'
  }
});

Idempotency

Safe retries for webhooks and payment processing:

const result = await client.events.create(
  {
    channelName: 'payments',
    title: 'Payment Received',
    metadata: { paymentId: 'pay_123' }
  },
  { idempotencyKey: 'payment-pay_123-webhook' }
);

// Subsequent requests with the same key return cached response
console.log('Was replayed:', result.wasReplayed);

Rate Limit Tracking

const result = await client.events.create({...});

// Check rate limit status
console.log(result.rateLimit);
// {
//   limit: 100,
//   remaining: 95,
//   reset: 1733270400,
//   resetIn: 45000
// }

// Access last known rate limit
console.log(client.rateLimit);

Error Handling

import {
  EmitKit,
  EmitKitError,
  RateLimitError,
  ValidationError
} from '@emitkit/js';

try {
  await client.events.create({...});
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log('Rate limit exceeded!');
    console.log(`Retry in ${error.rateLimit.resetIn}ms`);
  } else if (error instanceof ValidationError) {
    console.log('Validation failed:');
    error.validationErrors.forEach(err => {
      console.log(`- ${err.path.join('.')}: ${err.message}`);
    });
  } else if (error instanceof EmitKitError) {
    console.log(`API Error ${error.statusCode}:`, error.message);
    console.log('Request ID:', error.requestId);
  }
}

⚙️ Configuration

const client = new EmitKit('emitkit_xxxxxxxxxxxxxxxxxxxxx', {
  // Custom base URL (default: 'https://api.emitkit.com')
  baseUrl: 'https://api.your-domain.com',

  // Request timeout in milliseconds (default: 30000)
  timeout: 60000,

  // Custom fetch implementation
  fetch: customFetch
});

📖 API Reference

EmitKit

Main client class for interacting with the EmitKit API.

Constructor

new EmitKit(apiKey: string, config?: Partial<EmitKitConfig>)

Properties

  • rateLimit: Get the last known rate limit information

Methods

events.create(data, options?)

Create a new event.

Parameters:

  • data: Event data object

    • channelName (string, required): Channel name (auto-creates if doesn't exist)
    • title (string, required): Event title
    • description (string, optional): Event description
    • icon (string, optional): Single emoji icon
    • tags (string[], optional): Array of tags
    • metadata (object, optional): Custom JSON metadata
    • userId (string | null, optional): User identifier
    • notify (boolean, optional): Send notification (default: true)
    • displayAs ('message' | 'notification', optional): Display style
    • source (string, optional): Source identifier
  • options (optional):

    • idempotencyKey (string): Idempotency key for safe retries
    • timeout (number): Request timeout override
    • headers (object): Additional headers

Returns: Promise<EmitKitResponse>

identify(data, options?)

Identify a user with custom properties and aliases.

Parameters:

  • data: Identity data object

    • user_id (string, required): Your internal user ID
    • properties (object, optional): Custom user properties (email, name, plan, etc.)
    • aliases (string[], optional): Alternative identifiers (email, username, external IDs)
  • options (optional):

    • timeout (number): Request timeout override
    • headers (object): Additional headers

Returns: Promise<EmitKitResponse<IdentifyUserResponse>>

Response:

{
  data: {
    id: string;              // Identity record ID
    userId: string;          // User ID
    properties: object;      // Stored properties
    aliases: {
      created: string[];     // Successfully created aliases
      failed?: Array<{       // Failed aliases (if any)
        alias: string;
        reason: string;
      }>;
    };
    updatedAt: string;       // ISO 8601 timestamp
  };
  rateLimit: RateLimitInfo;
  requestId: string;
  wasReplayed: boolean;
}

Types

EmitKitResponse<T>

{
  data: T;                    // Response data
  rateLimit: RateLimitInfo;   // Rate limit info
  requestId: string;          // Request ID for debugging
  wasReplayed: boolean;       // Idempotent replay flag
}

RateLimitInfo

{
  limit: number;      // Max requests allowed
  remaining: number;  // Remaining requests
  reset: number;      // Unix timestamp when limit resets
  resetIn: number;    // Milliseconds until reset
}

Error Classes

EmitKitError

Base error class for all SDK errors.

Properties:

  • message: Error message
  • statusCode: HTTP status code
  • requestId: Request ID for debugging
  • details: Additional error details

RateLimitError

Thrown when rate limit is exceeded (HTTP 429).

Properties:

  • All EmitKitError properties
  • rateLimit: Rate limit information

ValidationError

Thrown when request validation fails (HTTP 400).

Properties:

  • All EmitKitError properties
  • validationErrors: Array of validation error details

🧪 Testing

# Run tests
pnpm test

# Watch mode
pnpm test:watch

# Coverage
pnpm test --coverage

📝 Examples

See the examples directory for more usage examples:

🤝 Contributing

Contributions are welcome! Please read our Contributing Guide.

📄 License

MIT License - see LICENSE for details

🔗 Links


Note: This SDK is automatically generated from the OpenAPI specification.