← Back to the journal
5 min read

Getting started with GitHub Copilot: a practical workflow with examples

Learn a small, repeatable GitHub Copilot workflow: explain existing code, give a precise task, review the change, and test the result.

GitHub Copilot is an AI coding assistant. A useful way to start is to give it a small task in a repository you understand, inspect what it suggests, and check the result yourself. This guide uses an original JavaScript example you can try in a practice repository.

Before you start

Use a repository you own or have permission to change. Make sure Copilot is available for your account and enabled in the tool you are using. The exact interface and available features depend on your environment and account settings; follow GitHub’s setup and quickstart documentation for the current steps.

Keep your experiment small. Create a branch, open the relevant file, and work on one behavior at a time. The prompts below are suggested exercises, not a transcript of a Copilot session or a promise of identical output.

First, ask it to explain the code

Before requesting an edit, ask Copilot to describe the relevant function and its edge cases. Give it the file or code you want it to inspect.

text
Explain the formatDisplayName function in this file.
Describe its inputs, output, and handling of whitespace.
Point out cases that are not covered. Do not change the code yet.

Compare its explanation with the actual implementation. If the explanation is wrong or incomplete, clarify that before moving on. This gives you a useful baseline for reviewing a proposed change.

Give it a specific task

Instead of asking it to improve an entire application, describe one result and include examples. Here is a practice task:

text
Write a JavaScript function named formatDisplayName(firstName, lastName).
Both arguments are strings. Trim whitespace around each argument.
Join the non-empty parts with a single space.
Return "Guest" if both parts are empty after trimming.
Do not add dependencies or change unrelated files.

Examples:
formatDisplayName("  Ada ", " Lovelace ") => "Ada Lovelace"
formatDisplayName("Ada", "") => "Ada"
formatDisplayName(" ", " ") => "Guest"

These requirements give you something concrete to evaluate. Our exercise is deliberately limited to string inputs; handling other input types would require a separate decision.

A reference implementation

The following is an original reference implementation for this exercise. Review the output you receive against the requirements rather than expecting it to match line for line.

javascript
export function formatDisplayName(firstName, lastName) {
  const parts = [firstName.trim(), lastName.trim()].filter(Boolean);
  return parts.join(" ") || "Guest";
}

This trims the edges of each name. It does not collapse spaces inside a name, validate names, or support non-string inputs. Decide whether your application needs those behaviors before expanding the function.

Ask for tests, then run them

Ask Copilot to propose tests based on the requirements. Check that the expected values are correct, and include cases the first draft might overlook.

text
Write tests for formatDisplayName using Node's built-in test runner.
Cover two names, only a first name, only a last name, and whitespace-only names.
Use strict assertions. Keep the tests focused on the agreed string-input behavior.

For a small standalone example, save the function as format-display-name.mjs and these tests as format-display-name.test.mjs in the same directory:

javascript
import test from "node:test";
import assert from "node:assert/strict";
import { formatDisplayName } from "./format-display-name.mjs";

test("joins two trimmed names", () => {
  assert.equal(formatDisplayName("  Ada ", " Lovelace "), "Ada Lovelace");
});

test("supports a first name on its own", () => {
  assert.equal(formatDisplayName("Ada", ""), "Ada");
});

test("supports a last name on its own", () => {
  assert.equal(formatDisplayName("", " Lovelace "), "Lovelace");
});

test("uses Guest for whitespace-only names", () => {
  assert.equal(formatDisplayName(" ", " "), "Guest");
});

With a current Node.js installation, run:

bash
node --test format-display-name.test.mjs

For an existing project, follow its own test framework and validation commands instead of introducing another setup just for one change.

Review the diff before committing

Read the changed files. Check the logic, imports, dependencies, and whether the change extends beyond the task. Run the relevant tests and try the user-facing behavior when applicable.

Review questionWhat to check
Does it solve the requested problem?Compare behavior with the examples in your prompt.
Did it change anything else?Review every file in the diff.
Are the tests meaningful?Verify expected values and important edge cases.
Is it ready to merge?Follow the project’s checks and review process.

If something fails, provide the relevant error and explain the result you expected. Ask for a focused correction, then inspect and test the new change again.

A workflow you can reuse

  1. Understand the code and decide what should change.
  2. Provide a small task, relevant context, constraints, and example outputs.
  3. Inspect the proposed implementation and tests.
  4. Run the checks and review the diff.
  5. Commit only when you understand the change.

You can adapt this pattern to explaining an unfamiliar function, drafting a small utility, or proposing tests for a bug. Good prompts help, but your review is still part of the work.

Further reading

GitHub and GitHub Copilot are GitHub’s products. Sruvio is not affiliated with GitHub.

S
Sruvio

Notes on learning, experimenting, and building.