How to Get Started with GitHub Copilot

GitHub Copilot FundamentalsLesson 3 of 13Beginner12 min readVersion-sensitive
Published
Updated
Last technically verified
How to Get Started with GitHub CopilotGitHub Copilot Fundamentals3Beginner/github-copilot/getting-started/setup/

Most “getting started with Copilot” guides stop at installation, which is the part that was never difficult. This one goes further: by the end you will have built a small Python service with Copilot’s help, asked chat to review it, and run a test suite that actually passes.

That last step matters. Installing Copilot teaches you nothing about whether to trust it. Running its output does.

Step 1 — Prerequisites

Before starting, confirm you have:

  • A GitHub account. Free is fine.
  • Python 3.10 or later. Check with python3 --version.
  • A code editor. VS Code, Visual Studio, a JetBrains IDE, Eclipse or Xcode all support Copilot.

That is genuinely all. There is no local model to download and nothing to configure at the system level.

Step 2 — Get a GitHub account

If you already have one, skip ahead.

Otherwise, sign up at github.com. Use an email address you will keep — your Copilot subscription, if you buy one later, attaches to this account.

Step 3 — Get Copilot access

For this tutorial, Copilot Free is sufficient.

Step 4 — Choose an IDE

Copilot’s features are not distributed evenly across editors. VS Code gets features first and has the broadest support; Visual Studio is close behind; JetBrains, Eclipse and Xcode support the core features with some in public preview; Neovim supports completion only.

If you have a strong preference, use it. If you do not, use VS Code for this tutorial — the instructions below assume it.

How to Install GitHub Copilot covers every environment in detail, including a full feature matrix.

Step 5 — Install Copilot

In VS Code, setup is largely automatic: when you first use Copilot, the required extensions install themselves. You do not need to hunt through the marketplace.

Open VS Code and click the Copilot icon in the title bar. If Copilot is not yet set up, VS Code will prompt you through it.

For other editors:

  • Visual Studio 2022 17.10 and later — Copilot is included as a built-in component.
  • JetBrains IDEs — install the GitHub Copilot plugin from the Marketplace, then restart.
  • Eclipse and Xcode — install the GitHub Copilot extension for that IDE.

Step 6 — Authenticate

Copilot needs to know who you are.

In VS Code, when prompted, sign in to GitHub and authorise the request in your browser. In JetBrains IDEs, go to Tools → GitHub Copilot → Login to GitHub, copy the device code, and complete authorisation in the browser window that opens.

Once authenticated, confirm the Copilot status indicator shows it is active. If it shows an error, the problem is almost always one of three things: no Copilot access on the account, an organisation policy blocking it, or an out-of-date extension. The installation lesson has a troubleshooting table.

Step 7 — Create a small project

Now for something real. You are going to build a small utility module with a deliberately specific contract, then test it.

Create the project:

mkdir copilot-demo && cd copilot-demo
python3 -m venv .venv
source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install pytest

Create the structure:

copilot-demo/

copilot-demo/ ├── .venv/ ├── app.py ├── requirements.txt └── tests/ └── test_app.py

mkdir tests
touch app.py tests/test_app.py
echo "pytest" > requirements.txt

Open the folder in your editor.

Step 8 — Get your first suggestion

Here is the important technique, and it is not a prompt.

Open app.py and type only this — the signature and the docstring, not the body:

def parse_duration(value: str) -> int:
    """Convert a duration string such as '90s', '5m' or '2h' into seconds.

    Supports the suffixes s (seconds), m (minutes) and h (hours).
    Raises ValueError for an empty string, an unknown suffix,
    a non-numeric quantity, or a negative value.
    """

Press Enter and pause. Copilot should propose an implementation as ghost text.

Notice what just happened. You did not write a prompt. You wrote a contract: the input type, the return type, the accepted suffixes, and four specific error conditions. That docstring is the prompt, and it is a far better one than most people type into a chat box.

Check specifically:

  • Does it handle all four error cases the docstring named?
  • Does it reject negative values, or silently accept them?
  • Does '5' with no suffix raise, or default to seconds?

If the suggestion misses something, that is useful — it is the gap between what you specified and what was inferred. Press Esc to dismiss, or Tab to accept and then fix it.

Step 9 — Use Copilot Chat

Now switch layers. Open Copilot Chat — Ctrl+Shift+Alt+L on Windows and Linux, Shift+Option+Command+L on macOS — and ask it to critique what you just accepted.

Copilot promptReview your own implementationCopilot Chat

Review the parse_duration function in this file. Identify any input that would produce a wrong result or an unhandled exception rather than the documented ValueError. List each case concretely with the exact input that triggers it.

This is chat used well: not “write me code”, but “find what I missed”. Inputs worth checking that implementations commonly miss include '5', '', '-3m', '1.5h', ' 30s ' and '10x'.

Now ask for tests:

Copilot promptGenerate a test suiteCopilot Chat

Write pytest tests for parse_duration in tests/test_app.py.

Cover: valid seconds, minutes and hours; zero; whitespace around the value; and each documented failure case raising ValueError. Use pytest.mark.parametrize for the valid cases and pytest.raises for the failures. Import from app.

Apply the result to tests/test_app.py. Read it before you run it — check that the assertions are actually correct, not just plausible. A generated test that asserts the wrong expected value will pass against a wrong implementation and tell you nothing.

One more chat pattern worth practising now, because it is the one people reach for least and benefit from most — asking for a change with an explicit constraint on what must not change:

Copilot promptRefactor without changing behaviourCopilot Chat

Refactor parse_duration to separate parsing from validation, so each failure case raises from one obvious place.

Do not change the function signature, the exception type, or any of the documented behaviour. The existing tests must still pass unmodified.

The final sentence is doing the work. Without it, “refactor this” invites the model to improve things you did not ask about — renaming the function, changing the exception type to something it considers more idiomatic, or helpfully extending the accepted suffixes. Stating what is fixed is how you keep a refactor a refactor.

Step 10 — Review the code

Before running anything, read both files properly. You are looking for the things that are easy to miss:

  • Does the implementation match its own docstring?
  • Are the test assertions right, or merely self-consistent with a bug?
  • Are there imports you did not need?
  • Would you defend every line in code review?

This step feels skippable. It is the step.

Step 11 — Run it

python -c "from app import parse_duration; print(parse_duration('5m'))"

Expect 300. If you get something else, or an exception, you have found a real defect — fix it before continuing.

Step 12 — Run the tests

pytest -q

If a test fails, that is a good outcome for a learning exercise. Feed the failure back:

Copilot promptDebug a failing testCopilot Chat

This pytest failure comes from the parse_duration implementation in this workspace. Explain the root cause, then propose the smallest change that fixes it without breaking the other passing cases.

[paste the full pytest output here]

Pasting the actual error output matters far more than describing it. The traceback is context; your paraphrase is not.

Step 13 — Write repository custom instructions

This is the step that pays off every day afterwards, and almost nobody does it on day one.

Custom instructions are persistent context prepended to Copilot’s requests in this repository. Instead of restating your conventions in every prompt — and getting suggestions that ignore them whenever you forget — you state them once, check the file into version control, and the whole team gets them.

Create .github/copilot-instructions.md in the project:

mkdir -p .github
# Project conventions

This is a small Python 3.10+ utility library.

## Style
- Use type hints on every public function.
- Docstrings state the contract: inputs, return value, and every exception raised.
- Prefer the standard library. Do not add a dependency without a stated reason.

## Errors
- Raise `ValueError` for invalid input; do not return sentinel values such as -1 or None.
- Error messages name the offending value.

## Tests
- pytest, in `tests/`, mirroring the module layout.
- Use `pytest.mark.parametrize` for input tables rather than repeated near-identical tests.
- Every documented exception has a test asserting it is raised.

Now start a fresh chat session and ask for a second function — say, the inverse format_duration(seconds: int) -> str. You should see the conventions applied without you mentioning them: type hints present, ValueError rather than a sentinel, a parametrised test.

When not to reach for Copilot

Worth establishing early, because the habit forms fast in both directions.

  • When you do not understand the problem yet. Copilot will produce a confident implementation of the wrong thing, and its confidence is contagious.
  • When correctness is subtle. Concurrency, floating-point precision, authentication and authorisation boundaries, anything handling money. The output looks the same whether it is right or wrong.
  • When you are learning the language. The struggle is where the understanding forms. Skipping it produces someone who can ship code they cannot debug.
  • When the code is trivial. Reading a suggestion takes longer than typing three lines.

None of these are permanent restrictions. They are situations where the review cost exceeds the typing saved, which is the actual trade being made.

Common mistakes

MistakeWhy it hurtsDo this instead
Accepting suggestions without reading themUnreviewed code accumulates one keystroke at a timeRead the ghost text before Tab
Vague prompts ("make a parser")Every unstated decision gets guessedState inputs, outputs and error behaviour
Asking for a whole application at onceLarge diffs are unreviewable, so they go unreviewedOne capability per request
Trusting generated testsA wrong test passing against wrong code proves nothingVerify the expected values yourself
Working with no relevant files openCopilot cannot use context it was not givenOpen the interfaces and neighbouring modules
Pasting real secrets into chatCredentials end up in prompt contextUse placeholders, always

What you actually learned

The Python was incidental. The loop is the lesson, and it is the same loop at every level of the product:

  1. Establish context. The docstring, the open files, the instructions file.
  2. Ask for something specific. A contract, not a vibe.
  3. Read what came back, before accepting it.
  4. Run it. Not “it looks right” — run it.
  5. Feed real output back when it fails. Tracebacks, not paraphrases.

When you move to agent mode later, the same five steps apply, except step 4 is something the agent can do itself and step 3 covers a multi-file diff instead of one function. The scale changes; the discipline does not.

Frequently asked questions

Do I need to pay to follow this tutorial? No. Copilot Free covers everything here. Its limits — 2,000 completions a month and no cloud agent — do not bite on a project this size.

Copilot is not suggesting anything. What is wrong? Work through it in order: is the status indicator showing Copilot as active; are you signed in to the right GitHub account; does that account have Copilot access; is an organisation policy blocking it; is the extension current. The installation lesson has the full table.

Why did my suggestion differ from what this page describes? Because output is probabilistic. The same prompt in the same file produces different results between runs. That is expected, and it is why this tutorial tells you what to check rather than what you will see.

Should I commit .github/copilot-instructions.md? Yes. That is the point of repository-scope instructions — the conventions travel with the repository, so every contributor gets the same context.

Can I do this in a language other than Python? Yes, and the structure transfers directly: write a signature with a documented contract, let completion propose the body, ask chat for tests, run them. Use a language you can review confidently — the review step is where the value is.

What to do next

You now have the full loop: context in, suggestion out, review, run, verify. Everything else in Copilot is a variation on it.

The most valuable next habit is a repository custom instructions file — a one-time write that tells Copilot your language version, test framework and conventions, so you stop restating them. It improves every future interaction in that repository, for everyone on the team.

From here:

When you are comfortable with these, Agent Mode is the next real step up — the same loop, but Copilot drives and you supervise.

Sources

Every version-sensitive claim on this page was checked against first-party documentation. Only sources actually used are listed.

Primary sources