GitHub Copilot Best Practices and Limitations
Getting the most out of GitHub Copilot requires knowing both what it does well and where it falls short. This final topic brings together the core habits of expert Copilot users and gives you an honest picture of Copilot's limitations so you can work around them rather than be surprised by them.
The Mindset That Makes Copilot Effective
Developers who get the most from Copilot treat it as a capable but imperfect collaborator — not an oracle and not a toy. The most productive mindset combines these three principles:
PRINCIPLE 1: ALWAYS BE THE REVIEWER Copilot is fast but fallible. Accept its speed, apply your judgment. Never ship code you have not read. PRINCIPLE 2: INVEST IN CONTEXT The quality of a suggestion equals the quality of context. Better prompts, better file names, better comments all produce better suggestions. PRINCIPLE 3: USE THE RIGHT TOOL FOR EACH TASK Inline suggestions → routine code generation Chat → explanations, refactoring, complex tasks Slash commands → targeted actions on selected code Agent Mode → multi-file, multi-step implementations
Best Practices: Writing and Generating Code
DO: ✓ Write a clear comment before every function you want generated ✓ Use specific, descriptive function and variable names ✓ Accept partial suggestions and continue from there ✓ Cycle through alternatives (Alt+]) before settling on one ✓ Keep files focused — one responsibility per file ✓ Open related files as tabs to give Copilot better context AVOID: ✗ Accepting a suggestion without reading it ✗ Using vague function names like process(), handle(), doStuff() ✗ Working in a 2000-line file where context is diluted ✗ Relying on Copilot for security-sensitive logic without review ✗ Using Copilot to write code you do not understand at all
Best Practices: Testing
DO:
✓ Generate tests immediately after writing a function
✓ Use /tests or right-click → Generate Tests
✓ Let Copilot write edge case tests — it often finds
cases you would have missed
✓ Verify each generated test actually tests the right thing
AVOID:
✗ Accepting test files without running them
✗ Skipping tests because "Copilot wrote the code, it must be right"
✗ Letting generated tests give false confidence
(tests that pass but do not actually test the expected behavior)
Best Practices: Security
DO:
✓ Reject any suggestion that hardcodes credentials
✓ Run a security linter (ESLint security plugin, Snyk,
Semgrep) in addition to using Copilot
✓ Enable the public code duplication filter in settings
✓ Use .copilotignore to protect sensitive files
AVOID:
✗ Using Copilot on files that contain real secrets
✗ Trusting Copilot's cryptographic function choices
without verifying they meet current standards
✗ Disabling security reviews because you trust AI output
Copilot's Genuine Strengths
WHERE COPILOT PERFORMS BEST: ──────────────────────────────────────────────────────────── TASK WHY COPILOT EXCELS ──────────────────────────────────────────────────────────── Boilerplate code Seen millions of times in training Standard CRUD operations Well-established patterns Writing tests Predictable structure Documentation generation Natural language from code Regex patterns Complex but finite patterns Data transformations Clear mathematical operations Algorithm implementations Classic CS problems well-known Converting between formats JSON ↔ XML ↔ YAML ↔ CSV Repetitive code patterns Replicates what it already sees Explaining unfamiliar code Reads and describes what it sees ────────────────────────────────────────────────────────────
Copilot's Genuine Limitations
WHERE COPILOT PERFORMS POORLY: ──────────────────────────────────────────────────────────── LIMITATION 1 — NO REAL-TIME KNOWLEDGE: Copilot's training has a cutoff date. It does not know about library versions released after training. Always check official documentation for new APIs. Example: Copilot may suggest deprecated syntax from an older version of React or Node.js. ──────────────────────────────────────────────────────────── LIMITATION 2 — NO PROJECT-WIDE MEMORY: Copilot reads a window of recent code. It cannot reason about your entire architecture without explicit context from @workspace or Chat. Example: Copilot may suggest importing a utility function that does not exist in your project. ──────────────────────────────────────────────────────────── LIMITATION 3 — WEAK AT NOVEL BUSINESS LOGIC: Copilot cannot know your business rules. It guesses based on naming and comments. Example: A "commission tier" function may produce plausible-looking code with wrong tier boundaries. ──────────────────────────────────────────────────────────── LIMITATION 4 — HALLUCINATIONS: Copilot sometimes invents function names, parameters, or library methods that do not exist. Example: It might suggest someLibrary.specialMethod() where specialMethod() is not a real function. Always verify library methods against documentation. ──────────────────────────────────────────────────────────── LIMITATION 5 — INCONSISTENCY ON REPEATED REQUESTS: Asking the same question twice may produce different answers. Copilot is probabilistic, not deterministic. Use this to your advantage: cycle through alternatives. ──────────────────────────────────────────────────────────── LIMITATION 6 — POOR REASONING ACROSS MANY STEPS: Copilot struggles with very long logical chains. Break complex tasks into smaller, sequential steps.
The Hallucination Problem in Detail
Hallucination is when Copilot confidently suggests something that does not exist or is factually wrong. It happens because Copilot predicts probable tokens — it does not verify against a real API or documentation.
EXAMPLE OF HALLUCINATION:
Copilot suggests:
import { parseMarkdownTable } from 'marked';
← 'marked' does not export parseMarkdownTable
HOW TO CATCH IT:
→ Your editor's TypeScript checker will underline it
→ You will see an import error when you run the code
→ Use your package's official documentation to verify
PREVENTION:
→ After accepting an import suggestion, hover over it
to see if your editor recognizes the export
→ Run the code and watch for "X is not a function" errors
→ Check the library's changelog for the specific version
your project uses
Staying Sharp as a Developer
One of the real risks of heavy Copilot usage is skill atrophy — relying so heavily on generated code that your own problem-solving ability weakens over time. Experienced developers manage this by staying intentional about when they use Copilot and when they code from scratch.
SKILL MAINTENANCE HABITS:
✓ Solve algorithm challenges manually, without Copilot
✓ Write the first draft of critical business logic yourself
✓ Read and understand every suggestion before accepting
✓ Use Copilot to speed up repetitive work,
not to avoid thinking through new problems
✓ Periodically review code Copilot wrote and
explain it aloud — this reveals gaps in understanding
Copilot Across the Development Lifecycle
PHASE COPILOT ROLE YOUR ROLE ────────────────── ───────────────────────── ───────────────────────── Planning Limited Architecture, design Scaffolding Strong — generates setup Review structure Implementation Strong — fills functions Review logic and security Testing Strong — generates tests Review coverage and cases Debugging Good — suggests fixes Diagnose root cause Documentation Strong — generates docs Review accuracy Code Review Good — flags issues Make final decisions Deployment Minimal Own the process entirely
A Practical Daily Workflow
MORNING: → Open the file you are working on → Open related files as tabs (models, services, tests) → Write a brief comment describing the first function DURING CODING: → Let Copilot suggest, cycle alternatives if needed → Accept, modify, or reject each suggestion deliberately → Use Chat when a suggestion needs more context or iteration → Generate tests after each significant function END OF SESSION: → Run all tests to confirm Copilot's output works correctly → Review any section where you accepted code quickly → Commit with a meaningful message
The Honest Summary
GitHub Copilot is the most productive coding tool most developers will ever use — and it is also a tool that requires active supervision. It writes fast. It makes mistakes. It needs your knowledge, your judgment, and your accountability for the code it helps produce.
Developers who treat Copilot as a multiplier of their own skills — not a replacement for those skills — consistently report dramatic improvements in speed, test coverage, and documentation quality. The developers who struggle with it are those who accept suggestions without understanding them, or who expect Copilot to know things it cannot know.
