Custom Instructions
Custom instructions are how you turn a generic AI agent into one that knows your stack, your conventions, and your rules — and the file you check into .github/ is the one that matters most.
Every session starts without context — unless you give it context before the session starts. That is what custom instructions do.
Without a custom instructions file, Copilot CLI comes in cold. It does not know whether your project uses tabs or spaces, which test command to run, whether git push is allowed, or that your team names things a specific way. It will make reasonable guesses. Some of those guesses will be wrong. You will notice this on the second or third session when Copilot CLI writes code that passes tests but does not match your patterns — and you have to explain the conventions again.
Custom instructions solve this. They load automatically at session start. You write them once, check them in, and every session on that repo starts with your rules already loaded.
The instruction sources
Copilot CLI reads instructions from several places, and when more than one file applies, their contents are combined — they layer, they do not replace each other. Understanding which sources exist saves debugging time later.
The file you almost always want to create first is .github/copilot-instructions.md. It is checked into version control, shared across every team member's sessions on that repo, and loads for every session in that repository. Alongside it, Copilot CLI also reads AGENTS.md files as a first-class source: an AGENTS.md can live anywhere in the repo, and when Copilot is working in a directory, the nearest AGENTS.md in the tree takes precedence among agent files. If both a root AGENTS.md and .github/copilot-instructions.md exist, the instructions from both files are used.
Global instructions at ~/.copilot/copilot-instructions.md are useful for personal preferences that apply everywhere: your preferred programming style, your name, your timezone. They load alongside repo-level instructions — keep repo-specific rules in the checked-in files so the whole team shares them.
What to put in the instructions file
The anatomy of a useful instructions file has four sections: concise context, actionable rules, tool config, and style conventions. None of these sections should be long. If your instructions file exceeds 200 lines, it is too detailed and Copilot CLI will weight the less important rules the same as the critical ones.
The most important rule about writing rules: make them imperative. "Use named exports" is better than "we prefer named exports." "Run npm test after edits" is better than "testing is important to us." Copilot CLI responds to directives, not preferences.
A minimal starter file
Here is a real instructions file for a TypeScript Node.js API project:
# Context
TypeScript REST API using Express and Prisma. Node 20.
Tests run with: `npm test` (Jest). Linting: `npm run lint`.
# Rules
- Run `npm test` after any source file edit
- Use named exports only — no default exports
- No `any` type; use `unknown` and narrow explicitly
- Prisma migrations go in `prisma/migrations/` — never edit them directly
- Environment variables accessed via `config/env.ts` only, never `process.env` directly
# Guardrails (guidance — enforce with --deny-tool flags)
Never run: git push, npm publish, prisma migrate deploy
# Style
- Async/await over .then() chains
- Error messages include the function name: `Error in createUser: ...`
- No console.log in non-test files — use the logger in `lib/logger.ts`
That file covers the information Copilot CLI most often gets wrong without it. The test command, the coding constraints, the actions it should never take, and the style rules that matter to the team.
One important distinction: instructions are guidance to the model, not an enforcement mechanism. A "never run git push" line strongly steers behavior, but the hard guarantee comes from the tool-permission flags (--deny-tool) covered in the tool control lesson. Use both — instructions for intent, flags for enforcement.
Modular instructions for monorepos
If your project is a monorepo with packages that have different rules, use path-specific instructions: NAME.instructions.md files inside the .github/instructions/ directory, each with an applyTo glob in its frontmatter declaring which paths it governs.
.github/
copilot-instructions.md ← shared baseline for the whole repo
instructions/
api.instructions.md ← applyTo: "packages/api/**"
frontend.instructions.md ← applyTo: "packages/frontend/**"
Each path-specific file starts with frontmatter like:
---
applyTo: "packages/api/**"
---
- API routes use the repository pattern in src/repositories/
- Integration tests run with: npm run test:integration
When Copilot CLI works on a file matching packages/api/**, it applies both the repo-wide instructions and api.instructions.md — the instructions from both files are used. (Nested AGENTS.md files are the other way to scope rules to a subtree: the nearest one in the directory tree takes precedence among agent files.)
AGENTS.md and other agent files
AGENTS.md is not a legacy fallback — it is a first-class instruction source for Copilot CLI. AGENTS.md files can live anywhere in the repository (the nearest one to the file being worked on takes precedence), and CLAUDE.md or GEMINI.md in the project root are read as well. If your team already maintains a good AGENTS.md, Copilot CLI will use it alongside any .github/copilot-instructions.md. Choose whichever convention your team standardizes on — the key is that the rules are checked in and shared.
Lesson Drill
- Create
.github/copilot-instructions.mdfor your current project. Write at least the Context and Rules sections. Keep it under 40 lines. - Start a Copilot CLI session and ask it to explain what instructions it loaded. Confirm it found your file.
- Add one guardrail to your instructions file — identify a shell command that Copilot CLI should not run in this project and state it explicitly. Then enforce it for real by launching with a
--deny-toolflag (covered in detail in the tool control lesson).
Bottom Line
Custom instructions load at session start and persist across every session on that repo. The file that matters is .github/copilot-instructions.md — version-controlled, shared by the team, and combined with path-specific .github/instructions/*.instructions.md files and any AGENTS.md. Keep it short, specific, and imperative. Vague instructions produce vague behavior. A well-written 20-line instructions file outperforms a verbose 200-line one every time.
The next lesson covers plan mode — how to make Copilot CLI produce an explicit plan before touching a single file.