Developer SDK

One npm install. Full SaaS backend.

React hooks for the frontend. Server functions for the backend. Auth, billing, credits, quotas, workspaces, permissions, notifications, and 13 pre-built settings screens. TypeScript-first with full type safety.

$ npm install @buildbase/sdk
<button onClick={() => openWorkspaceSettings('subscription')}>

Choose Your Plan

Compare plans for Northwind's Workspace

MonthlyQuarterlyYearly Save

Pro

$49.00 /month

For a team shipping every week

Subscribe

Starter

$19.00 /month

For a solo founder getting a product live

Subscribe

Features

Core appEverything you need to run the product
Priority supportAnswers within a business day

Usage quotas

API calls10k/mo1k/mo

Your app is an organization in BuildBase. Your users sign in and work inside workspaces - one per team or customer.

You set up

In the console and the SDK

  • One npm install and a provider around your app
  • Hooks and components where your app needs them
  • The server SDK in your backend

You get

For you and your team

  • Settings screens for workspaces, members and billing, already built
  • TypeScript types for everything the SDK returns
  • Every screen in 8 languages, including right-to-left

Three entry points, one package

Import what you need. React SDK for the frontend, server SDK for the backend, data module for reference data.

React SDK

/react

40+ hooks, 20+ conditional components, 13 pre-built settings screens. Add a provider, call hooks, ship. Works with Next.js, Vite, React Router / Remix, TanStack Start, or any other React web app.

  • useSaaSAuth() - sign in, sign out, session
  • useSaaSWorkspaces() - CRUD, members, roles
  • useSubscription() - plans, checkout, trials
  • useCreditBalance() - consume, purchase, track
  • useQuotaUsageStatus() - record, enforce limits
  • usePermissions() - 3-tier permission gates
  • useTrialStatus() - days remaining, ending?
  • useSeatStatus() - seat limits, invite checks
  • useTranslation() - i18n, RTL, native numerals
  • usePushNotifications() - subscribe, permission

Server SDK

@buildbase/sdk

Framework-agnostic. Works with Next.js API routes and Express, NestJS, Fastify, Hono, Astro, on Node.js, Bun, Deno and Cloudflare Workers. Factory pattern with automatic session resolution.

  • bb.usage.record() - metered billing
  • bb.usage.recordBatch() - bulk (up to 100)
  • bb.credits.consume() - with idempotency
  • bb.subscription.get() - check plan status
  • bb.subscription.checkout() - Stripe session
  • bb.workspace.list/create/update/delete()
  • bb.users.invite() - add workspace member
  • bb.notification.send() - email + push
  • bb.permissions.check() - verify access
  • bb.withSession() - background jobs

Shared

/data + core exports

Reference data, billing utilities, permission constants, and150+ TypeScript types shared across frontend and backend. Zero React dependency.

  • countries, currencies, languages, timezones
  • formatCents() - locale-aware currency
  • getPricingVariant() - multi-currency plans
  • calculateTotalSubscriptionCents()
  • validateInvite() - seat limit checks
  • Permission.* - 13 platform permissions
  • resolvePermissions() - 3-tier resolution
  • verifyWebhookSignature() - HMAC-SHA256
  • parseWebhookEvent() - typed payloads
  • eventEmitter - cross-component events

Production code, not pseudocode

Every example runs as-is. Copy, paste, ship.

Setup

Add the provider

Add the provider to the root layout. Pass the org ID and auth config. The SDK handles session management, token refresh, workspace loading, and settings resolution automatically.

app/providers.tsxTSX
import { ApiVersion } from '@buildbase/sdk';
import { SaaSOSProvider } from '@buildbase/sdk/react';

export default function Providers({ children }) {
  return (
    <SaaSOSProvider
      serverUrl="https://api.yourapp.com"
      version={ApiVersion.V1}
      orgId="your-org-id"
      auth={{
        clientId: 'your-client-id',
        redirectUrl: 'http://localhost:3000',
      }}
      locale="en" // en, es, fr, de, ja, zh, hi, ar
    >
      {children}
    </SaaSOSProvider>
  );
}
Authentication

Sign in, sign out

One hook returns the user, auth status, sign in, sign out, and openWorkspaceSettings() to open any settings screen. Conditional components render based on auth state.

components/app.tsxTSX
import {
  useSaaSAuth,
  WhenAuthenticated,
  WhenUnauthenticated,
} from '@buildbase/sdk/react';

function App() {
  const { user, signIn, signOut, openWorkspaceSettings } = useSaaSAuth();

  return (
    <>
      <WhenUnauthenticated>
        <button onClick={() => signIn()}>Sign In</button>
      </WhenUnauthenticated>

      <WhenAuthenticated>
        <p>Welcome, {user?.name}</p>
        <button onClick={() => openWorkspaceSettings('subscription')}>
          Manage Plan
        </button>
        <button onClick={signOut}>Sign Out</button>
      </WhenAuthenticated>
    </>
  );
}
Subscriptions & Trials

Paywalls as components

useTrialStatus() returns days remaining and whether the trial is ending. Conditional components gate UI by subscription state, specific plans, or trial status. Checkout creates a Stripe session automatically.

pages/billing.tsxTSX
import {
  useSubscription,
  useTrialStatus,
  useCreateCheckoutSession,
  WhenTrialEnding,
  WhenNoSubscription,
  WhenSubscriptionToPlans,
} from '@buildbase/sdk/react';

function BillingPage({ workspaceId }) {
  const { subscription } = useSubscription(workspaceId);
  const { isTrialing, daysRemaining } = useTrialStatus();
  const { createCheckoutSession } = useCreateCheckoutSession(workspaceId);

  return (
    <>
      <WhenTrialEnding daysThreshold={3}>
        <Banner>{daysRemaining} days left in your trial.</Banner>
      </WhenTrialEnding>

      <WhenNoSubscription>
        <button onClick={() => createCheckoutSession({
          planVersionId: 'pro-v1',
          billingInterval: 'monthly',
        })}>
          Subscribe to Pro
        </button>
      </WhenNoSubscription>

      <WhenSubscriptionToPlans plans={['starter']}>
        <UpgradePrompt />
      </WhenSubscriptionToPlans>
    </>
  );
}
Credits & Expiration

Consume, track, gate

Consume credits with idempotency keys for safe retries. Returns a typed INSUFFICIENT_CREDITS error on 402 with available and requested fields. Track expiring credits with a configurable lookahead window (1-90 days).

components/ai-feature.tsxTSX
import {
  useCreditBalance,
  useConsumeCredits,
  useExpiringCredits,
  WhenCreditsExhausted,
  WhenCreditsLow,
} from '@buildbase/sdk/react';

function AIFeature({ workspaceId }) {
  const { balance } = useCreditBalance(workspaceId);
  const { consumeCredits } = useConsumeCredits(workspaceId);
  const { expiringCredits } = useExpiringCredits(workspaceId, 7);

  const handleGenerate = async () => {
    try {
      await consumeCredits({ amount: 10, description: 'AI generation' });
      // proceed with generation
    } catch (err) {
      if (err.code === 'INSUFFICIENT_CREDITS') {
        // err.available and err.requested are available
      }
    }
  };

  return (
    <>
      <p>Credits: {balance?.available}</p>
      {expiringCredits > 0 && <p>{expiringCredits} credits expire soon</p>}

      <WhenCreditsLow threshold={10}>
        <p>Running low — buy more credits.</p>
      </WhenCreditsLow>

      <WhenCreditsExhausted>
        <p>No credits left.</p>
      </WhenCreditsExhausted>

      <button onClick={handleGenerate}>Generate (10 credits)</button>
    </>
  );
}
Server-Side

Backend integration

The BuildBase() factory resolves sessions automatically from a callback. For background jobs or non-request contexts, use withSession() to create a scoped client. Supports configurable timeout, retry with exponential backoff, and debug logging.

app/api/generate/route.tsTSX
import BuildBase from '@buildbase/sdk';

const bb = BuildBase({
  serverUrl: 'https://api.yourapp.com',
  orgId: 'your-org-id',
  getSessionId: async () => {
    const cookies = await getCookies();
    return cookies.get('bb-session')?.value ?? null;
  },
});

// API route — record usage and enforce quota
export async function POST(req) {
  const usage = await bb.usage.record(workspaceId, {
    quotaSlug: 'api-calls',
    quantity: 1,
    idempotencyKey: req.headers.get('x-request-id'),
  });

  if (usage.available <= 0) {
    return Response.json({ error: 'Quota exceeded' }, { status: 429 });
  }

  return Response.json({ remaining: usage.available });
}

// Background job — use withSession() for non-request contexts
const api = bb.withSession(serviceAccountSessionId);
await api.credits.consume(workspaceId, { amount: 50 });
await api.notification.send(workspaceId, 'job-completed');
Webhooks

Verify and handle

HMAC-SHA256 signature verification with timing-safe comparison and configurable max age (default 5 minutes). Parse events into typed payloads. Handle subscription changes, credit events, workspace actions, and more.

app/api/webhooks/route.tsTSX
import { parseWebhookEvent } from '@buildbase/sdk';

export async function POST(req) {
  const body = await req.text();

  // Verifies the signature and parses the payload — returns null on failure
  const parsed = parseWebhookEvent({
    body,
    signature: req.headers.get('x-buildbase-signature'),
    timestamp: req.headers.get('x-buildbase-timestamp'),
    secret: process.env.WEBHOOK_SECRET,
  });

  if (!parsed) {
    return Response.json({ error: 'Invalid signature' }, { status: 401 });
  }

  switch (parsed.event) {
    case 'subscription.upgraded':
      await enablePremiumFeatures(parsed.data.workspaceId);
      break;
    case 'credit.low_balance':
      await notifyTeam(parsed.data.workspaceId);
      break;
    case 'workspace.member_added':
      await syncToExternalCRM(parsed.data);
      break;
  }

  return Response.json({ received: true });
}
Permissions & Seats

3-tier permission resolution

Permissions resolve through three layers: workspace overrides, then org settings, then SDK defaults. Owners get all permissions automatically. useSeatStatus() returns member count, included seats, billable seats, max-seat status, and an invite validation result with a human-readable block reason.

pages/team.tsxTSX
import {
  usePermissions,
  useSaaSAuth,
  useSeatStatus,
  WhenPermission,
  WhenWorkspaceRoles,
  Permission,
} from '@buildbase/sdk/react';

function TeamPage({ workspace }) {
  const { can } = usePermissions();
  const { openWorkspaceSettings } = useSaaSAuth();
  const {
    memberCount, includedSeats, availableSeats,
    isAtMax, canInvite, inviteBlockReason,
  } = useSeatStatus(workspace);

  return (
    <>
      <p>{memberCount} of {includedSeats} seats used</p>

      <WhenPermission permission={Permission.WORKSPACE_MEMBERS_INVITE}>
        <button disabled={!canInvite}>
          {canInvite ? 'Invite Member' : inviteBlockReason}
        </button>
      </WhenPermission>

      <WhenWorkspaceRoles roles={['owner', 'admin']}>
        <button onClick={() => openWorkspaceSettings('permissions')}>
          Manage Permissions
        </button>
      </WhenWorkspaceRoles>

      {can(Permission.WORKSPACE_BILLING_MANAGE) && <BillingLink />}
    </>
  );
}
Internationalization

8 languages, native numerals

600+ translated strings across all settings screens. ICU MessageFormat for pluralization. Native numeral systems: Devanagari for Hindi, Arabic-Indic for Arabic. RTL layout direction for Arabic. English bundled by default; other languages lazy-loaded.

components/price.tsxTSX
import { useTranslation, SUPPORTED_LOCALES } from '@buildbase/sdk/react';
// Locales: 'en', 'es', 'fr', 'de', 'ja', 'zh', 'hi', 'ar'

function PriceDisplay({ cents, currency }) {
  const { t, fmtCents, fmtNum, dir } = useTranslation();

  return (
    <div dir={dir}> {/* Automatically 'rtl' for Arabic */}
      <p>{t('subscription.currentPlan')}</p>
      <p>{fmtCents(cents, currency)}</p>
      {/* $49.99 (en) | ४९.९९ (hi, Devanagari) | ٤٩٫٩٩ (ar, Arabic-Indic) */}
      <p>{fmtNum(1234)}</p>
      {/* 1,234 (en) | १,२३४ (hi) | ١٬٢٣٤ (ar) */}
    </div>
  );
}

13 pre-built settings screens

Every SaaS needs workspace settings. The SDK ships a production-ready settings dialog opened with one function call. Translated, permission-gated, and responsive.

openWorkspaceSettings('subscription')
Account

Edit name, email, language, country, currency, and timezone

Security

Manage passkeys and review or sign out active sessions

Devices

Review signed-in devices, rename them, sign out, or forget unrecognized ones

Connected agents

Review AI agents with account access and disconnect them to revoke access

Settings

Set workspace name, icon, and billing currency

Members

Invite members by email, assign roles, track seat usage, remove access

Plan & Billing

View current plan, switch plans, cancel or resume, access invoices

Usage

Track per-quota usage, overage costs, and billing cycle

Credits

Check balance, purchase packages, review transaction history

Features

Enable or disable feature flags per workspace

Notifications

Subscribe to push notifications, toggle per-event email and push delivery

Permissions

Edit role-permission matrix with granular toggle controls

Danger Zone

Permanently delete workspace with confirmation

Also included: <PricingPage>, <CreditStorePage>, <WorkspaceSwitcher>, and <BetaForm> - all with render props for full layout control.

Declarative UI gating

No if-statements for permissions, subscriptions, or feature flags. Wrap UI in conditional components. The SDK resolves state and renders or hides children.

Auth

<WhenAuthenticated>
<WhenUnauthenticated>

Subscriptions

<WhenSubscription>
<WhenNoSubscription>
<WhenSubscriptionToPlans plans={[]}>
<WhenTrialing>
<WhenNotTrialing>
<WhenTrialEnding daysThreshold={3}>

Quotas

<WhenQuotaAvailable slug="">
<WhenQuotaExhausted slug="">
<WhenQuotaOverage slug="">
<WhenQuotaThreshold slug="" threshold={80}>

Credits

<WhenCreditsAvailable min={1}>
<WhenCreditsExhausted>
<WhenCreditsLow threshold={10}>

Permissions & Roles

<WhenPermission permission="">
<WhenRoles roles={[]}>
<WhenWorkspaceRoles roles={[]}>

Feature Flags

<WhenWorkspaceFeatureEnabled slug="">
<WhenWorkspaceFeatureDisabled slug="">
<WhenUserFeatureEnabled slug="">
<WhenUserFeatureDisabled slug="">

Also included

8 languages built in

English, Spanish, French, German, Japanese, Chinese, Hindi, Arabic. ICU MessageFormat with pluralization. RTL for Arabic. Lazy-loaded - only English in the initial bundle.

Multi-currency billing

Per-plan pricing variants by currency. formatCents() for locale-aware display. Workspace billing currency lock. Available currencies auto-detected from plan config.

Notifications

Send email and push notifications from the server SDK. Per-event user preferences with toggles. Browser push with VAPID auto-setup. Browser-specific unblock instructions.

Seat-based pricing

useSeatStatus() calculates included seats, billable extras, per-seat cost, invite eligibility, and human-readable block reasons. Syncs with subscription state.

Pricing utilities

calculateTotalSubscriptionCents(), getBasePriceCents(), getQuotaOverageCents(), getBillingIntervalAndCurrencyFromPriceId() - full pricing math without Stripe SDK.

Usage batch recording

bb.usage.recordBatch() sends up to 100 usage events in one call. Idempotency keys per item. Returns per-item success/failure results.

Event system

Global eventEmitter for cross-component communication. Workspace CRUD, user changes, and role updates emit typed events components can subscribe to.

Auth intent preservation

saveAuthIntent() stores the destination before auth redirect. consumeAuthIntent() restores it after sign-in. Survives full page reloads.

40+

React Hooks

20+

Conditional Components

13

Settings Screens

150+

TypeScript Types

8

Languages

Skip the blank file

Start from a Next.js app that already has the SDK wired in, or have Claude add it to yours.

Integrate the SDK with Claude

buildbase@buildbase-skills

Takes a Next.js app from npm install to a working sign-in, then covers workspaces, billing, feature flags, quotas, credits, notifications, webhooks and calling BuildBase from a non-Node backend.

In Claude Code:

Any agent (Cursor, Codex, Copilot and others), from a shell:

Then ask Claude: “Add BuildBase auth to my Next.js app.”

Other ways to install, including claude.ai

Frequently Asked Questions

Do my users see this?

They see the workspace settings, profile, billing and credits screens the SDK renders in your app. Sign-in happens on hosted pages with your branding.

Which frameworks does it work with?

React on the front end (Next.js, Vite, React Router / Remix, TanStack Start), and Node.js on the server (Express, NestJS, Fastify, Hono, Astro).

What do I install?

One package, @buildbase/sdk. The React parts come from @buildbase/sdk/react, and the server functions from @buildbase/sdk itself.

Which languages do the screens come in?

8: English, Spanish, French, German, Japanese, Chinese, Hindi, Arabic, including right-to-left.

Install it and see

One package, a provider and a hook. The quick start goes from npm install to a signed-in user.

7-day free trialNo credit card requiredCancel anytime