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

@teracrafts/flagkit

v1.1.0

Published

FlagKit TypeScript SDK for feature flag evaluation

Readme

@teracrafts/flagkit

Official TypeScript SDK for FlagKit - Feature flag management made simple.

Features

  • Zero runtime dependencies - No external packages required
  • Universal - Browser and Node.js support
  • TypeScript-first - Full type safety with comprehensive type definitions
  • Tiny bundle - < 20KB gzipped
  • Resilient - Automatic retry with exponential backoff, circuit breaker
  • Event tracking - Analytics with batching
  • Offline mode - Works without network

Installation

npm install @teracrafts/flagkit
# or
yarn add @teracrafts/flagkit
# or
pnpm add @teracrafts/flagkit

Quick Start

import FlagKit from '@teracrafts/flagkit';

// Initialize the SDK
const client = await FlagKit.initialize({
  apiKey: 'sdk_your_api_key',
  onReady: () => console.log('FlagKit ready!'),
});

// Wait for SDK to be ready
await client.waitForReady();

// Identify user
client.identify('user-123', {
  email: '[email protected]',
  custom: { plan: 'premium' },
});

// Evaluate flags
const darkMode = client.getBooleanValue('dark-mode', false);
const welcomeMsg = client.getStringValue('welcome-message', 'Hello!');
const maxItems = client.getNumberValue('max-items', 10);
const config = client.getJsonValue('feature-config', { enabled: false });

// Track events
client.track('button_clicked', { button: 'signup' });

// Cleanup when done
await client.close();

Configuration

const client = await FlagKit.initialize({
  // Required
  apiKey: 'sdk_your_api_key',

  // Polling
  pollingInterval: 30000,    // Default: 30s
  enablePolling: true,       // Default: true

  // Caching
  cacheEnabled: true,        // Default: true
  cacheTTL: 300000,          // Default: 5 minutes

  // Network
  timeout: 5000,             // Default: 5s
  retries: 3,                // Default: 3

  // Modes
  offline: false,            // Default: false
  debug: false,              // Default: false

  // Bootstrap fallback values
  bootstrap: {
    'dark-mode': false,
    'max-items': 10,
  },

  // Callbacks
  onReady: () => {},
  onError: (error) => {},
  onUpdate: (flags) => {},
});

Developer Tools

FlagKit includes built-in developer tools for inspecting and overriding feature flags during development. The DevTools render inside Shadow DOM for complete style isolation and will never affect your application's layout or CSS.

Quick Start

import { FlagKit, FlagKitDevToolsCore } from '@teracrafts/flagkit';

const client = await FlagKit.initialize({ apiKey: 'sdk_your_key' });

// Mount developer tools (development only)
if (import.meta.env.DEV) {
  const devtools = new FlagKitDevToolsCore(client, {
    theme: 'system',
    buttonPosition: 'bottom-right',
  });
  devtools.mount(document.body);
}

Or use the convenience method:

client.mountDevTools(document.body, { theme: 'dark' });

React Integration

The React SDK provides components and a hook for DevTools:

import { FlagKitDevTools, FlagKitDevToolsLazy, useFlagKitDevTools } from '@teracrafts/flagkit-react';

// Component — auto-mounts/unmounts with lifecycle
function App() {
  const { client } = useFlagKit();
  return (
    <>
      <MyApp />
      {client && <FlagKitDevTools client={client} theme="system" />}
    </>
  );
}

// Lazy-loaded variant — only downloads DevTools code when rendered
function App() {
  const { client } = useFlagKit();
  return (
    <>
      <MyApp />
      {import.meta.env.DEV && client && <FlagKitDevToolsLazy client={client} />}
    </>
  );
}

// Hook — programmatic control
function DevToolsController() {
  const { isOpen, open, close, toggle, overrideCount, devtools } = useFlagKitDevTools({
    theme: 'system',
  });
  return <button onClick={toggle}>DevTools ({overrideCount} overrides)</button>;
}

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | theme | 'light' \| 'dark' \| 'system' | 'system' | Color theme (follows OS preference in system mode) | | buttonPosition | 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' | 'bottom-right' | Initial toggle button position | | panelPosition | 'top' \| 'bottom' \| 'left' \| 'right' | 'right' | Which viewport edge the panel anchors to | | initialSize | number | 420 | Initial panel size in pixels | | minSize | number | 280 | Minimum panel size in pixels | | maxSize | number | 800 | Maximum panel size in pixels | | storagePrefix | string | 'flagkit' | localStorage key prefix | | defaultOpen | boolean | false | Start with panel open | | dashboardUrl | string | — | URL for "View in Dashboard" links | | allowUrlOverrides | boolean | true (dev) / false (prod) | Allow URL-based override sharing | | autoCleanStaleOverrides | boolean | false | Remove overrides for deleted flags on init | | styleNonce | string | — | CSP nonce for injected <style> elements | | shadowDOMTarget | ShadowRoot | — | Use an existing Shadow DOM root instead of creating one | | shortcuts | boolean | true | Enable keyboard shortcuts | | logErrors | boolean | true | Log DevTools internal errors to console |

Panels

DevTools includes six panels, switchable via tabs or number keys 1-6:

Flags Panel

Two-column master/detail layout for inspecting and overriding flags.

  • Search — Filter flags by key name
  • Filter — All, Starred, Boolean, String, Number, JSON, Overridden, Enabled, Disabled
  • Sort — Key A-Z, Key Z-A, Updated, Type
  • Star flags — Pin frequently used flags to the top
  • Quick toggle — Inline boolean switch for fast toggling
  • Override with expiry — Set overrides that auto-expire after a duration
  • Bulk expire — Set all active overrides to expire in 30 minutes
  • Clean stale — Remove overrides for flags no longer in the flag set
  • Flag detail — Full evaluation result, metadata, history, dependencies, and bug report generator

Context Panel

View and modify the evaluation context used for flag targeting.

  • JSON tree viewer — Collapsible view of the current context
  • Edit context — JSON editor with validation
  • Apply as override — Override context without changing the SDK context
  • Set as SDK context — Directly update the SDK's evaluation context
  • Personas — Save, load, and manage named context configurations
  • PII detection — Warns when context contains fields that look like email, phone, SSN, or other sensitive data

Events Panel

Timeline of SDK events with filtering and export.

  • Event types — Flag Evaluated, Flags Changed, Custom, Identify, Override Set/Cleared, SDK Error, Init Complete
  • Filter — By event type or free-text search
  • Pause/Resume — Freeze the timeline while inspecting
  • Expand — Click any event to see its full JSON payload
  • Export — Copy all events to clipboard as JSON
  • Efficient append-only DOM updates with requestAnimationFrame batching

Network Panel

Monitor all HTTP requests made by the SDK.

  • Request list — Method, URL path, status code, duration, response size
  • Status indicators — Green (2xx), yellow (3xx), red (4xx/5xx)
  • Retry tracking — Retried requests show a retry icon and link to the original
  • Request detail — Full URL, method, status, duration, size, timestamp, and error info
  • Copy URL — Copy the full request URL to clipboard

Status Panel

SDK health dashboard showing runtime configuration and state.

  • SDK Info — SDK version, DevTools version, session ID, ready state, streaming status
  • Configuration — Polling interval, cache TTL, timeout, retries, offline mode, debug mode
  • Cache — Flag count, cache enabled/disabled, persistence status, stale/offline badges
  • Security — Strict PII mode, evaluation jitter, error sanitization status

Settings Panel

DevTools preferences and override management.

  • Theme selector — Light, Dark, or System (persisted across sessions)
  • Override presets — Save named sets of overrides and apply them later
  • Import/Export — Copy overrides to clipboard as JSON, or paste to import
  • Clear all — Remove all active overrides at once

Override Engine

The override engine intercepts flag evaluations and returns your override values instead of server values. Overrides are persisted to localStorage and sync across browser tabs.

const devtools = new FlagKitDevToolsCore(client, options);
devtools.mount(document.body);

// Programmatic override access
devtools.overrides.setOverride('feature-x', true, 'boolean');
devtools.overrides.setOverride('max-items', 50, 'number', Date.now() + 3600000); // expires in 1 hour
devtools.overrides.clearOverride('feature-x');
devtools.overrides.clearAllOverrides();
devtools.overrides.getAllOverrides();  // { [key]: { value, type, setAt, expiresAt? } }
devtools.overrides.count;              // number of active overrides

// Subscribe to changes
const unsubscribe = devtools.overrides.onOverrideChange((overrides) => {
  console.log('Overrides changed:', overrides);
});

URL Override Sharing

Share flag overrides with teammates via URL. Overrides are encoded as base64url JSON in the __fk_overrides query parameter.

// Generate a shareable URL with current overrides
const url = devtools.generateShareUrl?.();
// → https://app.example.com/page?__fk_overrides=eyJmZWF0dXJlLXgiOns...

// Overrides are automatically applied when the page loads with the parameter
// The parameter is stripped from the URL after applying

Command Palette

Press Cmd+K (Mac) or Ctrl+K (Windows/Linux) when DevTools is open to launch the command palette. Search across:

  • Tabs — Navigate to any panel ("Go to Flags panel", "Go to Network panel", etc.)
  • Commands — "Clear all overrides", "Export overrides", "Refresh flags"
  • Flags — Search and jump to any flag by key name

Use arrow keys to navigate and Enter to select.

Keyboard Shortcuts

| Shortcut | Action | |----------|--------| | Ctrl/Cmd + Shift + F | Toggle DevTools panel | | Escape | Close DevTools panel | | Ctrl/Cmd + K | Open/close command palette | | 1 - 6 | Switch panels (Flags, Context, Events, Network, Status, Settings) |

Console API

When mounted, DevTools registers window.__FLAGKIT_DEVTOOLS__ for use in the browser console:

// Flag inspection
__FLAGKIT_DEVTOOLS__.getFlag('show-marketplace')    // Full evaluation result

// Override management
__FLAGKIT_DEVTOOLS__.setOverride('my-flag', true, 'boolean')
__FLAGKIT_DEVTOOLS__.clearOverride('my-flag')
__FLAGKIT_DEVTOOLS__.clearAllOverrides()
__FLAGKIT_DEVTOOLS__.getAllOverrides()

// Panel control
__FLAGKIT_DEVTOOLS__.open()
__FLAGKIT_DEVTOOLS__.close()
__FLAGKIT_DEVTOOLS__.toggle()
__FLAGKIT_DEVTOOLS__.reset()               // Fully re-mount DevTools

// Status
__FLAGKIT_DEVTOOLS__.getStatus()
// → { isOpen, mounted, overrideCount, activeTab, theme }
__FLAGKIT_DEVTOOLS__.version               // DevTools core version
__FLAGKIT_DEVTOOLS__.sdkVersion            // SDK version
__FLAGKIT_DEVTOOLS__.mounted               // true

Programmatic API

const devtools = new FlagKitDevToolsCore(client, options);
devtools.mount(document.body);

devtools.open();
devtools.close();
devtools.toggle();
devtools.isOpen;                              // boolean

devtools.setActiveTab('network');             // Switch to a panel
devtools.showToast('Hello!');                 // Show a toast notification
devtools.recordEvent('custom', { foo: 1 });   // Add to events timeline
devtools.recordNetworkRequest({...});         // Add to network panel

devtools.getStore();                          // Access internal state store
devtools.getClient();                         // Access the SDK client

devtools.unmount();                           // Clean up all resources

Directory Structure

src/devtools/
├── devtools.core.ts                  # Main orchestrator class
├── index.ts                          # Public barrel exports
├── constants/
│   ├── theme-tokens.constants.ts     # CSS custom properties (light/dark themes)
│   ├── shell-styles.constants.ts     # Toggle, panel, header, tabs, resize CSS
│   ├── flag-styles.constants.ts      # Flag list, switch, detail panel CSS
│   ├── common-styles.constants.ts    # Buttons, inputs, toast, toolbar CSS
│   └── devtools.constants.ts         # Numeric limits and intervals
├── stores/
│   ├── override-engine.store.ts      # Override persistence, expiry, cross-tab sync
│   ├── devtools-state.store.ts       # Reactive state container
│   ├── presets.store.ts              # Named override preset management
│   ├── personas.store.ts            # Saved context personas with PII detection
│   ├── flag-history.store.ts         # Flag value change history
│   └── starred-flags.store.ts        # Starred/pinned flags
├── types/
│   └── devtools.types.ts             # DevToolsOptions, TabId, TabDefinition
├── ui/
│   ├── shell/components/
│   │   ├── floating-toggle.component.ts   # Draggable FAB with edge snap
│   │   ├── panel-header.component.ts      # Panel header with title and close
│   │   ├── tab-bar.component.ts           # Tab navigation bar
│   │   └── resize-handle.component.ts     # Panel resize drag handle
│   ├── shared/components/
│   │   ├── json-tree.component.ts         # Collapsible JSON viewer
│   │   ├── json-diff.component.ts         # Side-by-side JSON diff
│   │   ├── search-input.component.ts      # Debounced search input
│   │   └── toast.component.ts             # Toast notification system
│   └── panels/
│       ├── components/
│       │   ├── command-palette.component.ts   # Cmd+K fuzzy search
│       │   ├── events-panel.component.ts      # Event timeline
│       │   ├── network-panel.component.ts     # HTTP request inspector
│       │   ├── settings-panel.component.ts    # Theme, presets, import/export
│       │   └── status-panel.component.ts      # SDK health dashboard
│       ├── flags/components/
│       │   ├── flags-panel.component.ts       # Master/detail flag browser
│       │   ├── flags-panel-helpers.util.ts    # Filter, sort, format helpers
│       │   ├── flag-detail.component.ts       # Flag detail view
│       │   ├── flag-dependencies.component.ts # Flag dependency graph
│       │   └── evaluation-trace.component.ts  # Evaluation rule trace
│       └── context/components/
│           ├── context-panel.component.ts     # Context editor with JSON tree
│           └── persona-selector.component.ts  # Persona save/load/apply
└── utils/
    ├── styles.util.ts                # CSS injection into Shadow DOM
    ├── dom.util.ts                   # DOM element helpers (el, setText, svg)
    ├── devtools-integrations.util.ts # Keyboard shortcuts, console API, network hooks
    ├── devtools-panel-layout.util.ts # Panel shell DOM construction
    ├── devtools-panel-factory.util.ts# Panel creation and active panel rendering
    ├── url-overrides.util.ts         # URL-based override sharing (__fk_overrides)
    ├── persisted-state.util.ts       # localStorage read/write with validation
    ├── sanitize.util.ts              # XSS prevention and payload limits
    ├── accessibility.util.ts         # Focus trap, screen reader announcements
    ├── draggable.util.ts             # Pointer-event drag handler
    ├── edge-snap.util.ts             # Snap-to-nearest-edge positioning
    ├── bug-report-formatter.util.ts  # Markdown bug report generator
    └── virtual-scroll.util.ts        # Virtual scrolling for large lists

Production Safety

DevTools automatically skip mounting in production (NODE_ENV === 'production') unless allowUrlOverrides is explicitly set. Use tree-shaking-friendly conditional imports:

// The DevTools code won't be included in production bundles
if (import.meta.env.DEV) {
  const { FlagKitDevToolsCore } = await import('@teracrafts/flagkit');
  const devtools = new FlagKitDevToolsCore(client);
  devtools.mount(document.body);
}

API Reference

Flag Evaluation

// Boolean flags
client.getBooleanValue('feature', false);

// String flags
client.getStringValue('welcome-msg', 'Hello!');

// Number flags
client.getNumberValue('max-items', 10);

// JSON flags
client.getJsonValue('config', { enabled: false });

// Full evaluation result
client.evaluate('feature');

// Evaluate all flags
client.evaluateAll();

// Check if flag exists
client.hasFlag('feature');

// Get all flag keys
client.getAllFlagKeys();

Context Management

// Set evaluation context
client.setContext({ userId: 'user-123', country: 'US' });

// Identify user
client.identify('user-123', { custom: { plan: 'premium' } });

// Reset to anonymous
client.reset();

Event Tracking

// Track custom event
client.track('button_clicked', { button: 'signup' });

// Flush events immediately
await client.flush();

Lifecycle

client.isReady();           // Check if ready
await client.waitForReady(); // Wait for ready
await client.refresh();      // Force refresh flags
await client.close();        // Cleanup

Evaluation Context

client.setContext({
  userId: 'user-123',
  email: '[email protected]',
  country: 'US',
  custom: { plan: 'premium' },
  privateAttributes: ['email'],  // Not sent to server
});

Error Handling

import {
  FlagKitError,
  AuthenticationError,
  NetworkError,
} from '@teracrafts/flagkit';

try {
  await FlagKit.initialize({ apiKey: 'invalid' });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof NetworkError) {
    console.error('Network issue:', error.message);
  }
}

Browser Usage

<script src="https://unpkg.com/@teracrafts/flagkit"></script>
<script>
  FlagKit.initialize({ apiKey: 'sdk_your_api_key' })
    .then(client => {
      const darkMode = client.getBooleanValue('dark-mode', false);
    });
</script>

Requirements

  • Node.js 18+ (for server-side)
  • Modern browser with fetch support (for client-side)

License

MIT