Getting Started with GitHub Copilot: A Practical Guide
I’ve been writing code for over a decade, and I’ll admit: I was skeptical when GitHub Copilot first launched. “An AI that writes code for me? Sounds like a recipe for spaghetti.” But after using it daily for the past six months, I can tell you it’s both more useful and more frustrating than I expected. Let me show you exactly how to set it up, where it shines, and where it will absolutely waste your time.
The Real Pain Point: Context Switching
Here’s what broke me before Copilot: I’d be deep in a React component, writing a complex state update, and then I’d need to stop and write a utility function. Or I’d need to check the documentation for a library I use every six months. Or I’d need to write a test for a function that’s 90% boilerplate. Each interruption costs 15-20 minutes of focus. Copilot doesn’t eliminate that cost, but it reduces it to seconds.
Setting Up Copilot: The 10-Minute Setup
First, the prerequisites: You need a GitHub account (free or paid) and either VS Code, JetBrains IDE, or Neovim. I tested this on VS Code 1.85+.
Install the extension: Open VS Code, go to Extensions (Ctrl+Shift+X), search “GitHub Copilot”, and install the official one (blue icon, >50M downloads). Yes, there are clones—skip them.
Authenticate: Click the Copilot icon in the status bar (bottom right). It’ll open a browser tab to authorize. You need to be signed into GitHub. If you’re using a work account, make sure you have the correct org permissions—this tripped me up for 20 minutes.
Enable completions: By default, Copilot is on. You’ll see a little sparkle icon in the status bar when it’s active. Click it to toggle off if you need quiet time.
That’s it. No config files. No API keys. No model selection. This simplicity is both a blessing and a curse.
Your First 10 Minutes with Copilot
Open a new file called weather.js. Type this:
// function that takes a city name and returns the current weather
Wait one second. Copilot will likely suggest something like:
async function getWeather(city) {
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`);
const data = await response.json();
return data;
}
Press Tab to accept. Now type:
// format temperature from Kelvin to Celsius
It’ll suggest:
function kelvinToCelsius(kelvin) {
return (kelvin - 273.15).toFixed(1);
}
Press Tab again. This is Copilot at its best: boring, predictable transformations. But here’s where it gets tricky.
Where Copilot Fails (and Wastes Your Time)
1. It doesn’t understand your project context. I was working on a Node.js backend with Express. I typed // authenticate user. Copilot suggested a JWT-based auth flow—which was correct for 80% of projects. My project used session-based auth with Redis. The suggestion was completely wrong. I had to delete it and write the actual code myself.
2. It invents APIs. This is dangerous. I once typed // send email using SendGrid. Copilot suggested sgMail.send() with a function signature that doesn’t exist in the actual SendGrid v3 API. If I hadn’t checked the docs, I’d have a runtime error in production.
3. It doesn’t handle edge cases. Copilot will generate the happy path 90% of the time. Error handling? Timeouts? Rate limiting? It’ll skip those unless you explicitly prompt for them.
Practical Prompt Engineering for Copilot
After months of trial and error, here’s what actually works:
Bad prompt:
// calculate shipping cost
Good prompt:
// calculate shipping cost based on weight and distance
// weight in kg, distance in km
// return cost in USD
// apply 10% discount for orders over 100kg
The more specific your comment, the better Copilot’s output. I’ve found that including types, units, and business rules in comments produces code that needs 80% less editing.
Real Project Example: Building a Todo API
Let me walk through a real session. I’m building a simple Express API for a todo app.
I start with:
const express = require('express');
const app = express();
Copilot suggests the boilerplate app.listen() and middleware. I Tab through it. Then I type:
// in-memory todo storage
Copilot suggests:
let todos = [];
let id = 0;
I accept. Then I type:
// POST /todos - create a new todo
Copilot suggests:
app.post('/todos', (req, res) => {
const todo = {
id: id++,
title: req.body.title,
completed: false,
createdAt: new Date()
};
todos.push(todo);
res.status(201).json(todo);
});
Perfect. I accept. Then I type:
// GET /todos - list all todos
It suggests the obvious implementation. I accept. Then I type:
// PATCH /todos/:id - toggle completed
Here’s where Copilot surprised me. It suggested:
app.patch('/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) {
return res.status(404).json({ error: 'Todo not found' });
}
todo.completed = !todo.completed;
res.json(todo);
});
It handled the 404 case automatically. I didn’t prompt for it. That’s Copilot learning from common patterns.
The Testing Trap
I wrote a function to validate email addresses:
function isValidEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
Then I typed // tests for isValidEmail. Copilot suggested:
describe('isValidEmail', () => {
it('should return true for valid email', () => {
expect(isValidEmail('test@example.com')).toBe(true);
});
it('should return false for invalid email', () => {
expect(isValidEmail('invalid')).toBe(false);
});
it('should return false for email without @', () => {
expect(isValidEmail('testexample.com')).toBe(false);
});
});
Looks great, right? But it missed the edge case of emails with whitespace. I had to add that test manually. Never trust Copilot-generated tests blindly. They’ll pass, but they might not test the right things.
Keyboard Shortcuts That Save Minutes
After 100+ hours with Copilot, these are the shortcuts I use most:
- Tab: Accept suggestion
- Escape: Reject suggestion
- Ctrl+Enter: Open Copilot panel (shows 10 alternatives)
- Alt+]: Cycle to next suggestion
- Alt+[: Cycle to previous suggestion
The most underused feature: Ctrl+Enter. When Copilot gives you one bad suggestion, hit Ctrl+Enter and you’ll see 10 alternatives. I’ve found the 5th or 6th suggestion is often better than the first.
The Hidden Settings That Matter
Open VS Code settings (Ctrl+,) and search for “Copilot”. These three settings made a difference for me:
github.copilot.enable: Set tofalsefor Markdown and YAML files. Copilot is useless in those and just adds noise.editor.inlineSuggest.enabled: Keep thistrue. But if you find suggestions distracting, you can set it tofalseand only trigger suggestions with Ctrl+Space.github.copilot.advanced: This is hidden. Add"github.copilot.advanced": { "length": 100 }to your settings.json to limit suggestion length. I found longer suggestions (>100 chars) were often hallucinated.
The Real Cost: Your Attention
Here’s the honest truth: Copilot makes me faster at writing boilerplate, but it makes me slower at reasoning about complex logic. When I’m working on a tricky algorithm or a new design pattern, I turn Copilot off. Its suggestions break my flow and lead me down wrong paths.
I now have a mental rule: if the suggestion takes longer to evaluate than to write myself, I reject it. This happens about 30% of the time.
Your Next Step
Don’t try to use Copilot for everything. Instead, spend 20 minutes today on this exercise:
- Open a file with a function you wrote last week.
- Delete the function body.
- Write a detailed comment describing what it does, including types, edge cases, and error handling.
- See what Copilot suggests.
- Compare it to your original code.
You’ll learn more about Copilot’s strengths and weaknesses in those 20 minutes than in hours of reading. And you’ll know exactly when to trust it—and when to write the code yourself.