Quickstart
This guide takes you from install to a working feature gate: a free user hits an upgrade prompt, a paid user gets through — all client-side, with no account, no API keys, and no backend.
Before You Begin
Section titled “Before You Begin”- A React 18+ application
- Node.js 22.13+
-
Install the SDK
@revturbine/sdkis published to the public npm registry — no auth, token, or registry configuration needed.Terminal window npm install @revturbine/sdkTerminal window pnpm add @revturbine/sdkTerminal window yarn add @revturbine/sdk -
Add a Playbook
You don’t need a RevTurbine account for this. Scaffold a starter Playbook straight into your app:
Terminal window npx revturbine createThat installs the SDK and CLI and drops a local-mode
playbook.jsonin place. If you already have an account,revturbine download --live --save ./playbook.jsonpulls your real config instead.The Playbook contains your plans, entitlements, placements, targeting rules, surface templates, and UI paths — everything the SDK needs to run locally.
-
Wrap your app in
RevTurbineProviderwith local runtimesrc/App.tsx import { RevTurbineProvider, Slot, RuntimeMode } from '@revturbine/sdk';import playbook from './playbook.json';import { useMemo } from 'react';function App() {const options = useMemo(() => ({runtimeMode: RuntimeMode.LocalOnly,localRuntime: { playbook },user: {id: 'user_123',plan_handle: 'starter',},uiPathResolvers: {navigate_to_plans: (ctx) => {window.location.href = '/pricing';},open_checkout_modal: (ctx) => {// Open your checkout flow, e.g. Stripe Checkoutconsole.log('Checkout for plan:', ctx.plan_handle);},book_demo: (ctx) => {window.open(ctx.url ?? '/sales/demo', '_blank');},custom_url: (ctx) => {if (ctx.url) window.location.href = ctx.url;},},}), []);return (<RevTurbineProvider options={options}><YourApp /></RevTurbineProvider>);} -
Add a placement slot
Drop a
<Slot>where you want a placement to appear:src/components/Dashboard.tsx import { Slot } from '@revturbine/sdk';function Dashboard() {return (<div><h1>Dashboard</h1>{/* RevTurbine renders an upgrade banner here — or nothing */}<Slotid="dashboard_top_banner"surfaceTemplateIds={["banner_placement"]}/>{/* Rest of your dashboard */}</div>);} -
Gate a paid feature
Wrap the gated UI in
<Gate>. It renders its children when the user is entitled, and shows the configured upgrade placement when they aren’t — no manual check.src/components/BatchExport.tsx import { Gate } from '@revturbine/sdk';function BatchExport() {return (<Gate id="batch_export_gate" can="batch_export"><BatchExportButton /></Gate>);}can="batch_export"is shorthand forcheck={{ entitlement: 'batch_export' }}. For custom deny UI, use theuseCanhook instead — see the Entitlements guide. -
Verify it works
Start your dev server. With the starter Playbook’s free plan,
<Gate>renders the upgrade placement instead of the button. Switch the user to the paid plan — changeplanin theuseroption — and the button appears. Placement slots behave the same way: if no placement matches the current user context, the component renders nothing, which is the additive principle at work.
What Are UI Paths?
Section titled “What Are UI Paths?”A UI path is the bridge between a RevTurbine placement and your application’s navigation. When a user clicks a CTA button inside a placement (e.g., “Upgrade Now” or “View Plans”), the SDK doesn’t navigate directly — instead, it invokes a UI path resolver function that you provide, giving your app full control over what happens next.
Each UI path has an action_type that identifies the intent:
| Action Type | Typical Use |
|---|---|
navigate_to_plans | Go to pricing / plan comparison page |
open_checkout_modal | Open Stripe Checkout or your billing flow |
book_demo | Open a sales demo booking form |
custom_url | Navigate to an arbitrary URL |
open_upgrade_modal | Show an upgrade modal |
open_feature_tour | Launch a product tour |
dismiss | Close / dismiss the placement |
The resolver receives a context object with any metadata attached in the config (e.g., plan_handle, url, promotion_id). This keeps your conversion flows decoupled from placement content — marketers can change CTA copy and targeting without code changes.
Expected Output
Section titled “Expected Output”When a placement is configured and the user matches targeting rules, the slot renders the appropriate component — a banner, modal, button, toast, or other surface. When no placement is eligible, it renders nothing.
Next Steps
Section titled “Next Steps”- Interactive playground — try live editable SDK scenarios in your browser
- Runtime modes — understand local_only, server, and custom endpoints
- Component Gallery — interactive demos of the built-in placement surfaces
- Entitlement gates — gate features, enforce usage limits
- Headless API — use the SDK without React
- API Reference — full TypeDoc reference for all exports