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

@tanmaybajpai/flagship-js-sdk

v1.0.0

Published

Official JavaScript SDK for FlagShip — evaluate feature flags locally with zero latency.

Downloads

185

Readme

@tanmaybajpai/flagship-js-sdk

Official JavaScript SDK for FlagShip — a self-hosted feature flag platform.

Flags are fetched from your FlagShip server once on startup and cached locally. All evaluation happens in-process with zero network latency, using the same deterministic bucketing algorithm as the server.

Installation

npm install @tanmaybajpai/flagship-js-sdk

Quick Start

import FlagShip from '@tanmaybajpai/flagship-js-sdk';

const flagship = new FlagShip({
  apiKey: 'your-api-key',               // from the FlagShip dashboard
  baseUrl: 'https://your-server.com',   // your FlagShip server URL
  pollInterval: 30000                   // re-fetch config every 30s (optional)
});

await flagship.init();

const enabled = await flagship.evaluate('dark-mode', 'user-123', {
  country: 'US',
  plan: 'pro'
});

if (enabled) {
  // show the new feature
}

// record a conversion event
await flagship.trackSuccess('user-123');

// clean up when shutting down
flagship.destroy();

API

new FlagShip(options)

| Option | Type | Required | Default | Description | |---|---|---|---|---| | apiKey | string | Yes | — | API key from your FlagShip dashboard | | baseUrl | string | Yes | — | Base URL of your FlagShip server (no trailing slash) | | pollInterval | number | No | 30000 | Milliseconds between background config re-fetches |


flagship.init()Promise<void>

Fetches flag configuration from the server and starts the background polling loop. Must be called once before evaluating any flags.

await flagship.init();

flagship.evaluate(flagName, userId, userAttributes?)Promise<boolean>

Evaluates a flag for a given user entirely in-process. Returns false if the flag does not exist, is disabled, the user fails a targeting rule, or falls outside the rollout percentage.

const enabled = await flagship.evaluate('checkout-v2', 'user-456', {
  plan: 'pro',
  country: 'US'
});

| Parameter | Type | Description | |---|---|---| | flagName | string | The flag's name as shown in the dashboard | | userId | string | A stable identifier for the user (e.g. database ID) | | userAttributes | object | Key-value string pairs matched against targeting rules |


flagship.trackSuccess(userId)Promise<void>

Records a conversion event for a user. The server increments flagConversions or controlConversions on every flag owned by the account, based on which bucket the user falls into. This powers the lift analytics shown in the dashboard.

Call this at a meaningful conversion point — for example when a user completes a purchase, signs up, or activates a core feature.

await flagship.trackSuccess('user-456');

flagship.getAllFlags()Flag[]

Returns all flag config objects currently held in the local cache. Useful for debugging or building a flag explorer.

const flags = flagship.getAllFlags();
console.log(flags.map(f => f.flagName));

flagship.refresh()Promise<void>

Manually re-fetches flag configuration from the server. The polling loop calls this automatically on the configured interval, but you can trigger it on demand if needed.


flagship.destroy()

Clears the background polling interval. Call this when shutting down your application or in test teardowns.

process.on('SIGTERM', () => flagship.destroy());

Targeting Rules

Flags can have targeting rules that restrict which users are eligible for bucketing. A user must satisfy all enabled rules on a flag to be considered for rollout.

Each rule defines an attribute key and a list of allowedValues. The value in the user's attributes for that key must be present in the allowed list.

// This flag has two rules: plan must be 'pro' AND country must be 'US' or 'CA'
const enabled = await flagship.evaluate('new-billing', 'user-789', {
  plan: 'pro',
  country: 'CA'
});

If the user's attributes are missing a key that a rule checks, the user fails that rule and the flag returns false regardless of rollout percentage.


How Bucketing Works

FlagShip uses sticky deterministic bucketing — the same user always lands in the same bucket for a given flag, so evaluation is consistent across calls and deployments.

  1. Build the input string: userId + "|" + flagName + "|" + seed
  2. SHA-256 hash the string
  3. Take the first 8 bytes as an unsigned 64-bit integer
  4. bucket = value % 100
  5. Return bucket < rolloutPercent

The seed is a random value stored per-flag on the server. Resetting a flag's users (via the dashboard) regenerates the seed, reshuffling all bucket assignments without changing the rollout percentage.


Requirements

  • Node.js 18+ or a modern browser with Web Crypto API support
  • ES Modules — this package is published as ESM ("type": "module")

If you need CommonJS compatibility, use a dynamic import:

const { default: FlagShip } = await import('@tanmaybajpai/flagship-js-sdk');

License

MIT