5 tips for writing better custom instructions for Copilot
If you’ve read any of my stuff or listened to one of my presentations before, you’ve likely heard my snarky joke: “Don’t be passive aggressive with Copilot.” My point with this joke is serious, though. Copilot works best when you give it the right context. Just like a new teammate, it can’t read your mind (even if it sometimes feels like it can). Copilot can likely figure out what you’re doing and how you’re doing it. But spelling out the essentials – what you’re building, the stack you’re using, the rules to follow, etc., will help avoid confusion and mistakes. This is why instructions files are so important. They’re your chance to give Copilot that background, that institutional knowledge the rest of your team has from their experience with the project. The centerpiece for Copilot is copilot-instructions.md, the file which is read on every Copilot chat or agent request. So how should one be crafted? To help you avoid the blank-page problem, here are five things every instruction file should include (plus a bonus tip on how Copilot can even help you write the file itself). Before we get started One important tip I want to share before we get into more details is to not overthink things. There isn’t a specific prescribed way to write instructions files. The nature of generative AI is probabilistic, meaning the same requests can actually render different results. Your goal is to tilt the scales, to help point Copilot to finding the answer you’re hoping for as often as possible. The five sections (and bonus tip) below aren’t meant as requirements, but recommendations. In my experience, having these sections, or at the very least the key information indicated by these sections, in your instructions file will vastly increase the quality of suggestions from Copilot. You should use these as a starting point, and experiment and explore based on your projects, models, and experience with Copilot. Give GitHub Copilot a project overview It’s tough to write code for an app if you don’t know what the app is! The same thing is true for GitHub Copilot, and that’s where a project overview instructions file can be exceptionally helpful. The header for your instructions file should be the elevator pitch for your app. What’s the app? Who’s the audience? What are the key features? It doesn’t need to be long, just a few sentences to set the stage. Here’s an example of a project overview for an instructions file: # Contoso Companions This is a website to support pet adoption agencies. Agencies are onboarded into the application, where they can manage their locations, available pets, and publicize events. Potential adoptors can search for pets available in their area, discover agencies, and submit adoption applications. The above example is clear, direct, and simple. You don’t need to write the Magna Carta, but it’s important to give Copilot some context around what you’re trying to accomplish at a high level. And this example app totally isn’t a way for me to convince myself to adopt a new pet (seriously, it’s not and I’m not just telling myself that). Identify the tech stack you’re using in your project Once you’ve identified what you’re building, the next thing to identify is what you’re using to build it. This includes the backend and frontend tech you’re using, any APIs you’re calling, and any testing suites you’re targeting. After all, the number of frameworks alone to create a website is always growing. Case in point? Three new JavaScript frameworks have probably launched since you started reading this blog post! You don’t need to channel your inner George RR Martin when creating instructions files, crafting paragraphs upon paragraphs explaining the minutiae. Instead, think about creating a list highlighting the tech you’re using, and maybe add a note or two about how they’re being used. This will help Copilot understand the environment in which it’s creating code.Here’s a quick example from my own work for reference: ## Tech stack in use ### Backend – Flask is used for the API – Data is stored in Postgres, with SQLAlchemy as the ORM – There are separate database for dev, staging and prod – For end to end testing, a new database is created and populated, then removed after tests are complete ### Frontend – Astro manages the core site and routing – Svelte is used for interactivity – TypeScript is used for all front-end code ### Testing – Unittest for Python – Vitest for TypeScript – Playwright for e2e tests Spell out your coding guidelines Before you create your first pull request, you need to know the guidelines you should be following. Some of this is about how the code should be written. Are we using semicolons for JavaScript or TypeScript, for instance? Type hints for Python? Tabs or spaces? (The only correct answers are yes, yes, and spaces. I won’t be taking any questions.) Depending on your project structure, you could incorporate your guidelines into your tech stack instructions file. But I generally like having a separate section for guidelines, as many of them will apply across all languages in use. I find it to be more readable, which is important for maintainability, and there’s often crossover of guidance between languages and frameworks. You can also consider using .instructions files for guidelines for specific types of files, like all .astro or .jsx files, or unit tests which might match a pattern of /tests/test_*.py. Pro tip It’s very easy to fall into a spiral of trying to discover the perfect way to prompt Copilot or build the perfect instructions files. An “imperfect” instructions file will deliver far more impact than nothing at all. Your instructions file should also evolve over time, just like documentation. (We all keep our documentation up to date, right?) I strongly encourage you to experiment and see what works best, and to not let perfect be the enemy of good. Here’s another example from some of my own work: ##












