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

@dr-sentry/react

v1.1.4

Published

Official React SDK for the DeploySentry feature flag platform

Downloads

1,073

Readme

@dr-sentry/react

Official React SDK for the DeploySentry feature flag platform. Provides React hooks and a context provider for evaluating feature flags with real-time SSE updates.

Installation

npm install @dr-sentry/react

React 18 or later is required as a peer dependency.

Quick Start

Wrap your application with DeploySentryProvider and use hooks anywhere in the tree:

import { DeploySentryProvider, useFlag } from '@dr-sentry/react';

function App() {
  return (
    <DeploySentryProvider
      apiKey="ds_live_abc123"
      baseURL="https://api.dr-sentry.com"
      environment="production"
      project="my-app"
      application="my-web-app"
      user={{ id: 'user-42' }}
    >
      <MyComponent />
    </DeploySentryProvider>
  );
}

function MyComponent() {
  const showBanner = useFlag('show-banner', false);

  if (!showBanner) return null;
  return <div>New feature banner!</div>;
}

Provider Props

| Prop | Type | Required | Description | |---------------|--------------|----------|--------------------------------------------------| | apiKey | string | Yes | API key for authenticating with DeploySentry. | | baseURL | string | Yes | Base URL of the DeploySentry API. | | environment | string | Yes | Environment identifier (e.g. "production"). | | project | string | Yes | Project identifier. | | application | string | Yes | Application identifier | | user | UserContext | No | User context for targeting rules. | | children | ReactNode | Yes | React children. | | mode | string | No | SDK mode: server, file, or server-with-fallback. | | flagData | object | No | Pre-loaded flag config for file/fallback mode. | | defaults | object | No | Offline defaults consulted when the API call fails (fallback only). |

Offline / File Mode

For offline use or testing, pass pre-loaded flag config via the flagData prop:

import flagConfig from './.deploysentry/flags.json';

<DeploySentryProvider
  apiKey="not-used"
  baseURL=""
  environment="staging"
  project="my-project"
  application="my-web-app"
  mode="file"
  flagData={flagConfig}
>
  <App />
</DeploySentryProvider>

Modes

| Mode | Behavior | | --- | --- | | server (default) | API calls + SSE streaming | | file | Use flagData prop, evaluate locally. No server contact. | | server-with-fallback | Try server first. If unavailable, use flagData as fallback. |

Export the config from the dashboard (App Settings → Export flags.yaml), then convert to JSON or import with a YAML plugin.

Offline Defaults (Fallback)

For resilience against transient API outages, pass a flag-export JSON via the defaults prop. Unlike flagData (which replaces the API), defaults only kicks in when the API call fails — successful live data overwrites the defaults per-key.

Generate the snapshot with the CLI:

deploysentry flags export --application web --env production -f flags.json

Then import it as a build-time asset:

import defaults from './flags.json';

<DeploySentryProvider
  apiKey={import.meta.env.VITE_DEPLOYSENTRY_API_KEY}
  baseURL="https://api.dr-sentry.com"
  environment="production"
  project="my-app"
  application="web"
  defaults={defaults}
>
  <App />
</DeploySentryProvider>

Environment matching: the environment prop is matched against the export's environments[] first by UUID, then by name (case-insensitive). When a match is found, that env's per-flag {enabled, value} overrides the flag's global default_value. When no match, the global default_value is used (the flag is treated as enabled).

Hooks

useFlag(key, defaultValue)

Returns the resolved flag value. Falls back to defaultValue while loading or if the flag does not exist.

const isEnabled = useFlag('dark-mode', false);
const variant = useFlag('checkout-flow', 'control');

useFlagDetail(key)

Returns detailed evaluation information including metadata.

const { value, enabled, metadata, loading } = useFlagDetail('new-checkout');

// metadata contains: category, purpose, owners, isPermanent, expiresAt, tags

useFlagsByCategory(category)

Returns all flags matching the given category.

const experiments = useFlagsByCategory('experiment');
const releases = useFlagsByCategory('release');

Categories: 'release' | 'feature' | 'experiment' | 'ops' | 'permission' | 'envvar'

useExpiredFlags()

Returns all non-permanent flags whose expiresAt date is in the past. Useful for admin dashboards.

const expired = useExpiredFlags();

useFlagsVersion()

Returns the project's flag-set version last loaded from the server (number), or null before the first successful fetch / in file mode. The version advances on any change to the project's flag state, so it validates exactly which flag set the app is serving. Re-renders when a refetch changes the version.

const version = useFlagsVersion();
return <span>flags v{version ?? '—'}</span>;

useDispatch(operation)

Returns the resolved handler for a registered operation based on current flag state. See Register / Dispatch Pattern below.

const checkout = useDispatch<() => Promise<void>>('checkout');
await checkout();

useDeploySentry()

Returns the raw DeploySentryClient instance for advanced use-cases.

const client = useDeploySentry();

Register / Dispatch Pattern

The register/dispatch pattern centralizes all flag-gated behavior in one place instead of scattering if/else checks across components.

Setup (single-point registration)

Create one registration file that runs at app initialization:

// src/flags/registrations.ts
import type { DeploySentryClient } from '@dr-sentry/react';
import { legacySearch, vectorSearch } from '../search';
import { classicCheckout, newCheckout } from '../checkout';

export function registerFlags(client: DeploySentryClient) {
  // Search — default handler, then flag-gated override
  client.register('search', legacySearch);
  client.register('search', vectorSearch, 'vector-search-v2');

  // Checkout
  client.register('checkout', classicCheckout);
  client.register('checkout', newCheckout, 'new-checkout-flow');
}

Call registerFlags(client) after the client initializes (e.g. in the provider setup or an app-level effect).

Usage in components

import { useDispatch } from '@dr-sentry/react';

function SearchBar() {
  const search = useDispatch<(query: string) => Promise<Results>>('search');

  return (
    <input onChange={(e) => search(e.target.value).then(setResults)} />
  );
}

How it works

  1. client.register(operation, handler, flagKey?) — Register a handler for a named operation. With flagKey, it's only selected when that flag is enabled. Without flagKey, it's the default fallback.
  2. useDispatch(operation) — Returns the first registered handler whose flag is enabled, or the default handler. The component never knows about flags.

Why single-point registration

  • One file shows every flag-gated behavior in the app
  • Easy auditing — search for a flag key and find every behavior it controls
  • Simple cleanup when a flag is retired (remove the registration, keep the handler)
  • LLMs and code review tools can read one file to understand all flag-gated behavior

Real-Time Updates

The provider automatically opens an SSE connection to receive flag updates in real time. When a flag changes on the server, all components consuming that flag re-render immediately. The connection reconnects automatically with exponential backoff if it drops.

SSR Compatibility

Hooks return default/empty values during server-side rendering. Flags are fetched client-side after the provider mounts.

Types

All types are exported from the package:

import type {
  Flag,
  FlagCategory,
  FlagDetail,
  FlagMetadata,
  ProviderProps,
  UserContext,
} from '@dr-sentry/react';

Authentication

All requests use an API key passed in the Authorization header:

Authorization: ApiKey <your-api-key>

Pass the key via the provider's apiKey prop. The SDK sets the header automatically.

Session Consistency

Bind evaluations to a session so the server caches results for a consistent user experience:

<DeploySentryProvider
  apiKey="ds_key_xxxxxxxxxxxx"
  baseURL="https://api.dr-sentry.com"
  environment="production"
  project="my-app"
  application="my-web-app"
  sessionId={`user:${userId}`}
>
  <App />
</DeploySentryProvider>
const client = useDeploySentry();
await client.refreshSession();
  • The session ID is sent as an X-DeploySentry-Session header on every request.
  • The server caches evaluation results per session for 30 minutes (sliding TTL).
  • Omit the session ID to always get fresh evaluations on each request.

License

Apache-2.0