I'm building a large project by myself in an Nx monorepo with several applications, including Next.js, React Native, Fastify, and Python. AI coding tools often generate duplicated functions, excessively large methods, unsafe type casts, and schema changes that only make the code appear to work. They also tend to write weak tests, such as checking whether a button happens to be positioned correctly.
I've already set up typescript-eslint with strict type checking, SonarJS, and Knip, but I'd like to create a more reliable engineering process. I'm looking for resources and practical advice on configuring ESLint, static analysis, testing, and project conventions for a large codebase. The goal isn't to completely outsource code review, but to catch violations automatically so I can spend less time correcting the same issues after every AI-generated change.
3 Answers
Custom ESLint rules can be especially useful for project-specific constraints that general-purpose rules cannot express. For example, you could require particular decorators in DTO files, restrict one class per file, forbid constructors in certain layers, or enforce approved import boundaries between applications and libraries.
That turns your own standards into fast, repeatable checks. Have the AI help draft the rule if you want, but test the rule carefully and keep the implementation in version control like any other production code.
ESLint is mainly for patterns and enforceable conventions; it isn’t a complete measure of code quality. Combine it with TypeScript’s strict settings, formatting, dependency and dead-code checks, unit and integration tests, and CI gates. For an Nx workspace, define shared presets and boundaries between libraries so every application follows the same baseline while still allowing framework-specific rules.
Also separate tests that verify behavior from tests that merely repeat implementation details. Prefer assertions about API results, state transitions, accessibility behavior, and important failure cases over fragile checks about layout or exact markup. AI can help review code, but automated checks should block obvious violations before you perform the final review.
Start with a clear, intentional ESLint configuration rather than enabling every rule available. Use it to enforce the conventions that matter in your codebase, and make linting part of the normal workflow and CI checks.
For the AI tools, keep a project instruction file that explains your architecture, coding standards, commands for linting and testing, and where existing implementations should be reused. Tell the tool to search for similar code before creating a new function or abstraction. It still won’t understand the entire repository every time, so reviewing the result remains necessary.
Context size can be a real limitation. Configuration files and instructions consume the same context as the source code, so very large instruction files may become less effective. Keep the guidance focused and make the important checks executable through scripts rather than relying only on prose.

That’s the process I’m aiming for. I don’t want to delegate the final quality judgment; I want the tools to prevent predictable violations so I’m not repeatedly fixing the same standards issues after each generated change.