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

@flagdashio/react-native

v0.1.9

Published

FlagDash React Native SDK — feature flags, remote config, and AI configs

Readme

@flagdashio/react-native

Official React Native and Expo SDK: feature flags, remote config, AI configs, translations and experiments — with offline startup and lifecycle-aware live updates.

Installation

npm install @flagdashio/react-native @flagdashio/sdk \
  @react-native-async-storage/async-storage

Quick start

import { FlagDashProvider, useFlag } from "@flagdashio/react-native";

export function Root() {
  return (
    <FlagDashProvider sdkKey={process.env.EXPO_PUBLIC_FLAGDASH_SDK_KEY!}>
      <Checkout />
    </FlagDashProvider>
  );
}

function Checkout() {
  const enabled = useFlag("checkout-v2", false, { user: { id: "user_123" } });
  return enabled ? <NewCheckout /> : <LegacyCheckout />;
}

Use one provider at the application root. It owns the client, its subscriptions and their cleanup.

What you get beyond a fetch

| | | |---|---| | Offline startup | AsyncStorage keeps the last known values, so the first render after a cold start with no network gets real values instead of your defaults. | | Lifecycle aware | Realtime pauses while the app is backgrounded and resumes on foreground, so a backgrounded app is not holding a socket open. | | Live updates | A change in the dashboard re-renders the components that read it. |

Provider options

<FlagDashProvider
  sdkKey={key}
  baseUrl="https://flagdash.io"   // self-hosted? point it here
  refreshInterval={60_000}        // polling fallback, ms
  realtime={true}
  enableCache={true}              // AsyncStorage persistence
  enableLifecycle={true}          // pause/resume on background/foreground
>

user is ignored

The provider still accepts a user prop for backwards compatibility, but it is deprecated and not wired into evaluations. Passing it there silently changes nothing. Pass context per call instead:

useFlag("checkout-v2", false, { user: { id: userId, plan: "pro" } });

Include a user id whenever you want a stable answer. Percentage rollouts and A/B variations hash it, so a context without one re-rolls on every evaluation by design.

Feature flags

// Just the value.
const enabled = useFlag("checkout-v2", false, context);

// With loading state, for a first paint that should not flash the default.
const { value, isLoading } = useFlagWithLoading("checkout-v2", false, context);

// Why did it resolve that way?
const { value, reason, variationKey } = useFlagDetail("checkout-v2", false, context);

useFlag<T> is generic — the default's type is the value's type:

const copy = useFlag<string>("banner-copy", "control", context);
const limits = useFlag<Record<string, number>>("limits", {}, context);

Remote config

const limit = useConfig("rate_limit", 100);
const { value, isLoading } = useConfigWithLoading("rate_limit", 100);

AI configs

Prompts, agents, skills and rules, editable without an app store release.

const { config, isLoading } = useAiConfig("support-agent.md");
const { configs } = useAiConfigs({ fileType: "agent" });

Translations

useTranslation loads a whole catalogue and hands back a t function, rather than resolving one key at a time:

const { t, isLoading, error } = useTranslation("fr", "checkout");

<Text>{t("greeting", { variables: { name: "Alice" } })}</Text>

Reaching the client

const { client, isReady } = useFlagDash();

isReady is what to gate a splash screen on. client is the underlying ReactNativeClient for anything the hooks do not cover.

Interaction replay

import { ReactNativeInteractionReplay } from "@flagdashio/react-native";

const replay = new ReactNativeInteractionReplay({ sdkKey: replayKey, release: appVersion });
if (await replay.start()) {
  replay.screen("Checkout");
  replay.interaction({ name: "buy_tapped", screen: "Checkout" });
  replay.breadcrumb("payment requested");
  await replay.stop();
}

Records interactions for session replay. Treat what it captures as sensitive and check it against your privacy policy before enabling it in production.

Security

Create an environment key under Dashboard → Project → Environment → API keys and grant only the read scopes the app uses. Never embed a pat_ token or a write-capable key: anything in an app bundle is readable.

A client key never returns targeting rules, so the app cannot see who else you are targeting.

Source

Developed in the FlagDash monorepo and mirrored to flagdash/flagdash-js, alongside the browser, Node, React and Vue packages. Install from npm — Git cannot install a single workspace subdirectory as a standalone package.

License

MIT

AI releases

Create a release in Manage → AI Releases, select the environment, then set a baseline, candidate and rollout. With your initialized client, evaluate it using an environment-bound key with ai_configs:read:

const { client } = useFlagDash();
const release = await client?.aiConfigRelease("support-agent", "usr_123");

The result includes key, version, config, reason, variation_key, and rollout_percentage (idiomatic field names for typed SDKs). Pass a stable user identity. Decisions are fetched afresh; verify baseline, rollout and paused behavior in development before ramping production. Your backend calls the AI provider. Ordinary evaluation leaves secret references unresolved; never put provider credentials in a configuration delivered to browsers or mobile apps. See the release guide for lifecycle and cleanup.

Remote config value format

Remote config storage and server metadata use exactly one {"value": ...} envelope. Convenience config reads return the inner application value, without recursively unwrapping application fields named value. For example, stored {"value": {"value": 7, "enabled": false}} reads as {"value": 7, "enabled": false}. Metadata methods retain the envelope.

MCP and management writes accept the envelope and automatically wrap bare objects. To store an application object whose only key is value, send {"value": {"value": 7}}. Arrays and scalar values must be inside the envelope. Existing bare stored objects are migrated, preserving secret-reference bindings. Server SDK callers previously receiving the envelope should remove their extra .value access when upgrading. Verify in a development environment first.