JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 27
  • Score
    100M100P100Q61784F
  • License MIT

React hooks for A/B testing with Testly

Package Exports

  • @testlyjs/react
  • @testlyjs/react/dist/index.esm.js
  • @testlyjs/react/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@testlyjs/react) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@testly/react

A/B testing treated as infrastructure code. Define variants in code, and we handle the science behind the decision.

Features

  • Zero complex configuration - API key and go
  • Type-safe - TypeScript first
  • Framework agnostic internals - Works with Next.js, Remix, Vite, etc.
  • SSR-safe - Won't break during server-side rendering
  • Privacy-first - Ephemeral IDs, no 3rd party cookies
  • Bundle size < 10KB - Zero external dependencies (except React)

Installation

npm install @testly/react

Quick Start

1. Setup (once in your App)

import { TestlyProvider } from '@testly/react';

function App() {
  return (
    <TestlyProvider apiKey="tk_live_abc123">
      <YourApp />
    </TestlyProvider>
  );
}

2. Use in Components

Simple A/B Test

import { useExperiment, useConversion } from '@testly/react';

function PricingPage() {
  const { variant, loading } = useExperiment('pricing-test');
  const convert = useConversion();

  if (loading) return <div>Loading...</div>;

  if (variant === 'variant-b') {
    return (
      <div>
        <h1>New Pricing!</h1>
        <button onClick={() => convert('purchase')}>Buy Now</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Original Pricing</h1>
      <button onClick={() => convert('purchase')}>Buy Now</button>
    </div>
  );
}

Conversion with Metadata

const convert = useConversion();

<button onClick={() => convert('purchase', { 
  revenue: 99.90,
  plan: 'premium',
  currency: 'USD'
})}>
  Upgrade to Premium
</button>

API Reference

TestlyProvider

The provider component that must wrap your application.

Prop Type Description
apiKey string Your Testly API key
config Partial<TestlyConfig> Optional configuration object

TestlyConfig options:

  • debug: Enable robust console logs for debugging (default: false)
  • autoTrackImpressions: Automatically track when a user sees a variant (default: true)
  • dedupConversions: Prevent duplicate conversion tracking for the same experiment (default: true)
  • supabaseUrl: Custom endpoint for Testly API

🛡️ Resilience & Reliability

The SDK is designed to be "bulletproof" in production:

  • Strict Mode Protection: Prevents double-tracking in React Development Mode.
  • Atomic Conversions: Only marks a conversion as "done" if the API request succeeds.
  • Missing ID Validation: Actively warns if the backend returns incomplete data (e.g., missing experiment_id).
  • Offline Safety: Does not block the UI if the tracking server is unreachable.

useExperiment(experimentKey, options?)

Hook to assign a variant to a user.

Options:

  • fallback: Variant to use if the experiment fails or is not found.
  • onAssignment: Callback function called when a variant is assigned.

Returns: UseExperimentResult

  • variant: string | null
  • loading: boolean
  • error: Error | null

useConversion()

Hook to track conversion events.

Returns: (conversionType: string, metadata?: object) => Promise<void>

Development

Build

npm install
npm run build

Local Testing

  1. In this repo:
    npm link
  2. In your test app:
    npm link @testly/react

License

MIT