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

@arlioz/flagship

v3.0.0

Published

Official JavaScript/TypeScript SDK for FlagShip — feature flags for startups

Readme


Why FlagShip?

  • Zero dependencies — works in Node.js, browsers, edge runtimes, and serverless
  • Tiny footprint — under 2 KB minified + gzipped
  • TypeScript-first — full type safety out of the box
  • Real-time sync — built-in polling keeps flags up to date
  • Targeting & rollouts — percentage-based rollouts with user attribute conditions
  • Open source — self-host or use our managed platform

Quick Start

1. Install

npm install @arlioz/flagship
# or with your preferred package manager
yarn add @arlioz/flagship
pnpm add @arlioz/flagship

2. Initialize

import { FlagShip } from "@arlioz/flagship"

const client = new FlagShip({
  apiKey: "flg_production_your_key_here",
})

3. Use flags

const showNewUI = await client.get("new_ui")

if (showNewUI) {
  renderNewDashboard()
} else {
  renderLegacyDashboard()
}

That's it. You're shipping with feature flags. 🚀

Usage

Basic flag evaluation

// Boolean flag (most common)
const isEnabled = await client.get("dark_mode")

// With a fallback value
const limit = await client.get("upload_limit", 10)

// String flag
const theme = await client.get("theme", "light")

Fetch all flags at once

const flags = await client.fetchFlags()

console.log(flags)
// → { dark_mode: true, upload_limit: 50, theme: "dark" }

Get all cached flags (synchronous)

// After an initial fetch, read from cache without awaiting
const allFlags = client.getAll()

User targeting

const client = new FlagShip({
  apiKey: "flg_production_abc123",
  userId: "user-42",
  attributes: {
    plan: "pro",
    country: "FR",
    role: "admin",
  },
})

// Flags are evaluated server-side with targeting rules
const canAccessBeta = await client.get("beta_features")

Update user context

// When a user logs in or their context changes
client.identify("user-789", {
  plan: "enterprise",
  country: "DE",
})

// Cache is cleared — next .get() will re-fetch with new context
const flags = await client.get("premium_feature")

Auto-polling

const client = new FlagShip({
  apiKey: "flg_production_abc123",
  pollingInterval: 15000, // poll every 15 seconds
})

// Flags stay up to date automatically.
// When you toggle a flag in the dashboard,
// it takes effect within one polling cycle.

Clean up

// Stop polling when the app shuts down
client.close()

API Reference

new FlagShip(options)

Creates a new FlagShip client instance.

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | apiKey | string | Yes | — | Environment API key from your dashboard (e.g. flg_production_...) | | baseUrl | string | No | http://localhost:4000/api | Base URL of your FlagShip API | | userId | string | No | — | User ID for percentage-based rollouts | | attributes | Record<string, any> | No | {} | User attributes for targeting conditions | | pollingInterval | number | No | 30000 | Polling interval in ms. Set 0 to disable |

client.get<T>(key, defaultValue?): Promise<T>

Get a single flag value by key. Returns the defaultValue if the flag doesn't exist.

const isEnabled = await client.get("feature_x")          // boolean
const limit = await client.get("rate_limit", 100)         // number
const variant = await client.get("cta_text", "Sign Up")   // string

client.fetchFlags(): Promise<Record<string, any>>

Fetch all flags from the server and update the local cache. Returns the full flag map.

client.getAll(): Record<string, any>

Returns all cached flag values synchronously. Useful after an initial fetchFlags() call.

client.identify(userId, attributes?): void

Update the user context for subsequent evaluations. Clears the cache so the next read triggers a fresh fetch.

client.close(): void

Stop the polling timer and clean up resources. Call this when your app shuts down.

Framework Examples

Next.js (App Router)

// lib/flags.ts
import { FlagShip } from "@arlioz/flagship"

export const flagClient = new FlagShip({
  apiKey: process.env.FLAGSHIP_API_KEY!,
  baseUrl: "https://flagship-pwxs.onrender.com/api",
  pollingInterval: 0, // disable polling in server context
})
// app/page.tsx
import { flagClient } from "@/lib/flags"

export default async function HomePage() {
  const showBanner = await flagClient.get("promo_banner")

  return (
    <main>
      {showBanner && <PromoBanner />}
      <HeroSection />
    </main>
  )
}

Express / Node.js

import express from "express"
import { FlagShip } from "@arlioz/flagship"

const app = express()
const flags = new FlagShip({
  apiKey: "flg_production_abc123",
  baseUrl: "https://flagship-pwxs.onrender.com/api",
})

app.get("/api/config", async (req, res) => {
  const userId = req.headers["x-user-id"] as string

  if (userId) {
    flags.identify(userId)
  }

  const showNewCheckout = await flags.get("new_checkout")
  const uploadLimit = await flags.get("upload_limit", 10)

  res.json({ showNewCheckout, uploadLimit })
})

React (Client-side)

import { useEffect, useState } from "react"
import { FlagShip } from "@arlioz/flagship"

const client = new FlagShip({
  apiKey: "flg_production_abc123",
  baseUrl: "https://flagship-pwxs.onrender.com/api",
})

function App() {
  const [flags, setFlags] = useState<Record<string, any>>({})

  useEffect(() => {
    client.fetchFlags().then(setFlags)
    return () => client.close()
  }, [])

  return (
    <div>
      {flags.chat_widget && <ChatWidget />}
      {flags.dark_mode ? <DarkTheme /> : <LightTheme />}
    </div>
  )
}

How It Works

┌─────────────┐     GET /flags/evaluate      ┌──────────────┐
│  Your App    │ ──────────────────────────▶  │  FlagShip   │
│              │     ?environment_key=...      │  API Server  │
│  @arlioz/    │ ◀──────────────────────────  │              │
│  flagship    │     { dark_mode: true, ... }  │  PostgreSQL  │
└─────────────┘                               └──────────────┘
       │                                             ▲
       │  polls every 30s                            │
       └─────────────────────────────────────────────┘
  1. Your app initializes the SDK with an environment API key
  2. The SDK calls the evaluate endpoint with the key + user context
  3. The server evaluates targeting rules and returns resolved flag values
  4. The SDK caches results and polls for updates automatically

MIT — Arlioz