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

@sygnl/identity-manager

v1.0.3

Published

Lightweight identity and session management with cookie + localStorage fallback

Readme

@sygnl/identity-manager

Lightweight identity and session management with cookie + localStorage fallback

npm version License

Features

  • 🎯 Zero Dependencies - Fully self-contained
  • 🔒 Privacy-First - Anonymous user identification without PII
  • 💾 Dual Storage - Cookie + localStorage fallback for maximum persistence
  • 🌐 SSR-Safe - Works in both browser and Node.js environments
  • ⚙️ Fully Configurable - Customize every aspect of cookie/storage behavior
  • 🧪 Well Tested - Comprehensive test suite with >90% coverage
  • 📦 TypeScript Native - Full type definitions included
  • 🚀 Tiny Bundle - ~2KB minified + gzipped

Installation

npm install @sygnl/identity-manager
yarn add @sygnl/identity-manager
pnpm add @sygnl/identity-manager

Quick Start

import { IdentityManager } from '@sygnl/identity-manager';

// Create instance with default settings
const identity = new IdentityManager();

// Get or create anonymous user ID (365-day persistence)
const userId = identity.ensureAnonymousId();
// → "a3f2b8c9-4d5e-4f6a-8b9c-1d2e3f4a5b6c"

// Get or create session ID (1-day persistence)
const sessionId = identity.ensureSessionId();
// → "sess_1704067200000"

Use Cases

Analytics & Tracking

Track user behavior across sessions without requiring login:

const identity = new IdentityManager();

// Track page view with persistent user ID
analytics.track('page_view', {
  userId: identity.ensureAnonymousId(),
  sessionId: identity.ensureSessionId(),
  page: window.location.pathname,
});

A/B Testing

Consistently assign users to experiment groups:

const identity = new IdentityManager();
const userId = identity.ensureAnonymousId();

// User always gets same variant across sessions
const variant = hashUserId(userId) % 2 === 0 ? 'A' : 'B';

Shopping Cart Persistence

Associate cart with anonymous user before login:

const identity = new IdentityManager();

async function addToCart(productId: string) {
  await fetch('/api/cart', {
    method: 'POST',
    body: JSON.stringify({
      anonymousId: identity.ensureAnonymousId(),
      productId,
    }),
  });
}

Form Progress Tracking

Resume incomplete forms across sessions:

const identity = new IdentityManager();
const formKey = `form_${identity.ensureAnonymousId()}`;

// Save progress
localStorage.setItem(formKey, JSON.stringify(formData));

// Resume later
const savedData = localStorage.getItem(formKey);

API Reference

Constructor

new IdentityManager(options?: PartialIdentityManagerOptions)

Creates a new IdentityManager instance with optional configuration.

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | anonymousIdCookieName | string | '_stid' | Cookie name for anonymous ID | | sessionIdCookieName | string | '_session_id' | Cookie name for session ID | | anonymousIdTTL | number | 365 | Anonymous ID TTL in days | | sessionIdTTL | number | 1 | Session ID TTL in days | | cookieDomain | string? | undefined | Cookie domain (e.g., .example.com) | | cookiePath | string | '/' | Cookie path | | cookieSameSite | 'Strict' \| 'Lax' \| 'None' | 'Lax' | Cookie SameSite attribute | | cookieSecure | boolean | true | Cookie Secure flag (requires HTTPS) | | useLocalStorage | boolean | true | Enable localStorage fallback | | debug | boolean | false | Enable debug logging |

Methods

ensureAnonymousId(): string

Gets existing anonymous ID or creates a new one. Always returns a value.

const userId = identity.ensureAnonymousId();
// → "a3f2b8c9-4d5e-4f6a-8b9c-1d2e3f4a5b6c"

Persistence Strategy:

  1. Check cookie
  2. Check localStorage (if enabled)
  3. Generate new UUID v4
  4. Save to both cookie and localStorage

getAnonymousId(): string | null

Gets existing anonymous ID without creating a new one.

const userId = identity.getAnonymousId();
// → "a3f2b8c9-..." or null

ensureSessionId(): string

Gets existing session ID or creates a new one. Always returns a value.

const sessionId = identity.ensureSessionId();
// → "sess_1704067200000"

Format: sess_{timestamp}

getSessionId(): string | null

Gets existing session ID without creating a new one.

const sessionId = identity.getSessionId();
// → "sess_1704067200000" or null

getCookie(name: string): string | null

Low-level cookie getter.

const value = identity.getCookie('my_cookie');

setCookie(name: string, value: string, days: number): void

Low-level cookie setter.

identity.setCookie('my_cookie', 'my_value', 30);

configure(options: PartialIdentityManagerOptions): void

Updates configuration at runtime.

identity.configure({
  debug: true,
  anonymousIdTTL: 180,
});

Advanced Usage

Custom Cookie Names

Use custom cookie names to avoid conflicts:

const identity = new IdentityManager({
  anonymousIdCookieName: '_my_user_id',
  sessionIdCookieName: '_my_session',
});

Subdomain Sharing

Share identity across subdomains:

const identity = new IdentityManager({
  cookieDomain: '.example.com', // Shares across *.example.com
});

Extended Anonymous ID Persistence

Keep anonymous ID for longer:

const identity = new IdentityManager({
  anonymousIdTTL: 730, // 2 years
});

Longer Sessions

Extend session duration:

const identity = new IdentityManager({
  sessionIdTTL: 7, // 1 week
});

Debug Mode

Enable logging for troubleshooting:

const identity = new IdentityManager({
  debug: true,
});

// Logs to console:
// [IdentityManager] ensureAnonymousId: generated new ID { anonymousId: "..." }
// [IdentityManager] setCookie: success { name: "_stid", value: "...", ... }

Disable localStorage Fallback

Use cookies only:

const identity = new IdentityManager({
  useLocalStorage: false,
});

SameSite Configuration

For cross-site tracking (requires Secure):

const identity = new IdentityManager({
  cookieSameSite: 'None',
  cookieSecure: true, // Required for SameSite=None
});

SSR/Node.js Usage

The library is SSR-safe and won't throw in Node.js:

// Server-side rendering
const identity = new IdentityManager();
const userId = identity.ensureAnonymousId(); // Returns null in SSR

Edge Cases Handled

✅ Cookie Blocking

When cookies are blocked by browser settings:

  • Falls back to localStorage
  • Gracefully returns null if both fail
  • No errors thrown

✅ Private Browsing Mode

When localStorage throws errors:

  • Catches and handles silently
  • Falls back to cookies only
  • Continues working

✅ Storage Quota Exceeded

When localStorage is full:

  • Catches quota errors
  • Uses cookie as primary storage
  • No functionality loss

✅ SSR/Node.js Environment

When document/window are undefined:

  • Detects environment
  • Returns null gracefully
  • No errors thrown

✅ Cookie Expiration

When cookies expire but localStorage persists:

  • Automatically restores from localStorage
  • Syncs back to cookie
  • Seamless recovery

Migration Guide

From Custom Implementation

Before:

function getAnonymousId() {
  let id = getCookie('_user_id');
  if (!id) {
    id = generateUUID();
    setCookie('_user_id', id, 365);
  }
  return id;
}

After:

import { IdentityManager } from '@sygnl/identity-manager';

const identity = new IdentityManager({
  anonymousIdCookieName: '_user_id', // Match your existing cookie name
});

const id = identity.ensureAnonymousId();

From pixel.source.js (Sygnl)

This package extracts and enhances these functions from pixel.source.js:

  • getCookie()identity.getCookie()
  • setCookie()identity.setCookie()
  • generateUUID() → Internal (automatic)
  • ensureAnonymousId()identity.ensureAnonymousId()
  • ensureSessionId()identity.ensureSessionId()

Benefits of migration:

  • ✅ TypeScript support
  • ✅ Better error handling
  • ✅ Configurable options
  • ✅ Comprehensive tests
  • ✅ SSR safety
  • ✅ Maintained package

Browser Compatibility

  • ✅ Chrome/Edge 90+
  • ✅ Firefox 88+
  • ✅ Safari 14+
  • ✅ Node.js 18+ (SSR-safe)

UUID Generation:

  • Uses crypto.randomUUID() in modern browsers
  • Falls back to Math.random() for older browsers
  • Both implementations are RFC4122 compliant

Performance

  • Bundle Size: ~2KB minified + gzipped
  • Runtime: <1ms for ID generation
  • Memory: <1KB per instance
  • Zero dependencies

Testing

Run the test suite:

npm test

Run with coverage:

npm run test:coverage

Watch mode for development:

npm run test:watch

Test Coverage:

  • 60+ test cases
  • 90% code coverage

  • Edge cases covered
  • Integration tests included

TypeScript

Full TypeScript support included:

import { 
  IdentityManager,
  IdentityManagerOptions,
  PartialIdentityManagerOptions,
  DEFAULT_OPTIONS
} from '@sygnl/identity-manager';

// Type-safe configuration
const options: PartialIdentityManagerOptions = {
  debug: true,
  anonymousIdTTL: 365,
};

const identity = new IdentityManager(options);

Contributing

Contributions welcome! Please read our Contributing Guide first.

License

Apache-2.0

Copyright 2026 Edge Foundry, Inc.

Support

Related Packages


Made with ❤️ by Sygnl