22

I kept asking for "a Next.js SaaS starter" and getting a pile of files that referenced components that didn't exist, mixed the pages and app routers, and threw 40 type errors on first pnpm build.

The fix was to make the model commit to a file tree first, then generate every file in that tree and nothing outside it, and to end with a self-check that it re-reads its own imports. Zero-error builds went from never to almost always.

Anyone found a cleaner way to stop it from inventing a @/components/ui/* import for a component it never wrote?

THE PROMPT
You are scaffolding a production Next.js 14 project using the App Router and TypeScript in strict mode. Follow this contract exactly.

STACK: Next.js 14 (app/), React 18, TypeScript strict, Tailwind, no other UI libraries unless you also generate the component.

STEP 1 - Print the complete file tree first as a tree diagram. Nothing outside this tree may be imported. Include: app/layout.tsx, app/page.tsx, app/(marketing)/, app/(app)/dashboard/page.tsx, components/, lib/, and types/.

STEP 2 - Generate every file in the tree, in tree order, as separate fenced blocks with the path as the first comment line.

RULES:
- Every import must resolve to a file you actually emit. Do NOT import from '@/components/ui/*' unless you write that file.
- No `any`, no `@ts-ignore`, no `as unknown as`. Model all props with explicit interfaces in types/.
- Async server components must handle the error and empty states, not just the happy path.
- No pages/ directory, no getServerSideProps.

STEP 3 - Self-check: list every import across all files and confirm each one resolves to an emitted file. If any does not, fix it before finishing.

CONSTRAINT: The output must build with `next build` and zero type errors. State that constraint back to me and treat it as a hard gate.
3the self-check step is underrated. i started asking for it in every scaffold prompt and my first-build error count dropped hard.shipittoprod 1 month ago
add a comment

2 Answers

13

The "file tree first, nothing outside the tree" rule is doing most of the work here. The one thing I add for the phantom-import problem: force it to emit a components/index.ts barrel and require every component to be re-exported there. If it wants to import something, it has to appear in the barrel, and it's very obvious when it invents one that was never written.

THE PROMPT
Add: emit components/index.ts that re-exports every component you generate. All component imports must go through '@/components' and resolve to an entry in this barrel. Before finishing, diff the barrel against the files you actually wrote.
10

Works, but strict mode without noUncheckedIndexedAccess still lets it write arr[0].name and feel safe. I bumped the constraint to "tsconfig must set strict, noUncheckedIndexedAccess, and exactOptionalPropertyTypes, and the code must pass under all three." Caught two real bugs in the generated data layer on the first run.

Your Answer