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.
Recipes
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/sdkThe 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_xxxNEXT_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.