I Built a 'Production-Ready' NestJS API Almost Without Writing Code by Hand

16-07-2026 β€’ 5 min read

I Built a 'Production-Ready' NestJS API Almost Without Writing Code by Hand

Every new backend starts with the same tedious checklist.

Connect the database.

Wire up authentication.

Protect the endpoints.

Log in a format that's actually useful.

Validate the configuration.

Write the first tests.

None of this is hard. All of it takes time. And none of it defines the product you're actually building β€” it's the toll you pay before you can start.

A few weeks ago I decided to build that foundation, fully working end-to-end, almost without writing code by hand. Instead, I wrote prompts.

This wasn't "throw something at the AI and hope for the best." It was architecture, translated into instructions.


🧱 The Stack, Assembled Through Prompts

The result was a NestJS API foundation with:

  • πŸ”Ή Prisma + Postgres for the data layer.
  • πŸ”Ή Better Auth for authentication, integrated by following its own NestJS documentation.
  • πŸ”Ή Arcjet for protection β€” rate limiting, bot detection, and shield in the same layer.
  • πŸ”Ή Pino for structured logging, not loose strings printed to a console.
  • πŸ”Ή Zod to validate environment configuration before the app even starts.
  • πŸ”Ή The core tests, covering the real flow, not just the obvious happy path.

All of it working end-to-end. All of it documented β€” code and the exact prompts β€” in a public repo.

πŸ‘‰ The goal wasn't "see how fast AI can generate code." It was to see whether it could hold up real architectural decisions, prompt after prompt, without the result falling apart.


🎯 Specific Prompts, Not Generic Ones

The difference between "ask AI to build a backend" and what I actually did here comes down to specificity. Every prompt carried clear rules, not a vague description of what "would be nice to have."

A few examples, exactly as they're documented in the repo:

"/architect read https://better-auth.com/llms.txt/docs/integrations/nestjs.md and the better-auth skill before writing anything"

Before touching any code, the AI had to read the official integration docs. Not guess the NestJS pattern based on what it already knew from other frameworks.

"Create a global response intereceptor that wraps every response in .

-Support a @ResponseMessage decorator for custom messages, defaulting to Success. -Wire it globally in main.ts."

Explicit response contract. Explicit default behavior. Explicit integration point.

"Install class-validator and class-transformer.

-Set up the global ValidationPipe in main.ts that returns a clean validation errors as an array of objects using BadRequestException."

Explicit error shape, explicit exception, explicit location.

None of these prompts asked the AI to decide the architecture. Each one asked it to execute a decision I had already made.


🧠 AI Doesn't Replace Architectural Judgment β€” It Demands It

Here's the counterintuitive part.

The more specific the prompts were, the better the output. And to write a specific prompt, you first have to know exactly what you want: what shape the response takes, what happens when validation fails, which layer owns what.

That's architectural judgment. The AI didn't generate it. It demanded it.

A vague prompt produces vague code. A prompt with explicit architectural decisions produces code that respects those decisions.

If you don't have your system's shape clear before you write the prompt, the AI won't hand it to you for free. It'll fill the gaps with its best guess β€” and that guess might not match what the rest of your backend actually needs.


⚠️ None of This Ships Without Human Review

Every piece that got generated β€” the interceptor, the validation pipe, the Better Auth integration, the Arcjet rules β€” went through review before I trusted it.

Not because the output was bad. Most of the time it was exactly what I'd asked for. But "exactly what I asked for" and "correct in the context of the rest of the system" aren't always the same thing.

  • βœ… Does the interceptor break any endpoint that already returns its own response shape?
  • βœ… Does Arcjet's rate limiting make sense for public endpoints versus authenticated ones?
  • βœ… Does Zod's config validation fail fast, or let an invalid value slip through to production?

The AI doesn't answer those questions for you. Someone who understands the whole system β€” not just the fragment that was just generated β€” does.


πŸ”“ All the Code and Prompts, Open in the Repo

I left everything β€” the final code and the exact prompts that produced it β€” in a public repo, open for anyone to review, question, or use as a starting point:

πŸ‘‰ github.com/hugocruzlfc/nest-production-ready-api

I didn't publish it as "this is how it's done." I published it as a debatable starting point. If you see a prompt that should have been stricter, or an architectural decision you wouldn't stand behind in production, that's exactly the conversation I want to have.


🎯 Final Thoughts

Building this foundation almost without writing code by hand didn't mean thinking less about architecture. It meant thinking about it earlier, and with more precision, because every ambiguity in my head turned into an ambiguity in the prompt β€” and from there, into an ambiguity in the code.

AI doesn't replace judgment. It tests it in every instruction you give it.

The question that stuck with me: if you had to write every one of your architectural decisions as an explicit instruction before anyone could execute it, how many of those decisions are actually clear to you today?

Β© 2026 Hugo Cruz de la Torres. All rights reserved.

About this website: built with React & Next.js (App Router & Server Actions), TypeScript, Tailwind CSS, Framer Motion, React Email & Resend, and Vercel hosting.