This skill should be used when the user asks to "create a new project", "scaffold a Next.js app", "initialize a new app", "start a new project", "set up a new Next.js project", or mentions "create-next-project". Provides a guided, opinionated full-stack Next.js project initialization with Biome, Tailwind v4, shadcn/ui, better-auth, and Vercel deployment. Uses agent teams for parallel execution.
From bopen-toolsnpx claudepluginhub b-open-io/claude-plugins --plugin bopen-toolsThis skill uses the workspace's default tool permissions.
references/auth-setup.mdreferences/layout-architecture.mdreferences/stack-defaults.mdreferences/tanstack-query-setup.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Guided full-stack Next.js project scaffolding. Six interactive steps that scaffold, configure, and deploy a production-ready app using agent teams for parallel execution.
src/ directoryuseQuery/useMutation for all client data. NO TanStack Query needed.BEFORE any work, invoke these skills to load guidance into context:
Skill(vercel-react-best-practices) - React/Next.js optimization rulesSkill(vercel-composition-patterns) - Component composition patternsSkill(better-auth-best-practices) - Auth integration patternsApply their guidance throughout all steps.
This step gets the bare project on disk and into version control.
If the target directory already has files (e.g., a .claude/ directory), move them to /tmp first, scaffold, then move them back.
bunx create-next-app@latest <project-name> \
--typescript --tailwind --app --src-dir \
--import-alias "@/*" --use-bun --turbopack --yes
cd <project-name>
create-next-app does NOT have a --biome flag. It installs ESLint by default.
bun remove eslint eslint-config-next
rm -f eslint.config.mjs
bun add -d @biomejs/biome
Create biome.json -- see references/stack-defaults.md for the exact config. Key Biome 2.x rules:
organizeImports goes under assist.actions.source (not the old top-level key)files.ignore. Use negation patterns in files.includes (e.g., "!src/components/ui")/** (since Biome 2.2.0). Just "!foldername"vcs.useIgnoreFile: true respects .gitignore so .next/ and node_modules/ are auto-excludedcss.parser.tailwindDirectives: true is required for Tailwind v4Update package.json scripts:
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "biome check .",
"lint:fix": "biome check --write ."
}
}
Auto-fix all files:
bunx biome check --write .
git init
bun run build
bun run lint
git add .
git commit -m "Initial Next.js scaffold with Biome"
Prompt the user with 3 options:
gh org list, ask the user which one, then run gh repo create <org>/<name> --private --source=. --remote=origin (do NOT push yet). Never guess the org name from conversation -- always look it up.git remote add origin <url> (do NOT push yet)IMPORTANT: Do NOT push to GitHub yet. Pushing triggers a Vercel deploy, and the deploy will fail if the database isn't provisioned. The first push happens in Step 6 after all infrastructure is set up.
Now that the scaffold exists, gather ALL requirements in one round. Use AskUserQuestion with multiple questions.
Auth methods (multi-select):
Database:
Optional packages (multi-select):
@ai-sdk/openai + ai - AI/agent features@bsv/sdk - BSV blockchain@1sat-lexi/js - 1Sat Ordinals@1sat/connect + @1sat/react - 1Sat wallet integrationclawnet - ClawNet agent platformresend - Transactional emailTheme: "Pick a preset (nova, vega, maia, lyra, mira), create a custom one at ui.shadcn.com/create, or pick a theme at tweakcn.com and paste the registry URL."
Skills to reference in CLAUDE.md (multi-select from installed plugins):
vercel-react-best-practices and vercel-composition-patternsRecord all answers -- they inform the research agents and build team.
Send parallel research agents (using the Task tool with run_in_background: true) to gather context for each build workstream. Each agent reads relevant source code, docs, or skills so the build agents have everything they need.
Research Agent 1: UI + Layout
references/layout-architecture.md and references/stack-defaults.mdResearch Agent 2: Auth
references/auth-setup.mdSkill(sigma-auth:setup-convex) or Skill(sigma-auth:setup-nextjs)@convex-dev/better-auth adapter patternResearch Agent 3: Data Layer
Skill(convex-best-practices), read Convex schema patternsreferences/tanstack-query-setup.mdResearch Agent 4: Optional Packages (only if user selected packages)
Wait for all research agents to complete before Step 4.
Create an agent team (using TeamCreate) with specialized agents. Provide each agent with FULL context from Step 2 answers and Step 3 research results.
Agent 1: UI + Layout + Theme (Phases 2-3) Responsibilities:
bunx shadcn@latest init --preset nova --yes (or use the user's chosen preset from Step 2)--preset <code> instead# If user chose Base UI instead of Radix
bunx shadcn@latest init --base base --preset nova --yes
bunx shadcn@latest add dashboard-01bun add next-themesreferences/stack-defaults.md)references/layout-architecture.md)src/app/dashboard/ (dead route from dashboard-01 block)(app)/, (auth)/bun run build and bun run lint to verify"Add UI foundation and layout architecture"Agent 2: Data Layer (Phase 4) Responsibilities depend on database choice:
If Convex:
bun add convexbunx convex init (creates convex/ directory)convex/_generated/ stub files so build passes pre-deployment (see Convex Stubs section below)convex/schema.ts based on project needssrc/components/convex-provider.tsxbun run build to verify"Add Convex data layer"If other databases:
bun add @tanstack/react-querybun add -d @tanstack/react-query-devtoolsreferences/tanstack-query-setup.md)bun run build to verify"Add data layer"Agent 3: Auth (Phase 5 -- depends on Agent 2 completing first if Convex) Responsibilities:
bun add better-authbun add @convex-dev/better-auth + create convex/convex.config.tsbun add @sigma-auth/better-auth-pluginbunx shadcn@latest add login-05 signup-05convex/auth.ts or src/lib/auth.ts)src/lib/auth-client.ts)src/app/api/auth/[...all]/route.ts) -- use lazy initialization pattern for Convexbun run build to verify"Add authentication"Agent 4: Config + Optional Packages (Phase 6-7) Responsibilities:
.claude/CLAUDE.md with project conventions, commands, selected skills.env.vercel with ALL env vars the project needs (see .env.vercel section below).gitignore exception for .env.vercelbun run build and bun run lint final check"Add project configuration and optional packages"Every agent MUST receive:
bun run build and bun run lint before committingAfter all agents complete and the build passes locally, provision the database BEFORE the first deploy. Deploying without a database creates broken deployments and can cause duplicate/disconnected database instances.
STOP and instruct the user to do this themselves. The agent should NOT create the Vercel project. The user needs to:
- Go to vercel.com/new
- Select the correct team/org
- Import the GitHub repo
- Import the
.env.vercelfile (Settings > Environment Variables > Import .env) and fill in any empty values- Do NOT deploy yet -- add storage first (Step 5b)
Wait for the user to confirm they've done this before proceeding.
STOP and instruct the user to do this themselves. The user needs to:
Go to the Vercel project dashboard > Storage > Add > select your database
After the user confirms the Vercel project exists and storage is added, link the local project. Never guess the team slug -- look it up:
bunx vercel teams list
Ask the user which team from the list, then link with the exact slug:
bunx vercel link --yes --scope <team-slug>
Confirm it linked to the correct project.
After linking, pull the env vars that Vercel and the storage integration set automatically:
vercel env pull
This creates .env.local with all env vars from the Vercel project. At this stage the expected state is:
CONVEX_DEPLOY_KEY -- present (auto-set by the Convex Vercel integration)NEXT_PUBLIC_CONVEX_URL -- missing (this gets set after bunx convex dev connects the local project to the Convex deployment in Step 5e).env.vercel -- presentThis is normal. Do not treat the missing NEXT_PUBLIC_CONVEX_URL as an error.
Always provision Convex through the Vercel Marketplace integration (Step 5b). Never create a standalone Convex project separately -- the Vercel integration automatically connects deploy keys, handles preview deployments, and syncs env vars. Setting up Convex outside the marketplace when deploying to Vercel creates disconnected projects and manual sync headaches.
After Vercel Storage adds Convex, the dashboard shows a 4-step setup guide. Walk the user through it:
Convex Step 1: Connect to the Convex CLI
bunx convex login --vercel
This authenticates the CLI with the Vercel-managed Convex team.
Convex Step 2: Link local project to Convex deployment
We already have convex/ with schema and functions. Skip npm create convex@latest. Run:
bunx convex dev
Follow the prompts to "Choose an existing project" and select the project from the Vercel-managed Convex team. This:
convex/_generated/ files (replacing the stubs)NEXT_PUBLIC_CONVEX_URL to .env.localKeep convex dev running in its own terminal during development. It continuously syncs your convex/ code to the dev deployment.
Convex Step 3: Connect Convex project to Vercel project
This may already be done by the Vercel Storage integration. If not, in the Convex dashboard, connect to the Vercel project. This syncs CONVEX_DEPLOY_KEY to Vercel automatically.
IMPORTANT: Enable both "Production" and "Preview" environments. Keep the "Custom Prefix" field empty.
Convex Step 4: Override the Vercel build command
In Vercel project Settings > Build and Deployment, override the build command:
bunx convex deploy --cmd 'bun run build'
This is critical: convex deploy pushes functions/schema to the production Convex deployment, then runs bun run build which builds the Next.js frontend with NEXT_PUBLIC_CONVEX_URL pointing at production.
Set Convex server-side env vars:
Convex has its own environment variables separate from Vercel. These are set via the Convex CLI and are available inside Convex functions (actions, mutations, etc.).
CRITICAL: bunx convex env set targets the DEV deployment by default, NOT production. Always use --prod for production vars:
# Production (deployed app)
bunx convex env set SITE_URL "https://your-domain.com" --prod
bunx convex env set BETTER_AUTH_SECRET "$(openssl rand -hex 32)" --prod
# Dev (local development) -- same vars, different values
bunx convex env set SITE_URL "http://localhost:3000"
bunx convex env set BETTER_AUTH_SECRET "dev-secret-change-me"
Without --prod, you are ONLY setting vars on the dev deployment. Your production app will have missing env vars and fail silently or throw errors. This mismatch is a common source of hours-long debugging sessions.
Commit the generated files:
After convex dev runs, commit the real convex/_generated/ files:
git add convex/_generated/
git commit -m "Add Convex generated files from dev deployment"
These should be checked in so teammates can type-check without running convex dev.
Provision via Vercel Storage or CLI:
turso db create <name> turso db show <name> --url # TURSO_DATABASE_URL turso db tokens create <name> # TURSO_AUTH_TOKENSet both on Vercel.
Add via Vercel Storage (Neon) or use an external provider (Supabase, Railway). Set
DATABASE_URLon Vercel.
Local development only. No provisioning needed. Uses
./dev.db.
Now that the database is provisioned and env vars are set, push to trigger the first deploy:
git push -u origin main
Or if the user hasn't set up a GitHub remote yet, list orgs with gh org list, ask the user which one, then:
gh repo create <org>/<name> --private --source=. --remote=origin --push
The Vercel deploy will:
bunx convex deploy --cmd 'bun run build' (per the build override)convex deploy pushes functions/schema to the production Convex deploymentconvex deploy sets NEXT_PUBLIC_CONVEX_URL to the production URLbun run build builds the Next.js app pointing at production ConvexTwo terminals, always:
# Terminal 1: Convex dev server (watches convex/ and pushes to DEV deployment)
bunx convex dev
# Terminal 2: Next.js dev server (uses NEXT_PUBLIC_CONVEX_URL from .env.local pointing at DEV)
bun dev
convex dev continuously:
convex/_generated/ typesYour local Next.js app (via bun dev) connects to the dev Convex deployment. The production app connects to the production deployment. They have separate data, separate env vars, and separate function code.
| Dev deployment | Production deployment | |
|---|---|---|
| Connected by | bunx convex dev | bunx convex deploy (Vercel build) |
| URL in | .env.local | Set automatically by convex deploy during build |
| Env vars set with | bunx convex env set VAR val | bunx convex env set VAR val --prod |
| Data | Separate (dev data) | Separate (production data) |
| Schema pushed by | convex dev (on save) | convex deploy (on Vercel build) |
| When to use | Local development | Deployed app |
After first deploy completes:
Create a .env.vercel file committed to the repo with ALL env vars the project needs. Known defaults are pre-filled; unknowns are left empty. Add a .gitignore exception:
# env files
.env*
!.env.vercel
Example .env.vercel:
# Vercel Environment Variables
# Import this file into Vercel: Settings > Environment Variables > Import .env
# Values marked with comments must be filled in during setup
# Database (Convex example)
# IMPORTANT: NEXT_PUBLIC_CONVEX_URL = .convex.cloud (client SDK)
# IMPORTANT: NEXT_PUBLIC_CONVEX_SITE_URL = .convex.site (auth proxy destination)
# These are DIFFERENT URLs! Do NOT set SITE_URL to your app domain.
NEXT_PUBLIC_CONVEX_URL=
NEXT_PUBLIC_CONVEX_SITE_URL=
CONVEX_DEPLOY_KEY=
# Auth
BETTER_AUTH_SECRET=
# OAuth (if selected)
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# Sigma Auth (if selected)
NEXT_PUBLIC_SIGMA_CLIENT_ID=your-app-name
NEXT_PUBLIC_SIGMA_AUTH_URL=https://auth.sigmaidentity.com
Only include env vars for features the user actually selected.
When using Convex, the convex/_generated/ directory does not exist until bunx convex dev runs. Create stub files so bun run build passes pre-deployment:
convex/_generated/api.d.ts:
import type { AnyApi } from "convex/server";
declare const api: AnyApi;
declare const internal: AnyApi;
export { api, internal };
convex/_generated/api.js:
import { anyApi } from "convex/server";
export const api = anyApi;
export const internal = anyApi;
convex/_generated/server.d.ts:
export {
action,
httpAction,
internalAction,
internalMutation,
internalQuery,
mutation,
query,
} from "convex/server";
convex/_generated/server.js:
export {
action,
httpAction,
internalAction,
internalMutation,
internalQuery,
mutation,
query,
} from "convex/server";
convex/_generated/dataModel.d.ts:
import type { GenericDataModel } from "convex/server";
export type DataModel = GenericDataModel;
Important: If using @convex-dev/better-auth or other Convex components, the api.d.ts stub must also export components:
import type { AnyApi } from "convex/server";
declare const api: AnyApi;
declare const internal: AnyApi;
declare const components: Record<string, AnyApi>;
export { api, internal, components };
import { anyApi } from "convex/server";
export const api = anyApi;
export const internal = anyApi;
export const components = { betterAuth: anyApi };
These stubs get overwritten on first bunx convex dev.
Missing _generated/ stubs -- bunx convex init without a deployment does not create convex/_generated/. Create stub files (see above) so the build passes before first deployment.
Missing convex.config.ts -- required when using Convex components like @convex-dev/better-auth. Without it, the component is not registered and Convex fails at deploy time:
import betterAuth from "@convex-dev/better-auth/convex.config";
import { defineApp } from "convex/server";
const app = defineApp();
app.use(betterAuth);
export default app;
Auth handler eager initialization -- convexBetterAuthNextJs() throws at import time if env vars are missing. Use the lazy initialization pattern (see references/auth-setup.md).
Circular type references in cron jobs -- when convex/crons.ts references internal.someModule.someAction, and that module's return type depends on the internal type, TypeScript gets a circular reference. Fix by adding explicit return type annotations to action handlers referenced by crons.
Env var mismatch: dev vs production -- bunx convex env set targets the dev deployment by default. Always use --prod for production: bunx convex env set VAR_NAME "value" --prod.
NEXT_PUBLIC_CONVEX_SITE_URL must be .convex.site, NOT the app domain -- The auth proxy (convexBetterAuthNextJs) forwards /api/auth/* requests to this URL. If it points to your app domain (e.g., https://myapp.com), the proxy loops back to itself causing infinite redirects. Must be https://<deployment>.convex.site.
NEXT_PUBLIC_CONVEX_URL must be set on Vercel -- This env var (https://<deployment>.convex.cloud) is NOT auto-set by the Convex Vercel integration. You must add it manually to Vercel env vars, or pull it after vercel env pull. Without it, the production app has no Convex connection.
Convex functions not deployed to production -- bunx convex dev only pushes to the dev deployment. For production, run bunx convex deploy --yes. Without this, your production Convex deployment has no functions, queries, or HTTP actions.
Sigma SIGMA_MEMBER_PRIVATE_KEY must be on Convex prod -- This WIF key is required for server-side OAuth token exchange. Without it on production (bunx convex env set SIGMA_MEMBER_PRIVATE_KEY "..." --prod), sign-in silently fails.
bun, bunx for everythingcreate-next-app does NOT have a --biome flag. Remove ESLint, install Biome, create biome.json manuallyassist.actions.source.organizeImports, negation patterns in files.includes (no files.ignore), css.parser.tailwindDirectives: trueprocess.env.FOO!. Always validate env vars and throw informatively:
// WRONG
const url = process.env.DATABASE_URL!;
// RIGHT
const url = process.env.DATABASE_URL;
if (!url) throw new Error("DATABASE_URL environment variable is required");
useQuery/useMutation from convex/react. Do NOT install TanStack Query.create-next-app, shadcn, biome, vercel, gh CLIs--dry-run and --diff when iterating on component additions to preview changes before applying@latest for all installationsbun run build at every commit checkpointTeamCreate to parallelize Phases 2-7. Provide each agent thorough context since they lack conversation history.references/stack-defaults.md -- Exact configs for Biome, theme provider, Tailwind, shadcnreferences/layout-architecture.md -- Single-layout pattern with navbar and route-based contentreferences/auth-setup.md -- better-auth setup per provider (email, OAuth, Sigma, passkeys)references/tanstack-query-setup.md -- Provider setup, custom hooks (for non-Convex projects only)vercel-react-best-practices -- React/Next.js optimization rulesvercel-composition-patterns -- Component composition for scalable appsfrontend-design -- UI design avoiding generic aestheticsbetter-auth-best-practices -- Auth integration patternsconvex-best-practices -- Convex patterns (when using Convex)sigma-auth:setup-convex -- Sigma auth with Convexsigma-auth:setup-nextjs -- Sigma auth with Next.js (non-Convex)