DEV Community

Alex Morgan
Alex Morgan

Posted on Originally published at saaswithalex.pages.dev

Claude Code for NestJS: Modules, DI, and the Config Tax

Claude Code writes TypeScript well. It writes NestJS code inconsistently without project context. The specific failure modes are predictable: providers instantiated with new instead of injected through the constructor, @Module imports that reference services directly instead of the feature module, guards applied at the handler level when they belong on the controller, and interceptors written as middleware rather than as NestInterceptor implementations.

Each of these breaks the NestJS DI container in ways that are not immediately obvious. The application starts. The tests pass if you wrote them against the manual instantiation. But the DI container does not manage the instance lifecycle, scope, and teardown that NestJS provides. You end up with connection leaks, providers that bypass the module system, and code that becomes difficult to test in isolation.

The fix is a CLAUDE.md that encodes what you would tell a new backend engineer joining the project. NestJS has a specific way of doing things. Document it once and Claude follows it for every file it touches. If you have not set up Claude Code yet, the Claude Code setup guide covers installation and workspace configuration before the NestJS-specific steps below apply.

Why does NestJS need explicit Claude Code configuration?

NestJS is opinionated by design — modules, decorators, dependency injection, providers. But Claude Code does not know which patterns you want when there are five ways to do the same thing. Without a CLAUDE.md, it will mix patterns across modules, forget to use your custom interceptors, and generate services that bypass your validation layer entirely.

The problem is not that Claude Code is bad at TypeScript. It is that NestJS conventions are invisible in any single file. A codebase with dozens of modules, hundreds of DTOs, and custom guards, interceptors, filters, and adapters is genuinely ambiguous. Without context, Claude fills that ambiguity with reasonable defaults — and those defaults will not match your team's conventions.

This is where the config tax shows up. You can either accept inconsistent code that compiles but violates your architecture, or you can invest hours writing a CLAUDE.md that encodes your module boundaries, DI rules, and error-handling strategy. The latter is cheaper in the long run, but it is not free. Every new team member, every new microservice, every framework upgrade requires updating that config.

The same pattern appears in other frameworks, just with different symptoms. If you are evaluating whether the config tax is worth paying, Claude Code for SvelteKit: Runes, Routing, and Config Tax shows how file-based routing gives Claude Code a structural edge over runtime-configured frameworks when a CLAUDE.md enforces Svelte 5 runes.

What failure modes happen without a CLAUDE.md?

Without explicit CLAUDE.md configuration, Claude Code generates NestJS code with predictable failure modes: providers instantiated with new instead of constructor injection, @Module imports referencing services directly instead of feature modules, guards applied at the handler level instead of the controller, and interceptors written as Express middleware rather than NestInterceptor implementations per claudify.tech.

These are not random mistakes. They are the patterns a developer would write if they knew Express but had never seen NestJS. The DI container still starts. The routes still resolve. But the instance lifecycle management, scope handling, and teardown that NestJS provides are bypassed. You get connection leaks, providers that skip the module system, and tests that pass because they instantiate the class directly rather than asking the container for it.

The failure modes compound in monorepos. A large NestJS monorepo is one of the hardest environments for any AI coding assistant, because correctness depends on conventions that are invisible in any single file. An unconfigured Claude will call the database directly from a service instead of going through a repository, hardcode error strings instead of using your ErrorMessages constants, and put a new file in the wrong service per DEV Community.

The cost of these mistakes is not just debugging time. It is the accumulated technical debt of code that looks correct in review but violates the architectural boundaries your team relies on. A CLAUDE.md written once and committed to git prevents this class of error entirely.

How do you write NestJS rules Claude actually follows?

The key insight is that Claude Code reads .claude/ from your git root, so one configuration governs every service in the monorepo. Three mechanisms do the heavy lifting: CLAUDE.md (always-loaded project briefing), rules (hard prohibitions), and skills (multi-step workflows with templates) per DEV Community.

Write rules as prohibitions, not preferences. "NEVER query the DB in a loop" is enforced; "prefer bulk queries" is ignored under pressure. The single biggest win is service routing — a decision table in CLAUDE.md stops Claude from putting consumer logic in the operator service.

A NestJS CLAUDE.md should encode dependency injection rules including never instantiating providers with new outside test factories, always injecting via constructor, declaring providers in the owning module, exporting providers before importing elsewhere, and never importing services directly across module boundaries per claudify.tech.

The template below covers the minimum viable config for a NestJS 11 + TypeORM project:

# NestJS project rules

## Stack
- Node: 20.x
- NestJS: 10.x
- TypeScript: 5.x
- Database: PostgreSQL 16 (TypeORM 0.3.x) OR PostgreSQL 16 (Prisma 5.x)
- Package manager: pnpm

## Dependency injection rules (CRITICAL)
- NEVER instantiate a provider with `new` outside a test factory
- ALWAYS inject via constructor with type token
- ALWAYS declare providers in the module that owns them
- ALWAYS export a provider from its feature module before importing that module elsewhere
- NEVER import a service directly across module boundaries. Import the module, not the service.
Enter fullscreen mode Exit fullscreen mode

Commit .claude/ to git so the whole team shares it. The result: Claude generates code that follows your conventions on the first try, instead of guessing.

What open-source skills enforce NestJS patterns?

Several open-source skills package NestJS conventions into installable plugins. The most mature options are nestjs-expert, nestjs-best-practices-skill, and nestjs-agent-skills per GitHub.

  • nestjs-expert covers architecture, DI, guards, interceptors, pipes, MongoDB/Mongoose integration, authentication, and production patterns. Install it once and your AI assistant automatically enforces patterns every time you write, review, or refactor NestJS code.
  • nestjs-best-practices-skill enforces 24 production-ready rules covering architecture, authentication, TypeORM, validation, security hardening, testing, multi-tenancy, and more. It works with Claude Code, Cursor, and Windsurf.
  • nestjs-agent-skills is a set of three focused skills: nestjs-architecture-principles for module boundaries and data access, nestjs-oop-design-patterns for SOLID and DI review, and nestjs-features-performance for Nest-specific features and scaling.

The skills are intentionally separate. A small entry point loads first, and deeper references are used only when the task needs them. This keeps context usage low — relevant if you are watching token costs on subscription plans.

If you are using Claude Code across multiple frameworks, the complete commands reference maps slash commands and CLI flags organized by real developer workflow, including context management and subagent orchestration.

How does Claude Code pricing work for NestJS teams?

Claude Code is included with paid Claude plans (Pro, Max, Team, Enterprise) and is not available on the Free plan per VantagePoint. The pricing structure creates a governance-driven illusion: the product is "included" in subscription plans, but actual cost is determined by hidden shared-pool dynamics, tokenizer-induced token inflation, and the Enterprise plan's decoupling of seat fees from usage.

As of August 2026, Claude Pro costs $20/month or $17/month with annual billing, Max 5x costs $100/month, Max 20x costs $200/month, Team Standard seats cost $20/seat/month annually ($25 monthly), Team Premium seats cost $100/seat/month annually ($125 monthly), and Enterprise seats cost $20/seat/month plus usage billed at standard API rates per SSD Nodes.

The critical detail: Claude Code shares a single usage allowance with Claude chat, which resets on rolling 5-hour sessions and has separate weekly limits; heavy chat use reduces available capacity for coding sessions per Using Claude. A developer who spends the morning in chat has less left for Claude Code in the afternoon.

For API-billed deployments, Anthropic reports average Claude Code costs of approximately $13 per developer per active day, or up to $250 per developer per month per PromptsRush.

When should you use subscription vs API billing?

The choice depends on whether you need predictable spend or unlimited capacity. Subscription plans charge a flat monthly fee for a usage allowance that resets on a rolling five-hour window. API billing charges per token with no plan limits unless you set a monthly cap.

The Enterprise plan is often the most expensive option despite its $20/seat/month price matching Team Standard, because that fee buys governance controls only, with all usage billed separately at standard API rates per SSD Nodes. Compliance becomes a cost multiplier rather than a fixed overhead.

If you are trying to reduce costs without changing tools, Reducing Claude Code Costs: What Actually Works at Scale covers caching, model routing, and proxy tactics.

Claude Code pricing comparison

Plan Price (August 2026) Claude Code Included Usage Model Best For
Pro $20/month ($17 annual) Yes Shared chat-and-code pool, 5-hour reset Individual developers validating workflow
Max 5x $100/month Yes 5x Pro session usage Daily coding agents
Max 20x $200/month Yes 20x Pro session usage All-day / parallel agents
Team Standard $20/seat/month annual ($25 monthly) Yes Per-seat allowance, 1.25x Pro Teams needing shared billing
Team Premium $100/seat/month annual ($125 monthly) Yes Per-seat allowance, 6.25x Pro Heavy users in teams
Enterprise $20/seat/month + API usage Yes Seat fee + uncapped API metering Governance requirements, SCIM, audit logs
API (Console) Pay per token Yes (with API key) No plan limits; set your own caps Unlimited usage with hard spend caps

The table reveals the core tension: subscription plans offer predictable flat-fee billing with hard usage caps, while API billing offers uncapped metering with variable but potentially unlimited spend. Shared chat-and-code pools are economical but create zero-sum contention between chatting and coding. Dedicated per-activity allowances guarantee capacity but cost more.

For NestJS teams specifically, the decision hinges on whether your developers run Claude Code continuously throughout the day or in focused bursts. Continuous users hit the shared pool ceiling faster and should consider Max tiers or API billing with spend limits. Burst users on Team Standard seats get sufficient headroom at a fraction of the cost.

What changed in Claude Code for NestJS workflows?

Claude Code 2.0 (v2.1.224+) introduced cross-session messaging via list_agents and send_message, default auto mode for new sessions on Pro/Max/Team plans (as of August 14, 2026), a beta /design command, a built-in browser, and an iOS simulator per TechAmerica.

Cross-session messaging matters for NestJS monorepos. One session working on your database schema can now notify the session working on your API layer about a field name change, without you copy-pasting between windows. Named sessions persist across runs, allowing a specialist session to be called repeatedly as a reference point.

The default auto mode change is relevant for teams with strict governance requirements. Auto mode became the default permission mode for new sessions on Pro, Max, and Team plans, meaning Claude handles permission decisions automatically while checking for risky actions. If your team needs manual approval for every file edit, you will want to set a custom default.

The /design command generates editable design canvases directly from your code environment, but it requires Accept Edits mode rather than Auto mode. This is useful for planning NestJS module structures before implementation, but it is not a replacement for architectural review.

If you are comparing Claude Code against alternatives for large projects, Codex vs Claude Code for Large Projects: The Real Tradeoff covers how Claude Code wins for large projects needing deep context and state persistence.

The config tax is infrastructure, not docs

The pattern I have observed across NestJS projects is that the teams that get value from Claude Code are the ones that treat configuration as infrastructure, not documentation. A CLAUDE.md written once and committed to git is infrastructure. Open-source skills that encode your architectural decisions are infrastructure. Hard prohibitions in .claude/rules/ are infrastructure.

The teams that struggle are the ones that install Claude Code, accept the default behavior, and then wonder why their codebase is accumulating inconsistent patterns. The tool is doing exactly what it was trained to do: generate reasonable TypeScript. Without explicit constraints, "reasonable" defaults to Express idioms wrapped in NestJS decorators.

The investment pays back quickly. A NestJS monorepo setup is a few hours, one-time, and pays back on every feature: faster scaffolding, fewer convention violations in review, and faster onboarding per DEV Community. The alternative is perpetual cleanup.

If you are using Claude Code with Astro instead, Claude Code for Astro: Scaffolding, Costs, and Config Tax covers how the tool scaffolds Astro fast but needs detailed CLAUDE.md config to avoid ambiguous output, and how session costs explode via the Context Loop Tax as context grows.

The real cost is token throughput, not sticker price

Buyers should ignore list prices entirely and model cost based on actual token throughput and cross-activity pool contention. For any team writing code more than occasionally, the subscription model is a trap that conflates access with consumption, while API billing with hard spend limits provides the only true cost predictability.

Claude Fable 5.1, released September 1, 2026, cut cache-read pricing by 75% to $0.25 per million tokens (down from $1), while input prices remain at $10 per million tokens and output prices remain at the prior rate per WinBuzzer. Anthropic estimates ~25% lower typical workload costs and up to 45% for cache-heavy agents. For NestJS projects with large shared module contexts, this matters — the system prompt, module declarations, and DTO definitions that you cache across sessions become cheaper to reuse.

The tokenizer trap still applies. Claude 4.7 and later models produce roughly 30% more tokens for the same text, so moving to a newer model at an identical headline rate is effectively a 30% increase in cost per unit of actual work. Pin your model version and monitor token usage per session.

The practical consequence is that a seat has no dollar figure inside it. Usage inside the seat allowance is not metered in dollars anywhere, so "what did this developer cost us" has no answer on a pure seat plan. It has an answer the moment usage exceeds the allowance and usage credits kick in per SSD Nodes.

For NestJS teams specifically, the recommendation is to start with Team Standard seats for developers who use Claude Code intermittently, and API billing with hard spend limits for developers who run it continuously throughout the day. The config tax is fixed and predictable. The usage tax is variable and grows with context size.


Originally published at SaaS with Alex

Top comments (0)