Nextjs bootstrap
Skill vipincode/exr-agent-skills/.claude/skills/nextjs-bootstrap
Agent Skills for building production-grade Express + TypeScript + Mongoose backends with Claude Code
npx -y skills add vipincode/exr-agent-skills --skill nextjs-bootstrapAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Scaffold a new production-grade Next.js (App Router) + TypeScript + Tailwind + shadcn/ui frontend from scratch, wired to a separate API backend (e.g. Express) via a BFF proxy, with axios, Zod, TanStack Query, and React Hook Form. Use this whenever the user wants to start a new Next.js / React frontend, bootstrap a web client/UI, set up a shadcn starter, or initialize a frontend project — even if they only say "new frontend", "Next.js starter", "React app", "admin dashboard UI", or name the stack loosely. It scaffolds the infrastructure ONCE per project and emits the two source-of-truth files (ARCHITECTURE.md and MODULE_REGISTRY.md) that the future frontend-* skills depend on. Do NOT use this to add a feature/page to an existing project (that is frontend-feature-planner + frontend-module-builder) or to write tests. This scaffolds a Next.js + React frontend specifically — do NOT use it to bootstrap a backend/API (that is express-ts-bootstrap) or projects in other frontend stacks (Vite/CRA/Remix/Vue/Svelte/Angular); those are out of scope.
SKILL.md
17.4 KB, as published. Nobody here has run it
nextjs-bootstrap
Scaffold a runnable, production-grade Next.js (App Router) + TypeScript + Tailwind + shadcn/ui frontend that talks to a separate API backend through a BFF proxy, and — critically — emit ARCHITECTURE.md and MODULE_REGISTRY.md. Those two files are the shared memory that lets the future frontend skills (frontend-feature-planner, frontend-module-builder, frontend-test-writer, frontend-code-review, plus net-new ones like font-theme-setup, api-binder, ux-designer) avoid re-asking decisions and stop generating duplicate components. Getting them right matters more than the boilerplate.
This skill runs once per project. It does NOT build feature pages (auth screens, dashboards with real data, CRUD) — it lays the foundation: the BFF/auth wiring, the DRY shared form + typography components, the data-fetching and HTTP plumbing, and a role-based routing skeleton, so later skills have concrete patterns to copy.
This is the frontend twin of express-ts-bootstrap. It mirrors that skill's philosophy: infrastructure once, decisions once, a seeded registry so nothing gets built twice. Read ../NAMING.md and ../LAYOUT.md for how it coexists with a backend in one repo.
Stack (fixed)
Use latest for everything — this stack moves fast, so confirm current APIs with context7 before generating (see references/stack-context7.md). The bundled boilerplate is written against current stable APIs; if context7 shows an API has changed, follow context7, not the bundled snapshot.
- Next.js (App Router,
src/dir, TypeScript strict, import alias@/*). Role-based routing lives insrc/proxy.ts(Next 16+ renamed the deprecatedmiddleware.ts→proxy.ts, functionmiddleware→proxy; on Next ≤15 usemiddleware.ts/middleware— same body). Server-to-backend calls go through Route Handlers underapp/api/(the BFF). Treatcookies()/headers()as async. - React 19 with Server and Client Components. Shared interactive components are Client Components (
"use client"). - Tailwind CSS (v4, CSS-first config via
@import "tailwindcss"and@theme). Deep theme/font customization is intentionally deferred to a futurefont-theme-setupskill — ship sensible shadcn defaults here. - shadcn/ui — primitives live in
src/components/ui/, added via the shadcn CLI. They usecva. Never hand-author or duplicate auiprimitive; compose it. - axios — one configured instance in
src/lib/axios.ts, same-originbaseURL: "/api"(it hits the BFF, never the backend directly from the browser). - Zod 4 — validation. Root import
import * as z from "zod", top-level formats (z.email()),z.treeifyError(). - T3 Env (
@t3-oss/env-nextjs, https://env.t3.gg) — the only way env is defined.src/lib/env.tscallscreateEnvwithserver/clientschemas; it enforces the server/client split so secrets can't leak into the browser. No rawprocess.envreads anywhere else. This is a strict rule for every frontend skill. - TanStack Query v5 — server-state. One
QueryClient(src/lib/query-client.ts), aProvidersclient component, query/mutation hooks live in feature/service folders. - React Hook Form 7 +
@hookform/resolvers(Zod resolver) — all forms. Fields are never wired by hand; they use the shared*Fieldcomponents insrc/components/shared/form/.
Decision gate (ask ONLY these)
The whole point of this toolkit is to not interrogate the user. Ask exactly three questions, with defaults, then proceed. Everything else is a baked-in production default.
- Project name — always ask; there is no default. Get a short kebab-case name (e.g.
shoply,crm-portal) and scaffold into afrontend-<name>/subfolder (e.g.frontend-shoply/). The name-suffixed folder is deliberate: when the folder is later pushed as its own git repo,frontend-shoplyis self-describing where a barefrontendis not. If a backend already exists in this repo (check.claude/workspace.jsonfor abackendentry, or abackend-*folder), reuse its name suffix so the pair readsbackend-<name>/frontend-<name>..claude/stays at the repo root as the shared anchor. Scaffold into the repo root only if the user explicitly asks for that. This sets the project dir and is recorded in.claude/workspace.json. See../LAYOUT.md. - Package manager — pnpm / npm / bun. Default pnpm.
- Auth token strategy — how tokens flow between the backend and this app. Default (a). Offer:
- (a) Body → cookies: backend returns
accessToken+refreshTokenin the JSON body; a Next.js Route Handler sets them as httpOnly cookies. (default) - (b) Backend sets cookies: the backend already sets httpOnly cookies on login; Next just forwards/proxies them.
- (c) Header / client-stored: tokens kept client-side and sent via
Authorizationheader by an axios interceptor. Less secure; offer but note the tradeoff. - + Refresh rotation (yes/no): add an interceptor + Route Handler that silently refreshes the access token on a 401. Layers on top of (a)/(b)/(c). Default yes.
- (a) Body → cookies: backend returns
The backend connection is always a BFF proxy (Route Handlers under app/api/ forward to the backend; the browser only ever calls same-origin /api). Don't offer direct-to-backend — it leaks the backend URL and tokens into the browser.
Roles default to admin and user (→ /admin, /user) via an editable map in src/lib/auth/roles.ts. Mention it's extensible; don't interrogate. If the user already named roles/dashboards earlier in the conversation, use them.
If the user already stated any of these earlier, do not re-ask — use it.
Workflow
All paths below are relative to the resolved project dir (
<proj>= thefrontend-<name>/subfolder, or the repo root if explicitly chosen)..claude/and.claude/workspace.jsonalways stay at the repo root. See../LAYOUT.md.
Unlike the backend scaffolder (pure file copy), this skill is hybrid: run the official CLIs, then overlay our files. The CLIs own framework + ui primitives; we own everything in lib/, proxy.ts (role routing), the BFF/auth, and components/shared/.
- Resolve decisions. Apply the decision gate. Confirm the resolved set in one line before scaffolding (e.g. "Next.js App Router, pnpm, body→cookies + refresh rotation, in
frontend-shoply/— scaffolding now."). Create<proj>if needed. - Confirm current APIs via context7 for Next.js, shadcn, TanStack Query, React Hook Form, Zod, and Tailwind. See
references/stack-context7.mdfor the exact libraries/topics. This guards against the bundled snapshots having drifted. - Run
create-next-app@latestinto<proj>: TypeScript, App Router, Tailwind,src/dir, import alias@/*, ESLint. (Use the non-interactive flags so it doesn't prompt.) - Init shadcn (
shadcn@latest init) and add the primitives the shared components need: at minimumbutton label input textarea select checkbox radio-group switch field popover command calendar badge dialog sonner(dialogbacks the sharedModaloverlay wrapper). These land insrc/components/ui/. Notes on current shadcn:initis interactive — drive it non-interactively with-t next -b radix -p nova(it now asks for a component-library base (radix/base) and a preset (nova/…)). If a registry fetch fails with a TLS "unable to verify the first certificate" error, re-run the CLI withNODE_OPTIONS="--use-system-ca". Modern shadcn ships a form-library-agnosticfieldprimitive (Field/FieldLabel/FieldDescription/FieldError) — there is no RHF-boundformcomponent anymore, so our shared fields bind React Hook Form themselves viauseController.popover+command+badgeback MultiSelect/Combobox;calendarbacks DateField. - Install the data/form/HTTP/env deps with the chosen PM:
axios @tanstack/react-query @tanstack/react-query-devtools react-hook-form @hookform/resolvers zod @t3-oss/env-nextjs server-only. (@t3-oss/env-nextjsbackslib/env.ts;server-onlyguardslib/auth/session.tsfrom being bundled into client code.) Also install husky (v9+) and lint-staged as devDependencies and wire pre-commit checks: add"prepare": "husky || true"to scripts and a"lint-staged": { "*.{ts,tsx,js,jsx}": "eslint --fix" }config inpackage.json(the hook file itself ships inassets/files/.husky/pre-commitand is overlaid in step 6). Every scaffold ships with working git hooks — that's part of the boilerplate contract. See the "Git hooks" section ofreferences/conventions-core.md, including the adjusted form when<proj>is a subfolder of the git root (e.g.frontend-shoply/in a monorepo). - Overlay
assets/files/src/into<proj>/src/—lib/,proxy.ts(role routing), the BFF routes,components/shared/(form/,typography/,overlay/with theModalwrapper),providers.tsx, and.env.example+.husky/pre-commitinto<proj>. Wire<Providers>intoapp/layout.tsx. (On Next ≤15, rename the overlaidproxy.ts→middleware.tsand itsproxyexport →middleware.) Readreferences/form-fields.md,references/typography-cva.md, andreferences/module-structure.mdfirst so the shared components match the installeduiprimitives and the folder rules exactly. - Generate the chosen auth/token variant. The overlay ships variant (a) by default; for (b)/(c) or no-refresh, rewrite
lib/auth/session.ts,lib/auth/tokens.ts,app/api/auth/login/route.ts, and the axios interceptor perreferences/auth-bff.md. The BFF proxy +proxy.tsrole logic are the same across variants. - Generate
ARCHITECTURE.mdfromassets/ARCHITECTURE.template.md, filling every{{placeholder}}with the resolved decisions and the actual conventions fromreferences/conventions-core.md. Every other frontend skill reads this before writing code — it must be concrete, not aspirational. - Generate
MODULE_REGISTRY.mdfromassets/MODULE_REGISTRY.template.md. Seed it with what the scaffold ships: every shared*Field, the typography primitives, the sharedModaloverlay wrapper, thelib/utilities (axios, query-client, env, auth/session, auth/roles, auth/tokens), the BFF proxy route,proxy.ts(role routing), and the actual list ofuiprimitives you added. This is the dedup ledger; if a shared piece exists, it must be listed so later skills reuse it. - Record the project in the workspace manifest. Create or update
.claude/workspace.jsonat the repo root with{ "domain": "frontend", "path": "<proj relative to repo root, e.g. 'frontend-shoply', or '.'>", "stack": "nextjs" }. If the file exists, merge — never clobber abackendentry. See../LAYOUT.md. - Install, build, and smoke-check. Run
<pm> install, then<pm> run build(must pass typecheck + lint), then a quick<pm> run devcheck that/renders and a protected route redirects perproxy.ts. Confirm the husky hook installed (.husky/pre-commitpresent and gitcore.hooksPathset). Report the result.
What to read when
references/conventions-core.md— the canonical conventions (project layout, component placement rules, form pattern, data-fetching, naming, DRY rules). This is the substance distilled into the generated ARCHITECTURE.md. Read before generating ARCHITECTURE.md.references/module-structure.md— the strict feature-module anatomy (types/constants/hooks/api/schema/components/template) and the shared-vs-feature component rule + the shared-component taxonomy. Read before overlayingcomponents/shared/and before generating ARCHITECTURE.md; these rules bind every future frontend skill.references/auth-bff.md— the BFF proxy,proxy.tsrole routing, and all four token strategies with the exact files each one changes. Read before generating the auth wiring (step 7).references/form-fields.md— how each shared*Fieldis built (RHFuseController+ shadcn'sFieldprimitive +cvavariants) and whichuiprimitive each needs. Read before overlayingcomponents/shared/form/.references/typography-cva.md— theText/Heading/Labelcvacomponents and the "extend, don't duplicate shadcn" rule. Read before overlayingcomponents/shared/typography/.references/stack-context7.md— which context7 libraries/topics to query for current APIs (step 2).assets/files/— the literal boilerplate overlaid into<proj>/src(lib, middleware, BFF, shared components).assets/ARCHITECTURE.template.md/assets/MODULE_REGISTRY.template.md— templates for the two source-of-truth docs.
Non-negotiables (the reasons this toolkit exists)
- shadcn primitives are sacred. They live in
src/components/ui/, come from the CLI, and are never hand-duplicated. App-level reusable components live insrc/components/shared/. If you need a variant of a primitive, compose or extend it — a forkedButton2or a re-implementedSelectis a bug, while adding/re-valuing variants in the primitive's owncvaconfig (to match a design system, a later theming skill's job) is the sanctioned edit. (This is the answer to "buttons already have variants": don't redo them; buildText/Headingas new typography primitives and letLabel/Buttonkeep their own.) - One home per component, decided by dependency (strict). A component that is generic / domain-agnostic — wrappers, boxes, layout containers, modal wrappers (a shadcn-Dialog wrapper that takes only inner content), cards, chips, tags, badges — lives in
src/components/shared/(grouped by purpose:form/,typography/,overlay/,layout/,data-display/, …). A component that depends on a single feature's domain lives insrc/features/<name>/components/and stays there until a second feature needs it (then it moves tosharedand gets registered — never copied). The bootstrap shipsoverlay/Modalas the canonical shared example. Seereferences/module-structure.md. - Features are self-contained modules (strict). Each domain is one folder
src/features/<name>/with a fixed anatomy —types/,constants/,hooks/,api/,schema/,components/(feature-only components), andtemplate/(full composed screens like login/register;page.tsxfiles stay thin and render a template). A feature never cross-imports another feature; shared needs go tocomponents/shared/lib/hooks/services. This binds every future frontend skill. - Env is T3 Env, nowhere else.
lib/env.tsis the singlecreateEnvdefinition (@t3-oss/env-nextjs); it enforces the server/client split. No rawprocess.envreads in app code. Server-only secrets (backend URL, cookie names/secret) get noNEXT_PUBLIC_prefix; browser values do and are mirrored inexperimental__runtimeEnv. - Every form field goes through a shared
*Field. No bare<Controller>+<Input>wiring scattered in pages. The*Fieldcomponents are the single definition of field UI + validation display, so forms stay consistent and later skills reuse them. - The browser never calls the backend directly. All calls go through the same-origin BFF (
/api/...Route Handlers). Tokens live in httpOnly cookies (variants a/b) handled server-side; the backend URL stays a server secret. A browseraxioscall with the backend's absolute URL is a bug. - One HTTP instance, one QueryClient.
lib/axios.tsandlib/query-client.tsare the only places these are constructed. Per-feature hooks import them. - Seed the registry honestly. Every reusable thing the scaffold creates goes into
MODULE_REGISTRY.mdimmediately — including the exactuiprimitives installed. An empty or inaccurate registry defeats the dedup workflow and duplicates come right back. - Git hooks work out of the box.
.husky/pre-commit+ lint-staged ship with the scaffold and install on firstinstallvia thepreparescript. If the project dir isn't the git root, use the subfolder form from conventions-core — don't ship a hook that silently never runs. - Record the project location. The
.claude/workspace.jsonfrontendentry is mandatory and must merge with anybackendentry — without it, later skills can't find a project scaffolded intofrontend-<name>/. - Don't scaffold features. Real dashboards, auth screens, CRUD pages are out of scope here. Stop at infrastructure + shared components + a routing skeleton.
- Latest, verified. Don't pin fragile versions from memory; install latest and confirm fast-moving APIs via context7 (step 2).