mcpField
B
better-auth-scaffold

better-auth-scaffold

github.com/pproencaSecurity218133 installsUpdated 11w ago
Repository

About better-auth-scaffold

A template skill for adding Better Auth to a Next.js App Router project with Drizzle. It generates files for configurable authentication presets and guides schema generation and migrations.

Key features

  1. 01Parameterized authentication templates
  2. 02Minimal, social, and advanced presets
  3. 03Server, client, route, and middleware files
  4. 04Drizzle schema and client templates
  5. 05Generation and migration command guidance

Use cases

  1. 01Setting up authentication in a Next.js project
  2. 02Adding Better Auth to Next.js with Drizzle
  3. 03Generating a social or advanced configuration
  4. 04Filling gaps in a partial authentication setup

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pproenca/dot-skills --skill better-auth-scaffold

After installing, type/better-auth-scaffoldin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

config.json
gotchas.md
metadata.json
assets/templates/
auth-client.ts.template
auth.ts.template
db-index.ts.template
db-schema-better-auth.ts.template
email.ts.template
env.template
middleware.ts.template
permissions.ts.template
route.ts.template
sign-in-page.tsx.template
references/
conventions.md

Details

From the project README

Better Auth Scaffold (Next.js + Drizzle)

Parameterized templates for bootstrapping a Better Auth setup in a Next.js App Router project using the Drizzle adapter. Each template enforces the conventions documented in references/conventions.md — file layout, plugin ordering, env handling, runtime selection.

When to Apply

Reference these templates when:

  • Starting a new Next.js project that needs authentication
  • Adding Better Auth to an existing Next.js + Drizzle codebase
  • Refactoring a partial Better Auth setup that's missing the catch-all route, middleware, or nextCookies() ordering
  • Generating a per-feature variant (minimal, social, advanced) on top of an existing project

Setup

Required parameters
ParameterRequiredDefaultDescription
presetnominimalminimal (email+password) | social (adds Google + GitHub) | advanced (social + twoFactor + magicLink)
db_provideryes—pg | mysql | sqlite (Drizzle provider)
app_nameyes—Display name (becomes 2FA issuer in authenticator apps when preset=advanced)
Optional parameters
ParameterDefaultDescription
auth_pathlib/auth.tsServer auth module path
client_pathlib/auth-client.tsClient module path
api_route_pathapp/api/auth/[...all]/route.tsCatch-all route handler path
protected_paths["/dashboard"]Routes the middleware guards

If config.json already exists with values, the skill uses those; otherwise it asks the user.

Available Templates

TemplateOutput FileWhen to emit
auth.ts.templatelib/auth.tsAlways
auth-client.ts.templatelib/auth-client.tsAlways
route.ts.templateapp/api/auth/[...all]/route.tsAlways
middleware.ts.templatemiddleware.tsWhen protected_paths is non-empty
env.template.env.exampleAlways
db-schema-better-auth.ts.templatedb/schema/auth.tsAlways (stub — replace with output of better-auth generate)
db-index.ts.templatedb/index.tsWhen the project has no Drizzle client yet
email.ts.templatelib/email.tsWhen preset=advanced (and the file doesn't already exist)
sign-in-page.tsx.templateapp/sign-in/page.tsxWhen the project has no sign-in page (closes the middleware redirect loop)
permissions.ts.templatelib/permissions.tsOptional starter for org/admin plugin work

How to Use

  1. Resolve parameters. Read config.json first; for any missing required parameter (db_provider, app_name), ask the user via AskUserQuestion.

  2. Render each template. For each template file:

    • Read the template.
    • Substitute {{placeholder}} values ({{app_name}}, {{db_provider}}, etc.) with the resolved parameter values.
    • Apply PRESET[...] conditional blocks using these rules:
      1. Find every pair of marker lines matching // PRESET[<tags>] and // /PRESET[<tags>] (or /* PRESET[...] */ / # PRESET[...] for non-JS files — same syntax, different comment style).
      2. Parse <tags> as a comma-separated list (e.g. social,advanced).
      3. If the chosen preset value is in <tags> → remove ONLY the two marker lines; keep the lines between them.
      4. If the chosen preset value is NOT in <tags> → remove the ENTIRE block including both marker lines.
      5. Markers may be nested (e.g. PRESET[advanced] inside PRESET[minimal,social,advanced]); process from inside out.
    • For Mustache-style iteration in middleware.ts.template (// {{#protected_paths}} ... // {{/protected_paths}}), repeat the lines between the markers once per item in the list, substituting {{path}} with each value.
  3. Write output files. Before writing, check if the target file already exists:

    • If it doesn't exist → write it.
    • If it exists and is identical → no-op.
    • If it exists and differs → show a diff and ask the user (overwrite / merge / skip).
  4. Run the CLI sequence. After all files are written:

    npx @better-auth/cli@latest generate
    npx drizzle-kit generate
    npx drizzle-kit migrate
    

    These commands replace the placeholder db/schema/auth.ts with the real schema and apply migrations.

  5. Print next steps. Tell the user to:

    • Fill in .env.local (copy from .env.example)
    • Generate a secret: openssl rand -base64 32
    • Register OAuth redirect URIs with each provider console (for social/advanced presets)
    • Implement lib/email.ts to wire transactional email (for advanced preset)

Conventions

Read references/conventions.md for the rationale behind every convention these templates encode. Highlights:

  • lib/auth.ts is server-only (import "server-only")
  • nextCookies() is ALWAYS the last plugin in the array
  • Middleware does a cookie-presence check only; real validation in pages
  • All secrets via process.env.*, never inline
  • Sliding-window sessions with cookieCache enabled

Related Skills

  • better-auth — Library/API Reference with 42 rules covering setup, sessions, security, plugins, and migration. The templates here are one canonical realization of those rules; read the rule for the underlying reasoning when you need to deviate.

Gotchas

See gotchas.md — initialized empty, populated as we discover them.

Comments

Markdown supported