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

@sheepit-ai/react

v0.9.1

Published

Sheepit React bindings — Provider, hooks, and components for feature flags, experiments, and analytics

Readme

@sheepit-ai/react

React hooks and components for Sheepit feature flags, experiments, and events.

npm version license

React bindings for Sheepit, built on @sheepit-ai/sdk-js: a provider, hooks for flags, experiments, and events, and components for flag-gated UI, experiment variants, page views, and render errors.

Install

@sheepit-ai/sdk-js is a peer dependency, so install both:

npm install @sheepit-ai/react @sheepit-ai/sdk-js

Requires React 18 or later.

Key type

Use a publishable key (lp_pub_…). Never put a secret key (lp_sec_…) in client code.

Quick start

Wrap your app once. In the Next.js App Router, do it in a client component:

"use client";

import type { ReactNode } from "react";
import { SheepitProvider } from "@sheepit-ai/react";

export function Providers({
  children,
  user,
}: {
  children: ReactNode;
  user: { id: string; traits?: Record<string, unknown> } | null;
}) {
  return (
    <SheepitProvider config={{ apiKey: process.env.NEXT_PUBLIC_SHEEPIT_KEY! }} user={user}>
      {children}
    </SheepitProvider>
  );
}

Then use the hooks in any client component:

"use client";

import { useExperiment, useFlag, useTrack } from "@sheepit-ai/react";

export function CheckoutButton() {
  const track = useTrack();
  const newCheckout = useFlag("new_checkout_flow", false);
  const { variant } = useExperiment("checkout_copy");

  return (
    <button onClick={() => track("checkout_started", { variant, new_checkout: newCheckout })}>
      {variant === "bold" ? "Get it now" : "Buy"}
    </button>
  );
}

Release attribution

config is passed straight to Sheepit.create(), so release works as in @sheepit-ai/sdk-js: pass the commit SHA your bundler injects at build time: Next.js process.env.NEXT_PUBLIC_SHEEPIT_RELEASE, Vite import.meta.env.VITE_SHEEPIT_RELEASE (set to $CI_COMMIT_SHA in CI). process does not exist in a plain browser or Vite bundle. It must equal the version sheepit ci release registered (default: the full commit SHA). Events report context.sdk.name = "sdk-react".

Provider behaviour

  • config is any SheepitConfig. The provider calls Sheepit.create(config) once, in an effect on mount, and calls destroy() on unmount. Changing config later has no effect; remount the provider to use a new key.
  • Until the client is created (server render, first client render), and whenever creation fails, the context holds a no-op client: useFlag returns your default and useExperiment returns { variant: "control" }. A failed creation (for example, a missing or non-publishable key) is reported with console.warn, not thrown.
  • user drives identity: when user.id changes to a new value the provider calls identify(user.id, user.traits). undefined and null are treated the same (no user): going from a user the provider identified to either one calls reset(). If you never pass a user, the provider never calls identify() or reset(), so you can manage identity yourself with useSheepit(). On web, traits are not used for flag targeting yet.
  • The SDK evaluates nothing locally. Flag values and experiment assignments come from the API, and useFlag / useExperiment re-render automatically when configuration loads or changes. See how flags and experiments resolve for refresh timing.

API

| Export | Kind | Purpose | | --------------------------------------------------------------- | --------- | ---------------------------------------------------------------------------- | | <SheepitProvider config user?> | Component | Creates the client and provides it via context | | useFlag(key, default = false) | Hook | Current flag value, or default when there is none | | useExperiment(key) | Hook | { variant, payload? }; "control" when there is no assignment | | useTrack() | Hook | Stable track(event, properties?) function | | useSheepit() | Hook | The underlying client (identify, reset, flush, overrides, status, …) | | <Feature flagKey fallback? match?> | Component | Renders children when the flag is truthy, or equals match | | <Experiment experimentKey variants? fallback?> or render-prop | Component | Renders variants[variant], else fallback, else variants.control | | <PageViewTracker pathname searchParams? /> | Component | On route change: $page_leave for the previous route, then $page_view | | <ErrorBoundary fallback? onError?> | Component | Catches render errors and tracks them as $error | | noopClient | Value | The silent client the provider uses before init |

Flush and teardown are handled by the provider and the underlying SDK. To flush explicitly, call useSheepit().flush().

Components

"use client";

import { usePathname } from "next/navigation";
import { ErrorBoundary, Experiment, Feature, PageViewTracker } from "@sheepit-ai/react";

export function Page() {
  const pathname = usePathname();
  return (
    <ErrorBoundary fallback={<p>Something went wrong.</p>}>
      <PageViewTracker pathname={pathname} />
      <Feature flagKey="new_banner" fallback={null}>
        <p>New banner</p>
      </Feature>
      <Experiment
        experimentKey="hero_copy"
        variants={{ control: <h1>Ship faster</h1>, bold: <h1>Ship today</h1> }}
      />
      <Experiment experimentKey="pricing_layout">
        {({ variant, payload }) => (
          <p>
            {variant} {JSON.stringify(payload ?? {})}
          </p>
        )}
      </Experiment>
    </ErrorBoundary>
  );
}

Identity without the user prop

"use client";

import { useSheepit } from "@sheepit-ai/react";

export function LogoutButton({ onLogout }: { onLogout: () => Promise<void> }) {
  const sheepit = useSheepit();
  return (
    <button
      onClick={async () => {
        await onLogout();
        sheepit.reset();
      }}
    >
      Log out
    </button>
  );
}

Testing

@sheepit-ai/react/test exports TestProvider, createMockClient, and noopClient. TestProvider takes a client (a full or partial client); any method you do not supply falls back to the no-op client.

import { render } from "@testing-library/react";
import { vi } from "vitest";
import { TestProvider, createMockClient } from "@sheepit-ai/react/test";
import { CheckoutButton } from "./checkout-button";

// Partial client: set flag values directly
render(
  <TestProvider
    client={{ flag: (key, fallback) => (key === "new_checkout_flow" ? true : (fallback ?? false)) }}
  >
    <CheckoutButton />
  </TestProvider>,
);

// Spies on every method (pass your test runner's fn factory)
const client = createMockClient({}, vi.fn);
render(
  <TestProvider client={client}>
    <CheckoutButton />
  </TestProvider>,
);

Runtime support

Client components only. The hooks and components use React context and effects, so they cannot run in React Server Components; use @sheepit-ai/server on the server. React 18+; Node.js 20+ for tooling (engines).

Deprecated exports

GoaTechProvider, GoaTechProviderProps, useGoaTech, IGoaTech, and GoaTechConfig are aliases of the Sheepit* names. Use the Sheepit* names.

Links

License

MIT. Copyright (c) 2026 GoaTech AI LLC. See LICENSE.