GitHub Copilot Custom Instructions: Stop Repeating Yourself Every Prompt

June 03, 2026 8 min read 38 views
A clean flat-style illustration of a configuration document surrounded by floating code symbols on a soft blue-grey gradient background

Every time you open a Copilot Chat window, you find yourself typing the same thing: "We use Python 3.11, FastAPI, async handlers, snake_case everywhere, and we never use bare except clauses." It works, but it's tedious β€” and if you forget, the suggestions drift off into generic territory that doesn't match your codebase at all.

Custom instructions solve this. You write your context once, and Copilot applies it silently to every conversation without you having to repeat yourself.

  • What custom instructions are and where they live
  • How to write instructions that actually change Copilot's behavior
  • Repo-level vs. editor-level configuration
  • Practical templates for common stacks
  • What custom instructions can't do (and where people get tripped up)

What Custom Instructions Actually Are

Custom instructions are plain-text rules you provide to GitHub Copilot Chat that get prepended to every conversation automatically. Think of them as a persistent system prompt. You don't see them in the chat window, but Copilot does β€” and they shape every response it generates.

There are two places these instructions can live: in your editor settings (applying to all your projects) or in a .github/copilot-instructions.md file at the root of a repository (applying only to that project). The repo-level file takes priority when both exist, which makes it the right tool for team-wide consistency.

Prerequisites

Before you start, make sure you have:

  • GitHub Copilot Chat enabled on your account (individual, business, or enterprise plan)
  • VS Code with the GitHub Copilot Chat extension, or JetBrains IDEs with the Copilot plugin (repo-level instructions are supported in both)
  • The "Use Instruction Files" option turned on in your Copilot settings (it is on by default in recent versions)

If you're on an older version of the extension, update it first. Instruction file support was added relatively recently and older builds will silently ignore the file.

Setting Up the Repo-Level Instructions File

The repo-level approach is the most useful for professional work because the instructions travel with the codebase. Any teammate who opens Copilot Chat in the same repo gets the same context automatically.

Create the file at exactly this path:

.github/copilot-instructions.md

The filename and location are not flexible β€” Copilot looks for this exact path. Commit it to your main branch so the whole team picks it up.

Here is a minimal example for a Python/FastAPI project:

# Project context
This is a FastAPI application using Python 3.11. All route handlers are async.
We use SQLAlchemy 2.x with the async session pattern.

# Code style
- Follow PEP 8. Use snake_case for all variables and functions.
- Never use bare `except:` clauses. Always catch a specific exception type.
- Prefer explicit return type annotations on all functions.
- Use `pathlib.Path` instead of `os.path` for file operations.

# Testing
- We use pytest with pytest-asyncio for async tests.
- Every new function should have at least one corresponding test in the `tests/` directory.
- Use `httpx.AsyncClient` for API endpoint tests, not the requests library.

# What to avoid
- Do not suggest print() for logging. We use the standard `logging` module.
- Do not introduce new dependencies without noting it explicitly in your response.

Notice the structure: short factual statements about the stack, then specific behavioral rules, then explicit prohibitions. This pattern works better than vague requests like "write clean code."

Setting Up Editor-Level Instructions

If you want a baseline that applies across all your projects regardless of whether they have a repo-level file, you can set instructions in VS Code's settings.

Open your VS Code settings JSON (Ctrl+Shift+P β†’ "Open User Settings JSON") and add:

{"github.copilot.chat.codeGeneration.instructions": [{"text": "Always use const and let, never var. Prefer arrow functions. Use TypeScript strict mode assumptions even in plain JS files."}]}

You can also point to a file instead of inlining the text:

{"github.copilot.chat.codeGeneration.instructions": [{"file": "~/.config/copilot/default-instructions.md"}]}

Editor-level instructions are useful for personal style preferences that you want everywhere β€” your preferred comment style, a reminder to write defensive null checks, or your preferred import ordering.

Writing Instructions That Actually Work

The quality of your instructions determines how much Copilot's behavior actually shifts. Vague instructions produce marginal results; specific ones produce meaningful ones.

Be concrete, not philosophical

This is weak:

Write readable, maintainable code following best practices.

This is better:

Functions should do one thing. If a function exceeds 30 lines, add a comment explaining why it cannot be split further.

The second instruction gives Copilot a measurable condition to check against.

Describe your stack precisely

Don't just say "we use React." Say which version of React, which state management approach, whether you use a component library, and how you handle side effects. Specificity narrows the suggestion space dramatically.

Frontend stack: React 18 with TypeScript 5. State management via Zustand (no Redux).
Styling: Tailwind CSS v3. No CSS-in-JS.
Data fetching: TanStack Query v5. Do not suggest useEffect for data fetching.

Use prohibitions sparingly but firmly

A long list of "don't do this" rules can confuse the model. Pick the prohibitions that matter most β€” the ones where the default behavior would create real problems in your codebase β€” and state them clearly once.

Separate concerns with headings

Markdown headings inside the instructions file help the model parse the different categories of rules. Group related rules under a heading rather than dumping them in one block of prose.

Templates for Common Stacks

Node.js / Express API

# Stack
Node.js 20, Express 4, TypeScript 5. ESM modules only (import/export, not require).
Database: PostgreSQL via node-postgres (pg). No ORM.

# Style
- All async functions use async/await. No raw Promise chains.
- Error handling: use a centralized Express error middleware. Do not handle errors inline in routes.
- Validate all incoming request bodies with zod before touching the database.

# Testing
Vitest for unit tests. Supertest for integration tests against Express routes.

Django / Python

# Stack
Django 5.x, Python 3.12. We use Django REST Framework for all API endpoints.
Database: PostgreSQL. We write raw SQL for complex queries using Django's connection.execute().

# Style
- Class-based views for all DRF endpoints.
- Model fields should always include verbose_name and help_text.
- Never use Django's shell_plus in suggested commands. Use manage.py shell.

# Security
- Never suggest storing secrets in settings.py. Use environment variables via python-decouple.

Data / Analytics (Python)

# Stack
Python 3.11. Pandas 2.x for data manipulation, SQLAlchemy 2.x for database access.
Jupyter notebooks for exploration; production scripts are plain .py files.

# Style
- Prefer method chaining over intermediate variable assignment in Pandas.
- Use .copy() explicitly when slicing DataFrames to avoid SettingWithCopyWarning.
- Type-hint all function parameters and return values, including DataFrame inputs.

# What to avoid
- Do not use iterrows(). Use vectorized operations or apply() only when necessary.
- Do not suggest global variables in production scripts.

Common Pitfalls

Instructions that are too long get diluted. There is no hard character limit documented publicly, but in practice instructions over roughly 1,000 words start producing inconsistent results. The model is balancing your instructions against the active conversation β€” if your instructions are an essay, the signal-to-noise ratio drops. Keep it focused.

Conflicting instructions confuse the model. If your editor-level settings say "use semicolons" and your repo file says "no semicolons," you will get inconsistent output. Audit both layers when something feels off.

The file path is case-sensitive on Linux. .github/copilot-instructions.md must be lowercase. On macOS the filesystem is case-insensitive by default so you might not notice the problem locally, then it breaks when the repo is cloned on a Linux machine or in a CI container.

Instructions don't affect inline completions. The ghost-text completions you see as you type are not currently influenced by the instructions file. Custom instructions only apply to Copilot Chat conversations. If you ask Copilot Chat to generate a function and then accept it, the output respects your instructions. If you just start typing and accept a ghost-text suggestion, it does not.

Teammates need to have Copilot Chat open. The instructions file is picked up when a developer has the Copilot Chat panel active or uses a slash command. It won't retrofit suggestions someone gets through pure inline completion.

Keeping Instructions Up to Date

Treat the instructions file like any other piece of documentation: it goes stale if nobody maintains it. When you upgrade a major dependency, add a new linting rule, or switch test frameworks, update the file in the same PR. A stale instructions file is worse than none β€” it produces confident suggestions that contradict what your codebase actually does.

A lightweight way to handle this is to add a comment block at the top of the file with a "last reviewed" date. It is low-tech but it surfaces during pull request reviews and keeps the conversation alive.

<!-- Last reviewed: 2025-05 | Owner: backend team -->

What Custom Instructions Can't Do

It is worth being clear about the boundaries so you don't build workflows around assumptions that won't hold up.

Custom instructions cannot give Copilot access to your actual codebase structure. The model does not read your entire repo. It works from whatever files are open in your editor and whatever you paste into the chat. Instructions tell it how to respond; they don't give it new information about your specific code.

They also can't enforce anything. If you instruct Copilot never to suggest var, it will try not to β€” but it might slip, especially in complex prompts where other constraints take priority. Instructions shift probabilities; they don't create hard rules. Your linter and CI pipeline are still the real enforcement layer.

Next Steps

Here are concrete actions to take right now:

  1. Create a .github/copilot-instructions.md in your most active repository today. Start with just the stack version and two or three style rules. You can add more over time.
  2. Open Copilot Chat and ask it to generate a function you've written before. Compare the output to what you would have gotten without instructions. Iterate on the instructions based on what's still off.
  3. If you work on a team, open a short PR with the instructions file and ask teammates to review it the same way they'd review a linting configuration. Surface disagreements early.
  4. Set a recurring reminder (monthly is fine) to review the file when major dependencies change.
  5. Add editor-level instructions for personal style preferences that you carry across all your projects β€” things like preferred comment style or null-check patterns that your team's file wouldn't cover.

The goal isn't a perfect instructions file on day one. It's a file that gets slightly better every sprint until Copilot's suggestions feel like they already know your codebase.

πŸ“€ Share this article

Sign in to save

Comments (0)

No comments yet. Be the first!

Leave a Comment

Sign in to comment with your profile.

πŸ“¬ Weekly Newsletter

Stay ahead of the curve

Get the best programming tutorials, data analytics tips, and tool reviews delivered to your inbox every week.

No spam. Unsubscribe anytime.