Quickstart

Pluralize gives your single-player app multi-tenant auth, data, files and billing without a rewrite. This page takes you from an empty Next.js project to the running app below in about ten minutes.

yourapp.com

Recipes

ada@example.com
A
Ramen — 20 minjust now
Focaccia — 90 minjust now
Tacos al pastor — 45 minjust now
New recipe…
Add

1. Create a workspace

Sign up at pluralize.app/signup, create your first app, and copy the App ID (app_xxx) and publishable key (pk_live_xxx) from the dashboard. You'll need both; keep the publishable key out of server-only code because it's designed to ship to browsers.

2. Install the SDK

npm install @pluralize/sdk

The SDK works in browsers, Node.js, and React. A React-specific entry lives under @pluralize/sdk/react.

3. Configure environment variables

# .env.local
NEXT_PUBLIC_PLURALIZE_APP_ID=app_xxx
NEXT_PUBLIC_PLURALIZE_API_KEY=pk_live_xxx

NEXT_PUBLIC_ is required for client-side access in Next.js App Router. These values are not secrets — the key is scoped by appId and only works from the origins you allowlist in the dashboard.

4. Wrap your app in the provider

// app/layout.tsx
import { PluralizeProvider } from '@pluralize/sdk/react';
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <PluralizeProvider
          config={{
            appId: process.env.NEXT_PUBLIC_PLURALIZE_APP_ID!,
            apiKey: process.env.NEXT_PUBLIC_PLURALIZE_API_KEY!,
          }}
        >
          {children}
        </PluralizeProvider>
      </body>
    </html>
  );
}

5. Ship a first page

The page below signs a visitor up, stores a recipe scoped to them, and lists what's there. Every user gets their own rows automatically — no tenant provisioning, no database migrations.

// app/page.tsx
'use client';
import { useEffect, useState } from 'react';
import { useAuth, usePluralize } from '@pluralize/sdk/react';
 
export default function Home() {
  const { user, loading } = useAuth();
  const app = usePluralize();
  const [recipes, setRecipes] = useState<{ id: string; data: { title: string } }[]>([]);
 
  useEffect(() => {
    if (!user) return;
    app.db.collection('recipes').find().then((res) => setRecipes(res.records));
  }, [user, app]);
 
  if (loading) return <p>Loading…</p>;
  if (!user) return <SignupButton />;
 
  return (
    <main className="mx-auto max-w-xl p-6">
      <h1 className="mb-4 text-xl font-semibold">Hi {user.email}</h1>
      <ul className="space-y-1">
        {recipes.map((r) => (
          <li key={r.id}>{r.data.title}</li>
        ))}
      </ul>
    </main>
  );
}
 
function SignupButton() {
  const app = usePluralize();
  return (
    <button
      onClick={() =>
        app.auth.signup('ada@example.com', 'correct horse battery staple')
      }
      className="rounded-md bg-black px-4 py-2 text-white"
    >
      Sign up
    </button>
  );
}

That's every piece: a provider, a hook that tells you who the user is, and a collection call. The same shape extends to files and billing.

Alternative: plain JavaScript (no React)

If you're not using React, initialize once and share the instance:

// lib/pluralize.ts
import { Pluralize } from '@pluralize/sdk';
 
export const app = Pluralize.init({
  appId: process.env.NEXT_PUBLIC_PLURALIZE_APP_ID!,
  apiKey: process.env.NEXT_PUBLIC_PLURALIZE_API_KEY!,
});

Then use app.auth, app.db, app.files, app.billing directly.

Next steps

  • Authentication — login forms, protected routes, session hooks.
  • Data — filters, sort, pagination, unique fields, and share links.
  • Files — per-tenant uploads with MIME and size guardrails.
  • Billing — Stripe checkout, the customer portal, and plan entitlements.