Optimizing GitHub Copilot Custom Instructions for Complex TypeScript Project Architectures
useEffect inside a service class or mixing your Zod schemas with API response types, your .github/copilot-instructions.md (or the IDE settings) needs a hard architectural constraint.The secret to stopping the "hallucinated patterns" is to define a strict hierarchy of truth. Instead of telling Copilot to "write clean code," tell it exactly which directory governs the types for which layer.
For my current project—a complex TS backend with a Clean Architecture approach—I stopped relying on the AI's general knowledge of TypeScript and forced it to adhere to my specific folder structure using a "Context Map" in the custom instructions.
Here is the snippet I added to my project instructions to fix the constant type-leakage:
## Architectural Constraints
- Domain Layer (`/src/domain`): Zero dependencies on external frameworks. Use pure TS classes and interfaces. No Prisma types allowed here.
- Application Layer (`/src/app`): Orchestrates domain logic. Only allowed to import from `/src/domain`.
- Infrastructure Layer (`/src/infra`): Where the "dirty" work happens. This is the ONLY place where `prisma` or `axios` imports should exist.
## TypeScript Preferences
- Prefer `interface` over `type` for public API definitions.
- Always use `z.infer<typeof schema>` for request validation to ensure a single source of truth.
- Avoid `any` at all costs; if a type is truly unknown, use `unknown` and a type guard.Beyond the architectural rules, the biggest productivity gain comes from "Pattern Anchoring." Copilot is great at mimicking, but it often mimics the average of the web rather than the best part of your codebase. I started adding specific "Golden Examples" to my instructions.
Instead of saying "use the Repository pattern," I write:
"When creating a new repository, follow the pattern in src/infra/repositories/UserRepository.ts: define the interface in domain, implement in infra, and inject via the constructor."
One major gotcha I hit: if your instructions file gets too bloated (over 2k words), the AI starts ignoring the middle sections. I found that bulleted lists of "Never Do This" are processed much more reliably than long paragraphs of "How to do this."
My "Never" list for Copilot:
- Never use
index.tsbarrel files for internal module exports (it kills tree-shaking and confuses the AI's path resolution). - Never suggest
anywhen a Generic<T>could be used. - Never implement business logic inside the Controller layer.
To make this work across a team, don't just put this in your local VS Code settings. Commit a
.github/copilot-instructions.md file to the root of your repo. This ensures that every dev on the team gets the same architectural suggestions, turning Copilot from a generic autocomplete tool into a project-aware pair programmer.When you combine this with the @workspace agent in Copilot Chat, the accuracy of the suggested file paths jumps significantly because the AI now has a mental map of where things should live before it even scans the file tree.
All Replies (0)
No replies yet — be the first!
