Writing a Copilot Instructions File Your Team Will Actually Follow: A Checklist

Programmer typing code on a laptop

A Copilot instructions file is a Markdown file, saved at .github/copilot-instructions.md in a repository’s root, that gives GitHub Copilot repository-specific context and preferences it applies automatically to every Copilot Chat, code review, and coding agent request made in that repository. It needs checking periodically because an instructions file that is vague, outdated, or written for a human reader instead of a model quietly stops doing anything — Copilot still runs, but it ignores the parts that don’t parse as usable guidance, and nobody notices until a pull request full of wrong-convention code shows up. The checklist below is built directly from GitHub’s current documentation, not guesswork, and each item tells you why it matters and what a real version looks like.

What the file actually is, according to GitHub’s docs

Before the checklist, the terms need to be pinned down, because GitHub now ships three different kinds of “custom instructions,” and teams often use the wrong one without realizing it.

Repository-wide custom instructions live in a single file at .github/copilot-instructions.md and, per GitHub’s documentation, “apply to all requests made in the context of a repository.” Path-specific instructions live in one or more NAME.instructions.md files inside .github/instructions/, each with a YAML frontmatter block that uses an applyTo key with glob syntax (for example **/*.py) to scope the instructions to matching files only. Agent instructions are a newer, broader convention — AGENTS.md, and GitHub’s coding agent also recognizes CLAUDE.md and GEMINI.md — that can be placed at the repository root or nested in subdirectories, with the nearest file in the directory tree taking precedence for any given file. GitHub’s own reference page states plainly that “multiple types of custom instructions can apply to a request” and sets a priority order of personal, then repository, then organization instructions, with a direct warning to “avoid providing conflicting sets of instructions.”

Support for each file type also varies by surface. According to GitHub’s custom-instructions support reference, .github/copilot-instructions.md is the most broadly supported format — read by Copilot Chat, code review, and the cloud coding agent across GitHub.com, VS Code, Visual Studio, JetBrains IDEs, Eclipse, Xcode, and the Copilot CLI. AGENTS.md-style agent instructions have narrower support — notably, as of GitHub’s documentation, Xcode and Visual Studio Chat do not read them, and GitHub’s docs explicitly note that “Agent instructions… are currently not supported by all Copilot features.” That gap alone is a reason to keep copilot-instructions.md as the primary file even if your team also maintains an AGENTS.md for cross-tool compatibility with other AI coding agents.

The checklist

1. The file lives at exactly .github/copilot-instructions.md

Copilot only looks for repository-wide instructions at this one path, so a typo in the folder name or file name makes the whole file invisible to Copilot with no error or warning.

Why it matters: GitHub’s documentation is specific that the file must be created at .github/copilot-instructions.md in the repository root — not .github/COPILOT_INSTRUCTIONS.md, not docs/copilot-instructions.md, not inside a nested package folder. There’s no validation step that tells you the path is wrong; Copilot simply never reads a misplaced file, and the team keeps writing prompts assuming context that was never loaded.

Example: Run git ls-files | grep copilot-instructions from the repo root. The only acceptable result is .github/copilot-instructions.md. If you see it under a different casing or folder, move it — Copilot treats the file as available “as soon as you save the file(s),” per GitHub’s docs, so the fix takes effect immediately with no rebuild or redeploy.

2. Content is Markdown written as natural-language instructions, not prose documentation

Copilot’s custom instructions are parsed as directives for a model, not as a README for humans, so the writing style needs to match that.

Why it matters: A paragraph like “Our team generally tries to follow a testing-first approach when it makes sense” reads fine to a person onboarding, but it gives a model nothing concrete to act on — no verb it can execute, no condition it can check. GitHub’s own guidance for generating a file instructs the coding agent to write “verified commands” and concrete procedures, implying the target format is actionable statements, not narrative explanation.

Example: Replace “We like to keep things tested” with:

Write a unit test for every new function in `src/`. Run `npm test` before considering a change complete. Do not mark a task done if `npm test` fails.

3. Instructions are repository-wide, not task-specific

This file is read on every single Copilot request in the repo, so anything narrow enough to apply to just one feature or one PR will misfire on every other request.

Why it matters: GitHub’s own prompt template for generating this file states directly: “Instructions must not be task specific.” If you put “when refactoring the payments module, prefer the Stripe SDK over raw HTTP calls” into the repo-wide file, Copilot will try to apply payments-module logic to a request about the marketing site’s contact form, because the file doesn’t know which part of the repo the current request concerns. Task- or path-specific guidance belongs in a path-specific .instructions.md file instead, scoped with applyTo.

Example: Keep this in copilot-instructions.md: “This repository is a monorepo with apps/web, apps/api, and packages/shared.” Move this into .github/instructions/payments.instructions.md with applyTo: "apps/api/payments/**": “Use the Stripe SDK, never raw HTTP calls to Stripe’s API.”

4. The file stays within roughly two pages

Length is not a style preference here — GitHub’s own tooling enforces a budget, and an instructions file that keeps growing past it starts getting silently deprioritized or truncated in practice.

Why it matters: When GitHub’s documentation describes asking the Copilot cloud agent to generate repository instructions, it specifies: “Instructions must be no longer than 2 pages.” Teams that treat this file as a dumping ground for every onboarding note, architecture decision record, and style debate end up with a file so long that the genuinely load-bearing rules (security constraints, test commands) are buried on page five, effectively invisible in any context window that also has to hold the actual code.

Example: If your file has grown past roughly 500-700 words, split it: keep cross-cutting rules (tech stack, build commands, non-negotiable constraints) in copilot-instructions.md, and move anything scoped to a folder or file type into a dedicated .instructions.md file.

5. It includes the real build, test, and validation commands — and they’re verified to work

Copilot’s coding agent uses this file to decide how to validate its own changes, so a wrong or outdated command doesn’t just fail to help — it actively wastes agent runs or produces unvalidated code.

Why it matters: GitHub’s guidance for generating the file calls for “build, test, and validation procedures with verified commands” as core content. If the file says npm run test but the project switched to pnpm test:unit eight months ago, the coding agent will either fail the step outright or, worse, silently skip validation and hand back code nobody actually ran.

Example:

## Build and test
- Install dependencies: `pnpm install`
- Run unit tests: `pnpm test:unit`
- Run lint: `pnpm lint`
- A change is not complete until both `pnpm test:unit` and `pnpm lint` pass with no errors.

6. It states the project layout and where key logic actually lives

Without a map, Copilot has to infer architecture from whatever files happen to be open or attached, which means it frequently guesses wrong about where new code belongs.

Why it matters: This is listed explicitly in GitHub’s own generation guidance as expected content: “project layout and architectural guidance” plus “key file locations and dependencies.” A model that doesn’t know your API layer lives in apps/api/src/routes and not src/controllers will propose code in the wrong place, and a reviewer has to catch that by hand every time.

Example:

## Project layout
- `apps/web` — Next.js frontend
- `apps/api` — Express REST API, routes in `apps/api/src/routes`
- `packages/shared` — types and utilities shared by both apps; do not duplicate types that already exist here

7. Conflicting guidance is checked against path-specific and agent-level files

Because GitHub allows repository, path-specific, and agent instruction files to coexist and all apply to the same request, a rule in one file can silently contradict a rule in another.

Why it matters: GitHub’s reference documentation states outright: “Multiple types of custom instructions can apply to a request” and sets precedence as personal, then repository, then organization — but it does not resolve every possible conflict between a repository-wide file and a path-specific or AGENTS.md file touching the same area, and it warns teams directly: “Whenever possible, try to avoid providing conflicting sets of instructions.” A repo that says “use tabs” in copilot-instructions.md while an AGENTS.md nested in a subfolder says “use spaces” leaves Copilot resolving the contradiction inconsistently across surfaces.

Example: Before merging a new .instructions.md or AGENTS.md file, grep the repo for the rules it states and confirm none of them contradict a line already in copilot-instructions.md. If both files need to exist, have one explicitly defer: “For payments-specific conventions, see .github/instructions/payments.instructions.md,” rather than restating rules in both places.

8. Review the file’s effect on actual Copilot code review output, not just on Chat answers

Repository instructions also feed GitHub’s Copilot code review feature, which is a separate, toggleable setting in repository configuration — and it’s easy to write a file that reads well in Chat but produces noisy or irrelevant review comments.

Why it matters: GitHub’s documentation confirms code review is one of the surfaces that reads copilot-instructions.md, that it’s “enabled by default” but can be toggled per repository, and specifically that for code reviews “instructions read from the head branch,” meaning you can test a change to the instructions file in a PR before it merges. Teams that never check this miss that an instruction like “flag any use of any in TypeScript” produces a flood of review comments on a codebase that hasn’t finished a TypeScript migration yet.

Example: Open a draft PR that edits copilot-instructions.md alongside a small code change, and read the Copilot code review comments it produces on that same PR before merging — because the head-branch behavior means you’re reviewing against the updated instructions already, not the old ones.

9. The file is owned by someone, dated, and revisited on a schedule

An instructions file with no owner tends to fossilize at whatever state it was in when it was first written, even as the stack, commands, and layout underneath it keep changing.

Why it matters: None of GitHub’s enforcement mechanisms (the two-page guidance, the path matching) catch staleness — a command can be syntactically fine and still refer to a dependency the team dropped two quarters ago. Since the file takes effect the instant it’s saved, with no review gate of its own, the only thing that keeps it accurate is a team habit of treating it like any other piece of configuration that can drift.

Example: Add a one-line footer comment, enforced by convention rather than tooling: <!-- Last verified: 2026-10-01 by @username. Re-check commands each quarter. -->, and put “verify copilot-instructions.md” on the recurring checklist for whoever owns developer tooling.

A complete, ready-to-copy example file

Below is a full .github/copilot-instructions.md example that follows every item above, with inline annotations explaining each section’s purpose and what happens if it’s left out.

<!-- .github/copilot-instructions.md -->
<!-- Last verified: 2026-10-01. Re-check quarterly. -->

## Project summary
This repository is a monorepo for an e-commerce platform:
- `apps/web` — Next.js 14 frontend (App Router)
- `apps/api` — Express REST API
- `packages/shared` — shared TypeScript types and utilities

## Build and test
- Install dependencies: `pnpm install`
- Run unit tests: `pnpm test:unit`
- Run lint: `pnpm lint`
- Run type check: `pnpm typecheck`
- A change is not complete until `pnpm test:unit`, `pnpm lint`, and `pnpm typecheck` all pass.

## Coding conventions
- Use TypeScript strict mode; never add `// @ts-ignore` without a comment explaining why.
- Use functional React components with hooks; do not introduce class components.
- Shared types belong in `packages/shared`; do not redefine a type that already exists there.

## Testing
- Write a unit test for every new exported function in `apps/api/src`.
- Prefer integration tests over mocking the database for API route handlers.

## Constraints
- Never commit API keys or secrets; use environment variables documented in `.env.example`.
- Do not modify files under `packages/shared/generated/` — they are auto-generated.

## Where to look for more specific rules
- API route conventions scoped to `apps/api`: see `.github/instructions/api.instructions.md`.
- Payment-related code scoped to `apps/api/payments`: see `.github/instructions/payments.instructions.md`.

Annotations:

  • Project summary — gives Copilot the map it needs to place new code correctly. Omit it, and Copilot guesses the architecture from whatever file happens to be open, frequently placing new logic in the wrong app or package.
  • Build and test — this is what the coding agent actually runs to validate its own changes. Omit it, and the agent either fails validation outright or skips it, handing back code nobody confirmed actually passes tests.
  • Coding conventions — encodes team-specific style choices that aren’t visible from the code alone (why no class components, why strict mode matters). Omit it, and Copilot falls back to generic JavaScript/TypeScript idioms that may contradict your team’s actual standard.
  • Testing — states the testing philosophy in an actionable form rather than a vague aspiration. Omit it, and you get code changes with no new tests, because nothing told Copilot that tests were expected for this specific kind of change.
  • Constraints — the non-negotiable rules, especially security-related ones. Omit it, and there’s no guardrail stopping Copilot from, for example, suggesting a hardcoded key in an example snippet or editing generated files that will be overwritten on the next build.
  • Where to look for more specific rules — points to path-specific files instead of duplicating their content here, keeping this file within the two-page budget and avoiding the conflicting-instructions problem described in item 7. Omit it, and either this file balloons with task-specific detail that doesn’t belong here, or path-specific files go undiscovered and never get written at all.

None of this replaces a human reviewer. What it does is remove the most common reason a Copilot instructions file quietly stops being useful: it was written once, for a stack that has since changed, in a style suited to a person rather than a model, with no single surface checked to confirm it was working. Running down this checklist against your actual file — not your memory of what it says — usually takes under twenty minutes and surfaces at least one stale command or forgotten conflict in most repositories that have had the file for more than a few months.

A good instructions file assumes a baseline of solid prompt engineering fundamentals and knowing how to prompt a coding assistant well in the first place — the file encodes what you’d otherwise repeat by hand. It’s also worth pairing with guidance on tool use and function calling if your agent has any, and with a habit of running changes through AI-assisted code review before they merge.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top