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-react

v1.1.0

Published

FlagKit React SDK - Feature flags for React applications

Readme

@teracrafts/flagkit-react

React SDK for FlagKit feature flags. Provides React-specific hooks and components for easy integration.

Requirements

  • React 17.0.0 or higher
  • @teracrafts/flagkit (peer dependency)

Installation

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

Quick Start

1. Wrap your app with FlagKitProvider

import { FlagKitProvider } from '@teracrafts/flagkit-react';

function App() {
  return (
    <FlagKitProvider
      apiKey="sdk_your_api_key"
      options={{ pollingInterval: 30000 }}
      context={{ userId: 'user-123' }}
      onReady={() => console.log('FlagKit ready!')}
      onError={(err) => console.error('FlagKit error:', err)}
    >
      <YourApp />
    </FlagKitProvider>
  );
}

2. Use hooks to access flags

import { useBooleanFlag, useStringFlag, useJsonFlag } from '@teracrafts/flagkit-react';

function MyComponent() {
  // Simple boolean flag
  const darkMode = useBooleanFlag('dark-mode', false);

  // String flag
  const theme = useStringFlag('theme', 'default');

  // JSON flag with type safety
  const config = useJsonFlag<{ maxItems: number }>('feature-config', { maxItems: 10 });

  return (
    <div className={darkMode ? 'dark' : 'light'}>
      <h1>Theme: {theme}</h1>
      <p>Max items: {config.maxItems}</p>
    </div>
  );
}

API Reference

Components

<FlagKitProvider>

Provider component that initializes the SDK and makes it available to child components.

<FlagKitProvider
  apiKey="sdk_xxx"              // Required: Your API key
  options={{                     // Optional: SDK options
    pollingInterval: 30000,
    cacheEnabled: true,
  }}
  context={{                     // Optional: Initial evaluation context
    userId: 'user-123',
    email: '[email protected]',
  }}
  onReady={() => {}}             // Optional: Called when SDK is ready
  onError={(err) => {}}          // Optional: Called on errors
  onFlagsChanged={(flags) => {}} // Optional: Called when flags update
>
  <App />
</FlagKitProvider>

<FeatureFlag>

Component for conditional rendering based on flag value.

// Simple usage
<FeatureFlag flag="new-feature" fallback={<OldFeature />}>
  <NewFeature />
</FeatureFlag>

// With loading state
<FeatureFlag
  flag="feature"
  loading={<Spinner />}
  fallback={<Disabled />}
>
  <Enabled />
</FeatureFlag>

// With render prop for value access
<FeatureFlag flag="ab-test">
  {(value, result) => (
    value === 'variant-a' ? <VariantA /> : <VariantB />
  )}
</FeatureFlag>

Hooks

useFlagKit()

Access the FlagKit client instance directly.

const client = useFlagKit();

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

// Identify users
client?.identify('user-456', { plan: 'premium' });

useFlagKitStatus()

Get SDK initialization status.

const { isReady, isLoading, error, lastUpdated } = useFlagKitStatus();

if (isLoading) return <Spinner />;
if (error) return <Error message={error.message} />;

useBooleanFlag(key, defaultValue, options?)

Get a boolean flag value.

const darkMode = useBooleanFlag('dark-mode', false);
const betaEnabled = useBooleanFlag('beta-features', false, {
  context: { userId: 'special-user' }
});

useStringFlag(key, defaultValue, options?)

Get a string flag value.

const theme = useStringFlag('theme', 'light');
const welcomeMessage = useStringFlag('welcome-message', 'Hello!');

useNumberFlag(key, defaultValue, options?)

Get a number flag value.

const maxItems = useNumberFlag('max-items', 10);
const discountPercent = useNumberFlag('discount', 0);

useJsonFlag<T>(key, defaultValue, options?)

Get a JSON flag value with type safety.

interface Config {
  enabled: boolean;
  maxRetries: number;
  endpoints: string[];
}

const config = useJsonFlag<Config>('feature-config', {
  enabled: false,
  maxRetries: 3,
  endpoints: [],
});

useFlag(key, options?)

Get full flag evaluation result.

const { value, enabled, reason, isLoading, result } = useFlag('my-flag');

console.log(`Flag evaluated with reason: ${reason}`);

useFlags(keys, options?)

Get multiple flags at once.

const flags = useFlags(['feature-a', 'feature-b', 'feature-c']);

return (
  <div>
    {flags['feature-a']?.enabled && <FeatureA />}
    {flags['feature-b']?.enabled && <FeatureB />}
  </div>
);

useAllFlagsEnabled(keys, options?)

Check if all specified flags are enabled.

const allEnabled = useAllFlagsEnabled(['feature-a', 'feature-b']);

if (allEnabled) {
  return <CombinedFeature />;
}

useAnyFlagEnabled(keys, options?)

Check if any of the specified flags are enabled.

const anyEnabled = useAnyFlagEnabled(['beta-a', 'beta-b', 'beta-c']);

if (anyEnabled) {
  return <BetaFeatures />;
}

Advanced Usage

Direct Context Access

For advanced use cases, you can access the FlagKit context directly:

import { useFlagKitContext } from '@teracrafts/flagkit-react';

function AdvancedComponent() {
  const { client, isReady, isLoading, error, lastUpdated } = useFlagKitContext();

  if (!isReady) return null;

  // Direct client access for complex operations
  const result = client?.evaluate('complex-flag');

  return <div>Last updated: {lastUpdated}</div>;
}

Dynamic Context Updates

Update evaluation context dynamically based on user actions:

function UserProfile({ user }) {
  const client = useFlagKit();

  useEffect(() => {
    if (client && user) {
      client.identify(user.id, {
        email: user.email,
        plan: user.plan,
        createdAt: user.createdAt,
      });
    }
  }, [client, user]);

  // Flags will re-evaluate with new context
  const premiumFeature = useBooleanFlag('premium-feature', false);

  return premiumFeature ? <PremiumUI /> : <StandardUI />;
}

Type-Safe JSON Flags

When using useJsonFlag, provide a type parameter for full type safety:

interface FeatureConfig {
  enabled: boolean;
  maxRetries: number;
  endpoints: string[];
}

// TypeScript will enforce the structure
const config = useJsonFlag<FeatureConfig>('feature-config', {
  enabled: false,
  maxRetries: 3,
  endpoints: [],
});

// config.maxRetries is typed as number
// config.unknownProp would be a type error

Server-Side Rendering (SSR)

The SDK supports SSR by checking for the browser environment. During SSR, hooks will return default values until the client-side hydration completes.

// Safe to use in Next.js, Remix, etc.
const darkMode = useBooleanFlag('dark-mode', false);
// Returns false during SSR, then updates on client

Next.js App Router

For Next.js App Router, wrap the provider in a client component:

// providers.tsx
'use client';

import { FlagKitProvider } from '@teracrafts/flagkit-react';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <FlagKitProvider apiKey={process.env.NEXT_PUBLIC_FLAGKIT_KEY!}>
      {children}
    </FlagKitProvider>
  );
}

// layout.tsx
import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Developer Tools

FlagKit React includes DevTools components for inspecting and overriding feature flags during development. DevTools render inside Shadow DOM for complete style isolation — they will never affect your application's layout or CSS. When overrides are toggled in DevTools, all flag hooks automatically re-evaluate.

Quick Start

import { FlagKitProvider, FlagKitDevTools, useFlagKitContext } from '@teracrafts/flagkit-react';

function App() {
  return (
    <FlagKitProvider apiKey="sdk_your_key">
      <MyApp />
      {import.meta.env.DEV && <DevToolsMount />}
    </FlagKitProvider>
  );
}

function DevToolsMount() {
  const { client } = useFlagKitContext();
  if (!client) return null;
  return <FlagKitDevTools client={client} theme="system" defaultOpen={false} />;
}

Components

<FlagKitDevTools />

Floating overlay with a draggable toggle button. Mounts to document.body and manages its own lifecycle.

<FlagKitDevTools
  client={client}
  theme="system"
  buttonPosition="bottom-right"
  panelPosition="right"
  enabled={import.meta.env.DEV}
/>

<FlagKitDevToolsPanel />

Embedded panel without floating toggle — renders inline in your layout. Useful for admin dashboards.

<FlagKitDevToolsPanel client={client} theme="dark" />

<FlagKitDevToolsLazy />

Code-split variant using React.lazy that only downloads DevTools code on first render.

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

{import.meta.env.DEV && <FlagKitDevToolsLazy client={client} />}

useFlagKitDevTools Hook

Programmatic control over DevTools from any component inside the provider.

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

function DevToolsController() {
  const { isOpen, open, close, toggle, overrideCount, devtools } = useFlagKitDevTools({
    theme: 'system',
  });

  return (
    <button onClick={toggle}>
      DevTools {isOpen ? '(open)' : '(closed)'} — {overrideCount} overrides
    </button>
  );
}

| Return | Type | Description | |--------|------|-------------| | isOpen | boolean | Whether the panel is currently open | | open | () => void | Open the DevTools panel | | close | () => void | Close the DevTools panel | | toggle | () => void | Toggle the panel open/closed | | overrideCount | number | Number of active flag overrides | | devtools | FlagKitDevToolsCore \| null | Direct access to the core instance |

Configuration

All components accept the same configuration props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | client | FlagKitClient | required | Client instance from useFlagKitContext() | | enabled | boolean | true | Whether to render | | 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 | | 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 16:

Flags Panel

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

  • Search — Filter flags by key name
  • Filters — 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
  • 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
  • Personas — Save, load, and manage named context configurations
  • PII detection — Warns when context contains fields that look like 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
  • Export — Copy all events to clipboard as JSON

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

Status Panel

SDK health dashboard showing runtime configuration and state.

  • SDK Info — SDK version, DevTools version, session ID, ready state
  • Configuration — Polling interval, cache TTL, timeout, retries, offline mode
  • Cache — Flag count, cache status, persistence, 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

When you toggle a flag in DevTools, the override engine intercepts flag evaluations and returns your override value instead of the server value. Overrides persist to localStorage and sync across browser tabs automatically.

All React flag hooks (useFlag, useBooleanFlag, useStringFlag, useNumberFlag, useJsonFlag) re-evaluate automatically when overrides change.

URL Override Sharing

Share flag overrides with teammates via URL. Overrides are encoded in the __fk_overrides query parameter and automatically applied when the page loads.

Command Palette

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

Keyboard Shortcuts

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

Console API

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

__FLAGKIT_DEVTOOLS__.getFlag('my-flag')       // Full evaluation result
__FLAGKIT_DEVTOOLS__.setOverride('my-flag', true, 'boolean')
__FLAGKIT_DEVTOOLS__.clearOverride('my-flag')
__FLAGKIT_DEVTOOLS__.clearAllOverrides()
__FLAGKIT_DEVTOOLS__.getAllOverrides()
__FLAGKIT_DEVTOOLS__.open()
__FLAGKIT_DEVTOOLS__.close()
__FLAGKIT_DEVTOOLS__.toggle()
__FLAGKIT_DEVTOOLS__.getStatus()              // { isOpen, mounted, overrideCount, activeTab, theme }

Production Safety

DevTools code should be excluded from production bundles. Use conditional rendering:

function App() {
  return (
    <FlagKitProvider apiKey="sdk_your_key">
      <MyApp />
      {import.meta.env.DEV && <DevToolsMount />}
    </FlagKitProvider>
  );
}

The <FlagKitDevToolsLazy /> variant ensures DevTools code is only downloaded when rendered, keeping your production bundle clean when combined with conditional rendering.

Security

The React SDK inherits all security features from the core TypeScript SDK.

Security Options

Configure security options through the options prop on FlagKitProvider:

<FlagKitProvider
  apiKey="sdk_your_api_key"
  options={{
    // Throws SecurityError instead of warning when PII detected
    strictPIIMode: true,

    // Secondary key for seamless key rotation
    secondaryApiKey: "sdk_backup_key",

    // Grace period for key rotation (default: 5 minutes)
    keyRotationGracePeriod: 300000,

    // Local development port (uses http://localhost:{port}/api/v1)
    // ONLY for development - do not use in production
  }}
>
  <App />
</FlagKitProvider>

API Key Types

Use the appropriate key type for your environment:

  • sdk_ - Client SDK keys, safe for browser use
  • cli_ - Limited client keys with restricted permissions
  • srv_ - Server keys, should ONLY be used server-side
// Good: Client SDK key for React apps
<FlagKitProvider apiKey="sdk_your_client_key">

// Warning: Server keys in browser will trigger a security warning
<FlagKitProvider apiKey="srv_your_server_key">

Strict PII Mode

Enable strict PII mode to prevent accidental PII exposure:

<FlagKitProvider
  apiKey="sdk_xxx"
  options={{ strictPIIMode: true }}
  context={{
    userId: "user-123",
    // This will throw SecurityError instead of just warning
    email: "[email protected]",
  }}
>

With strict mode enabled, potential PII fields in context will throw a SecurityError. Either:

  1. Remove the PII field from context
  2. Mark it as a private attribute (not sent to server)

Best Practices

1. Place Provider at the Root

Wrap your entire app with FlagKitProvider to ensure all components have access:

// Correct: Provider at root
<FlagKitProvider apiKey="sdk_xxx">
  <App />
</FlagKitProvider>

2. Use Appropriate Default Values

Always provide sensible defaults that work when flags are unavailable:

// Good: Safe default for a potentially breaking change
const newCheckout = useBooleanFlag('new-checkout', false);

// Good: Default to a working configuration
const config = useJsonFlag('api-config', {
  timeout: 5000,
  retries: 3,
});

3. Handle Loading States

Use the loading prop or useFlagKitStatus to handle initialization:

function App() {
  const { isLoading, error } = useFlagKitStatus();

  if (error) return <ErrorBoundary error={error} />;
  if (isLoading) return <AppSkeleton />;

  return <MainContent />;
}

4. Avoid Flag Evaluation in Loops

Memoize flag values when rendering lists:

// Good: Flag evaluated once
const showBadge = useBooleanFlag('show-badge', false);

return items.map(item => (
  <Item key={item.id} showBadge={showBadge} />
));

5. Track Important Conversions

Use the client to track events when users interact with flagged features:

const client = useFlagKit();
const newFeature = useBooleanFlag('new-feature', false);

const handleClick = () => {
  client?.track('feature_used', {
    feature: 'new-feature',
    variant: newFeature ? 'enabled' : 'disabled',
  });
};

License

MIT