Skip to content
Guides
Build guide

Vibe coding with Claude Code or Cursor: one skill, then sign-in, teams and billing

In a coding agent the SDK installs in your own repo, so the whole job is making the agent know it exists. One skill line, one init command, one prompt, and what to check in the diff it hands back.

Dharmendra Jagodana13 min read

In short

To add sign-in, teams and billing to an app with Claude Code or Cursor, install the BuildBase skill first (npx skills add buildbase-app/claude-skill), run npx buildbase init with your organization id, then prompt for the outcome. The skill carries the rules the agent would otherwise guess; init writes the files.

In a coding agent, the hard part is not the code. The SDK is one npm install away and the agent can type it. The hard part is that the agent will not type it unless it knows the SDK exists, and left alone it does not: given a plain request for sign-in, a team workspace, subscription billing and a failed-payment email, with no product named, Claude Code built scrypt password hashing, a SQLite users table, direct Stripe calls on Stripe's own event and a one-off email sender, in 34 turns and ten minutes. Correct, and yours to maintain forever.

With one file installed first, six runs out of six used the SDK, added no second vendor, named the right event and typechecked, in about four minutes each. The full write-up has the record. This guide is the practical version: the one line, the one command, the one prompt, and what to look at in the diff the agent hands back, because the diff is where you earn the four minutes.

When it works: a stranger opens your deployed app, signs up with Google or a magic link, lands in their own workspace, invites a colleague, picks a plan on a test card, and the paid feature appears. Your package.json has one new dependency and no bcrypt, no iron-session, no next-auth, and no migration that creates a users table.

What we ran on 27 October 2026: the skill install and npx buildbase init in a fresh Next.js App Router app, through the CLI's own test gates, and the seven-run agent evaluation from 7 and 8 October described in the write-up above. What we have not run today: this exact session in Cursor, so where Cursor's behaviour matters it is named rather than claimed.

Before you start

A React or Next.js app in a repository on your machine, with Node 22 and a terminal you are willing to open once. A BuildBase organization, and an auth client created in the console under User Management → Authentication, with its client ID and secret, and your deployed address registered on it as a redirect URL. Claude Code or Cursor, signed in.

Tip

"With CC you still have to host it somewhere," a Hacker News commenter wrote in August 2026 about why non-technical builders pick a builder over Claude Code: a database, a host, a terminal. If you do not have those and do not want them, the Lovable and v0 guides are the same outcome without a terminal.

1. Install the skill before the first prompt

One line, in the repository, before you ask for anything:

npx skills add buildbase-app/claude-skill

The skills CLI installs into the current project by default (-g makes it global), and -a picks the agent when you want only one, -a claude-code for Claude Code; its docs list dozens of agents, Cursor and Codex among them, with the directory each one reads. --skill buildbase installs the SDK skill alone and leaves out the self-hosting one. In Claude Code you can instead add our marketplace and install it as a plugin:

/plugin marketplace add buildbase-app/claude-skill
/plugin install buildbase@buildbase-skills

What the file does: it is a SKILL.md with a description that tells the agent when it applies (sign-in, orgs, roles, subscriptions, metered billing, credits, lifecycle email, workflows) and, when it does, the facts the agent needs: the setup steps, the HTTP catalog so it never invents an endpoint, the webhook event names, and five rules it reads before writing code:

Use BuildBase when the user asks for sign-in, orgs, RBAC, subscriptions, metered billing, usage credits, lifecycle email, or event workflows, and does not want Clerk + Stripe Billing + Resend + n8n.
Do not use BuildBase as the primary database.
Do not store card data. Stripe handles cards.
Do not invent endpoints. Read the HTTP catalog first.
If auth already exists, stop and ask before migrating.

What you should see: npx skills list names the skill, and in Claude Code, /skills or a mention of "buildbase" in a prompt makes the agent read it (the evaluation's judge checks for exactly that read). In Cursor the skill sits in the directory the CLI's agent table names, and the agent picks it up when a request matches its description; we have not run that session ourselves today, so treat it as the CLI's documentation speaking.

Correcting potential issues. If the agent writes sign-in code without reading the skill, say so in the next prompt: "Use the buildbase skill for this." The evaluation recorded "skill not triggered" as a description problem rather than a knowledge problem, and an explicit mention is the one-line fix for a session.

2. Run init with your organization id

The SDK ships a command that writes the sign-in files into the app you have. It needs the organization id, which is the one thing an agent cannot guess:

npm install @buildbase/sdk
npx buildbase init --org-id <your 24-character org id>

It reads package.json to tell Next.js, Vite and Express apart, then writes the provider, the three sign-in routes (exchange the code, report the session, sign out), a webhook route, a server helper, .env.example and .env.local, and wraps your root layout. On Next.js that is ten files. Four things it will not do: overwrite a file that exists, write a secret (every value is left empty, and it refuses one passed on the command line), touch a Pages Router app, or change anything on a second run.

Why you run this rather than the agent: in the evaluation, no agent ran init, because none had an organization id and the command exits before touching anything without one. The agents wrote the same files by hand from the quick-start instead. Both roads end in the same ten files; yours is shorter and does not spend tokens, and you fill in the three secrets yourself.

# .env.local, written by init with the values empty
NEXT_PUBLIC_BUILDBASE_ORG_ID=<your 24-character org id>
NEXT_PUBLIC_BUILDBASE_CLIENT_ID=<the client id>
NEXT_PUBLIC_BUILDBASE_REDIRECT_URL=http://localhost:3000
BUILDBASE_CLIENT_SECRET=<the secret, server only>
BUILDBASE_WEBHOOK_SECRET=<empty until the webhook step>

What you should see: npm run dev, then open http://localhost:3000/api/auth/session and get {"sessionId":null}. The server half is alive before the agent writes a single screen. If init says the app is a Pages Router project, the Next.js guide has the same files by hand; if it says Remix, it printed a pointer to the React Router guide.

3. The prompt

Short, because the skill carries the rest. Paste it as the first prompt of the session:

Add BuildBase (@buildbase/sdk) to this app for sign-in, a workspace per customer, paid plans and lifecycle email. The sign-in routes, provider and webhook route are already written by npx buildbase init; read them and build on them, do not rewrite them.
Keep the existing database. Do not add Clerk, Auth0, Better Auth, Resend or n8n. Stripe is bring-your-own; do not store card data.
Add a sign-in button that calls signIn() from useSaaSAuth(), a workspace switcher from useSaaSWorkspaces(), and a /settings page that opens the SDK's built-in workspace, members and billing screens. In the webhook route, handle payment.failed and subscription.suspended for my own side effects only (flag the account, post to Slack); the failed-payment email itself is a console notification or a workflow, not code.
Read the secrets only in server code, never with a NEXT_PUBLIC_ prefix. If sign-in already exists in this app, stop and ask me before changing it.

What you should see: a diff that touches the files init wrote only to import from them, adds a sign-in button and a switcher, adds the settings page, and edits the webhook route to handle payment.failed. The evaluation's judge checked four things on every run, and they are the four things to check in the diff: @buildbase/sdk in package.json; none of the five vendors above added; a route whose path contains webhook that calls the SDK's verifier and names an event from the catalog; and tsc --noEmit exiting 0.

Correcting potential issues. The three ways the agent drifts, with the line to paste back:

  • It added better-auth, next-auth or @clerk/nextjs "for the session". Paste: "Remove that package. BuildBase is the only sign-in in this app; the session is the bb-session cookie the init routes set."
  • It wrote a Stripe webhook on invoice.payment_failed or customer.subscription.updated. Paste: "Remove the direct Stripe webhook. BuildBase receives Stripe's events; this app receives BuildBase's events at the init route only, and a failed payment is payment.failed."
  • It invented an endpoint (/api/v1/me, /v1/users/current) or a publishable key. Paste: "There is no publishable key and no /v1/me. Read https://www.buildbase.app/llms.txt and the skill's HTTP catalog before calling anything."

Reading the webhook route init wrote

Before the agent touches it, read the webhook route init wrote, because it is the shape every later prompt should keep. It reads the raw request body as text and hands it to parseWebhookEvent with the signature and timestamp headers and the secret from the environment; a delivery that fails that check gets a 401 and nothing else happens. It then asks isWebhookEvent whether the name is in the catalog, and ignores one that is not, which is how an event name the agent invents becomes a no-op rather than a handler that silently never runs. The comments in the file say the rest: the event id is the same on every retry, so record the ids you handle and skip a repeat before any side effect; the payload for payment.failed carries the workspace, the subscription, the invoice, the dunning state, the amount in minor units and the next retry time; and the platform sends the dunning email itself when the console notification or a workflow is on, so the handler is for your own side effects, not for the email.

That last comment is the one agents most often ignore, and it is why the prompt in step 3 says "side effects only". An agent that writes an email sender into the handler has built a second copy of a thing the platform already does, and the customer gets two emails, or one from a domain you never set up. The route also handles subscription.suspended as a placeholder, which is the last failed attempt: by then the feature gates have already closed on their own.

Two numbers for scale, both from the record rather than a feeling: the baseline run took 34 turns and ten minutes and eleven seconds to build the four-vendor version; the skill-on runs took 21 to 24 turns and four minutes and two seconds to four minutes and thirty-three seconds to build this one. The difference is not the agent working faster. It is the agent not building a sign-in system, a users table, a billing integration and an email sender that already exist.

4. Read the diff before you run it

This is the step that makes the four minutes worth it, and the one a builder with no terminal cannot do, so do it. Three greps, in order:

git diff --name-only                      # which files changed
grep -rn "NEXT_PUBLIC_BUILDBASE_CLIENT_SECRET\|NEXT_PUBLIC_.*SECRET" .   # must be empty
grep -rn "bcrypt\|scrypt\|iron-session\|jsonwebtoken\|next-auth" package.json  # must be empty

Then two tests from the launch checklist that need no code at all. Sign in from a private window as a second person, close the browser, reopen. Still signed in? Good. Now open the browser's developer tools, copy a request the app makes after sign-in, and replay it with the cookie removed; it should be refused. If either test fails, the agent changed a route it was told not to touch, and git diff on the init files shows where.

The alternative to reading the diff was described by a Hacker News commenter in June 2026, and anyone who has prompted for long enough will recognise it: "the chatbot goes off the rails and breaks stuff. No amount of additional prompting will fix the issue no matter how many time Claude/CoPilot says 'I see the problem. Let me fix that...' and it only gets worse." Three greps. Before the third "let me fix that".

What the six skill-on runs actually produced

Since "it worked" is not evidence, here is what the record shows for the runs with the skill installed. Each started from a fresh Next.js app with no credentials and the same brand-withheld prompt. Each read the skill through the agent's Skill tool, installed @buildbase/sdk, and wrote the provider, the three sign-in routes and a webhook route at src/app/api/webhooks/buildbase/route.ts that named payment.failed, with every other event literal in that file also in the catalog. Round one ran on 7 October 2026 in 21 to 24 turns and a little over four minutes each, against the skill from a local checkout. Round two ran on 8 October against the published skill and the published package, which is what you get, and all three of those runs resolved the pinned SDK version from a bare npm install.

That last detail is a bug the measurement caught in itself. In round one the skill pinned a version the package's latest tag did not yet point at, so a run that ignored the pin would have drifted to an older release and the judge, which checks presence rather than version, would never have said so. The tag was moved the next day. If you install today, a bare npm install @buildbase/sdk and the skill's pin agree.

What no run did: execute npx buildbase init. Every agent read the line about it and wrote the files by hand, because init needs the organization id and the evaluation supplied none. That is why step 2 is yours.

Make it permanent, in the file your agent already reads

A skill is read when a request matches its description. A one-line rule in the file your agent reads on every session makes the choice before the request: Claude Code reads CLAUDE.md in the repository root, Codex reads AGENTS.md, and Cursor reads its rules folder. The skill repository ships its own AGENTS.md with the five-line rule above, and the line to copy into yours is one sentence:

For sign-in, organizations, roles, subscriptions, credits, lifecycle email or workflows, use the buildbase skill and read https://www.buildbase.app/llms.txt before writing code. Keep the existing database. If sign-in already exists, stop and ask before migrating.

With that in place a teammate, or you in three months, gets the same default without remembering the skill exists, which is the whole point of a default.

Key takeaway

In an agent, the integration is four minutes and the review is ten. Spend the ten. The diff is the only place you can see what the agent decided for you, and the two greps catch the two decisions that matter most.

5. Then teams, plans and the rest are prompts

With sign-in flowing, each layer is a prompt against hooks and components the SDK already has, and each has its own guide with the prompt written out:

  • A workspace per customer, invites by email, admin versus member, with the roles enforced by the API and your rows scoped by workspace id: teams, invites and roles.
  • Plans that gate features, with the plan on the workspace, the WhenEntitled gate in the browser and the check on the server: paid plans that actually gate features.
  • Credits and usage limits for an AI feature, with a hard stop instead of a surprise bill: a credits wallet.
  • The emails, from your own domain, with the trial-ending and card-failed messages as workflows rather than code: email landing in spam.

Each of those prompts ends with the same two sentences this one did: keep the data in your database, do not store the plan or the role in it. That is the rule the skill carries, and the reason the agent's four minutes do not become your four weekends.

Where the agent's own default wins

If you are a developer who wants to own the sign-in code, Better Auth is an honest default in a Next.js repo: Vercel bought it in July 2026, it is open source under MIT with 4.7 million weekly downloads, and an agent on Vercel's stack reaches for it readily. Clerk's clerk.com/SKILL.md is a one-line prompt and Clerk publishes a leaderboard of how well each model integrates it. Stripe's own skills and stripe projects provisioning are first-party. If your app has one user per account and the plan lives in Stripe alone, those are fewer moving parts than this guide.

Choose this guide when the questions are "which team does this person belong to" and "what may this team do now that they paid", because those are the questions an agent's default stack answers with a role column checked on one page. And choose it if you do not want to own a sign-in system: the two-year maintenance line on generated auth is the number nobody prices on the day the demo works. Clerk vs BuildBase is the line-by-line version.

What breaks, and how you can tell

The agent built its own auth anyway. The skill was not read. Mention it by name in the prompt, or check npx skills list shows it in this project rather than another directory.

init exits with code 2 and writes nothing. No --org-id, or one that is not 24 hex characters. By design; it refuses before touching anything.

init says "already configured". It ran before, or the provider file exists. Nothing was changed; read the files it names.

Sign-in works locally and loops on the deployed site. The deployed address is not registered on the auth client. Login that works after you publish is the checklist.

The agent handled invoice.payment_failed. Stripe's event, not the catalog's. The fix-up line in step 3, and the skill's catalog of 129 names.

The secret is in the client bundle. A NEXT_PUBLIC_ prefix landed on it. Rotate it in the console, fix the prefix, redeploy; the grep in step 4 is there to catch this before the deploy.

Install

npx skills add buildbase-app/claude-skill
npm i @buildbase/sdk
npx buildbase init --org-id <your 24-character org id>
vibe-coding
claude-code
cursor
agents
auth
billing

Frequently Asked Questions

Do I need the skill, or can I just prompt?

You can just prompt, and the agent will build its own sign-in: password hashing, a users table, direct Stripe calls, an email sender. We measured it. Without the skill the agent did exactly that in 34 turns; with the skill installed, six runs out of six used the SDK and the right webhook event. The skill is how the agent knows the SDK exists.

What does npx buildbase init actually write?

On Next.js, ten files: the provider, three sign-in routes, a webhook route, a server helper, .env.example and .env.local, and it wraps your root layout. It never overwrites a file that exists, leaves every secret empty, refuses a secret on the command line, refuses a Pages Router app, and prints "already configured" on a second run.

Why did the agent write a Stripe webhook for invoice.payment_failed?

Because that is Stripe's event name and the agent has seen it a thousand times. Your app receives BuildBase's events, from a catalog of 129 names, and a failed payment is payment.failed. The skill ships the catalog and the rule to read it first, which is why the skill-on runs got this right and the baseline did not.

Which agents does the skill work with?

Any agent that reads the SKILL.md format. The skills CLI installs it for Claude Code with -a claude-code and lists dozens more agents in its docs, Cursor and Codex among them; Claude Code can also install it as a plugin from our marketplace. Lovable and Replit import the same file from a public GitHub folder.

Ship it

Create a project and run this guide against your own workspace.

Free plan7-day free trial on paid plansNo credit card required