Skip to content

cuped-io/flame

Repository files navigation

flame

@cuped-io/flame on npm @cuped-io/flame-react on npm @cuped-io/flame-edge on npm License: MIT

Client-side SDKs for cuped.io — A/B testing with CUPED variance reduction.

This repo is a pnpm workspace with three packages:

Package npm Source Role
@cuped-io/flame npmjs.com ./packages/flame Core SDK. IIFE for <script> tag use; ESM/CJS for npm consumers.
@cuped-io/flame-react npmjs.com ./packages/flame-react React bindings: <CupedProvider>, useExperiment, <Experiment>, useObserve.
@cuped-io/flame-edge npmjs.com ./packages/flame-edge Edge resolver + signed cookie utilities for zero-flash SSR. Web Crypto only.

What it does

  1. Fetches active experiments for a project
  2. Assigns visitors to variants
  3. Applies variant changes to the DOM (8 change types: text, html, attribute, class, style, css, visibility, redirect)
  4. Auto-detects e-commerce events (add to cart, checkout, etc.)
  5. Tracks observations with experiment assignments for server-side goal matching

Quick start

You'll need a DSN. Sign up at cuped.io, create a project, and copy the DSN from Settings → Install snippet (it looks like https://YOUR_KEY@api.cuped.io).

Option 1: Script tag (no-code DOM mutations)

Drop this in your <head> and define variants in the dashboard:

<script
  src="https://cdn.cuped.io/flame.js"
  data-dsn="https://YOUR_KEY@api.cuped.io"
></script>

Option 2: React (CSR)

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

function App() {
  return (
    <CupedProvider dsn="https://YOUR_KEY@api.cuped.io">
      <Hero />
    </CupedProvider>
  );
}

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

Option 3: Next.js App Router with zero-flash SSR

The recommended setup for Next.js. Variants are resolved at the edge before the first byte renders, so server HTML matches the assigned variant from request #1.

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

.env.local:

CUPED_DSN=https://YOUR_KEY@api.cuped.io
NEXT_PUBLIC_CUPED_DSN=https://YOUR_KEY@api.cuped.io
CUPED_COOKIE_SECRET=<generate with: openssl rand -base64 32>

middleware.ts:

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:

'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:

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>
  );
}

That's it — useExperiment and <Experiment> work the same way as Option 2.

Examples

  • examples/script-tag — Static HTML page exercising all 8 change types.
  • examples/next-app — Next.js App Router app with edge middleware + signed prehydrated cookie. Includes verification steps.

Documentation

Development

pnpm install
pnpm test         # all packages
pnpm typecheck
pnpm lint
pnpm build        # IIFE + ESM/CJS across packages

Releases are managed by changesets and published to npm via OIDC trusted publishing with provenance attestations.

License

MIT — see LICENSE.

About

Client-side script for cuped.io

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors