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

@cuped-io/flame-react

v0.2.1

Published

React bindings for the cuped.io A/B testing SDK (@cuped-io/flame)

Readme

@cuped-io/flame-react

npm License: MIT

React bindings for the cuped.io A/B testing SDK.

Provides <CupedProvider>, useExperiment, <Experiment>, and useObserve so you can branch React components on variant assignment without touching the DOM directly.

Install

pnpm add @cuped-io/flame @cuped-io/flame-react

For Next.js zero-flash SSR, also install @cuped-io/flame-edge and follow the Next.js setup below.

You'll need a DSN — get one at cuped.io under Settings → Install snippet.

Usage (CSR / Vite / CRA)

import { CupedProvider, useExperiment, Experiment, useObserve } from '@cuped-io/flame-react';

function App() {
  return (
    <CupedProvider dsn="https://[email protected]">
      <Hero />
      <CheckoutButton />
    </CupedProvider>
  );
}

// Branch on variant
function Hero() {
  const { variant } = useExperiment('hero-cta');
  return <button>{variant?.name === 'treatment' ? 'Buy now' : 'Get started'}</button>;
}

// Or declaratively
function Hero2() {
  return (
    <Experiment
      id="hero-cta"
      variants={{
        control: <button>Get started</button>,
        treatment: <button>Buy now</button>,
      }}
    />
  );
}

// Track a custom event. The event name matches against goals defined
// once at the project level on cuped.io (Project → Goals → Custom event);
// any experiment in the project can then attach the goal as primary
// or secondary.
function VoteButton({ gameId, option }: { gameId: string; option: string }) {
  const observe = useObserve();
  return (
    <button
      onClick={() => {
        castVote(option);
        observe('vote_cast', { game_id: gameId, option });
      }}
    >
      Vote
    </button>
  );
}

Next.js App Router with zero-flash SSR

For Next.js, run variant resolution at the edge so the first server-rendered HTML already matches the assigned variant — no flash, no hydration mismatch.

Install all three packages:

pnpm add @cuped-io/flame @cuped-io/flame-react @cuped-io/flame-edge

Set env vars in .env.local:

CUPED_DSN=https://[email protected]
NEXT_PUBLIC_CUPED_DSN=https://[email protected]
CUPED_COOKIE_SECRET=<generate with: openssl rand -base64 32>

Both CUPED_DSN (server-side, for middleware) and NEXT_PUBLIC_CUPED_DSN (client-side, bundled) are needed and should hold the same value.

Three files:

middleware.ts — resolves at the edge, signs the result into a cookie:

import { createCupedMiddleware } from '@cuped-io/flame-edge/next';

export default createCupedMiddleware({
  dsn: process.env.CUPED_DSN!,
  secret: process.env.CUPED_COOKIE_SECRET!,
});

export const config = {
  matcher: ['/((?!_next/static|_next/image|api/|favicon.ico).*)'],
};

app/providers.tsx — client component that mounts <CupedProvider> (it uses React hooks, so it must be a client boundary):

'use client';
import { CupedProvider } from '@cuped-io/flame-react';
import type { PrehydratedState } from '@cuped-io/flame';

export function Providers({
  children,
  prehydrated,
}: {
  children: React.ReactNode;
  prehydrated?: PrehydratedState;
}) {
  return (
    <CupedProvider
      dsn={process.env.NEXT_PUBLIC_CUPED_DSN!}
      prehydrated={prehydrated}
    >
      {children}
    </CupedProvider>
  );
}

app/layout.tsx — server component that reads the signed cookie and passes the prehydrated state down:

import { cookies } from 'next/headers';
import { readPrehydratedForServerComponent } from '@cuped-io/flame-edge/next';
import { Providers } from './providers';

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const prehydrated = await readPrehydratedForServerComponent(
    await cookies(),
    process.env.CUPED_COOKIE_SECRET!,
  );
  return (
    <html>
      <body>
        <Providers prehydrated={prehydrated ?? undefined}>{children}</Providers>
      </body>
    </html>
  );
}

Once wired, useExperiment and <Experiment> work the same as in CSR — they just render the assigned variant on the server too.

A complete working example lives at examples/next-app in the source repo, including verification steps for cold-resolution, repeat visits, tampered/expired cookies, and graceful network-failure fallback.

Peer dependencies

react ^18 || ^19, react-dom ^18 || ^19.

Documentation

License

MIT