Development Environment Setup

1

Development Environment Setup

▶

Before a single line of project code is written, every member of a team needs a working, verified development environment. An environment is more than "having an editor installed" — it is the combination of a code editor, version control tooling, authentication credentials, a shared folder structure, and a verified communication path to the remote repository on GitHub. When these pieces are configured consistently across a team, collaboration becomes almost invisible: people clone, branch, commit, and push without thinking about it. When they are configured inconsistently, teams lose entire weeks to "it works on my machine," broken file paths, rejected pushes, and commits attributed to the wrong person. This topic walks through each layer of the setup, explains why each configuration choice matters, and ends with a concrete end-to-end verification procedure that every individual must complete independently.

Choosing a Code Editor

A code editor is the primary interface to the project, so the choice has a real effect on productivity and on how easily teammates can help each other. The practical recommendation for most teams — and the default assumption for the rest of this module — is Visual Studio Code (VS Code). It is free, it runs on Windows, macOS, and Linux with a near-identical interface, and it is overwhelmingly common in both industry and education. That ubiquity matters: when a teammate says "open the Command Palette and run Git: Clone," everyone knows exactly what that means, and the same keyboard shortcuts and screenshots work for the whole group.

It is worth distinguishing an editor from a full IDE. A traditional IDE such as IntelliJ IDEA or Visual Studio ships with a compiler toolchain, debugger, profiler, and project model bundled in. VS Code starts as a lightweight editor and becomes an IDE through extensions — you add only the language tooling you actually need. Other reasonable choices exist, and the table below summarizes the trade-offs, but a team should pick one primary editor and document it.

EditorCostPlatformsBest suited toMain trade-off
VS CodeFree, open source coreWindows, macOS, Linux, browserWeb, Python, JavaScript, general-purpose, student teamsNeeds extensions for deep language support
JetBrains IDEs (IntelliJ, PyCharm, WebStorm)Paid (free student licences, free Community editions)Windows, macOS, LinuxLarge Java/Kotlin/Python codebases, heavy refactoringHeavier, slower startup, licence management
Visual StudioFree Community editionWindows (limited macOS)C#/.NET, C++ on WindowsPlatform-limited; large install
Neovim / VimFreeAll, including over SSHRemote servers, keyboard-driven workflowsSteep learning curve; hard to standardize across a team

Extensions. Extensions are what turn a generic editor into a project-specific workbench. They fall into a handful of recognizable categories:

  • Language support — syntax highlighting, IntelliSense/autocomplete, go-to-definition, and inline type errors. Examples: the official Python extension (which bundles Pylance), ESLint for JavaScript/TypeScript, C/C++ from Microsoft, Extension Pack for Java.
  • Linters — tools that flag suspicious or non-conforming code before it runs: unused variables, undefined names, shadowed parameters. ESLint, Pylint, Ruff, and Flake8 are typical.
  • Formatters — tools that rewrite code into a canonical style automatically: Prettier for web languages, Black for Python, clang-format for C/C++. Formatters are the single highest-value team extension because they eliminate whitespace-only diffs and style arguments in code review.
  • Version control helpers — GitLens (blame annotations and history), GitHub Pull Requests and Issues (review PRs without leaving the editor).
  • AI assistance — GitHub Copilot, Copilot Chat, or similar tools that suggest completions and explain code. These are productivity aids, not authorities: suggestions must still be read, tested, and understood, and many courses or employers have explicit policies about their use.
  • Collaboration and environment — Live Share for pair programming, Dev Containers and Remote–SSH for working inside containers or on remote machines.

Sharing a recommended extensions list. Rather than telling teammates in chat which extensions to install, commit the list to the repository. VS Code reads a file at .vscode/extensions.json and, when someone opens the folder, prompts them to install anything missing. This makes the toolchain part of the project itself, versioned alongside the code.

// .vscode/extensions.json
{
  "recommendations": [
    "ms-python.python",
    "ms-python.vscode-pylance",
    "charliermarsh.ruff",
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    "eamodio.gitlens",
    "github.vscode-pull-request-github"
  ],
  "unwantedRecommendations": []
}

Pair it with a committed .vscode/settings.json so that formatting behaviour is identical for everyone — otherwise one person's editor reformats a whole file on save and the pull request becomes unreviewable:

// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.tabSize": 2,
  "files.eol": "\n",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.tabSize": 4
  }
}

A complementary .editorconfig file at the repository root does the same job for teammates on other editors, since EditorConfig is supported natively or via plugin almost everywhere.

Installing and Configuring Git Locally

Git is the version control system; GitHub is a hosting service for Git repositories. Installing Git gives you the command-line program git, which is what actually performs clones, commits, merges, and pushes — the editor's buttons are just a friendly front end for those same commands.

  • Windows: install Git for Windows from git-scm.com, which also provides Git Bash (a Unix-like shell) and the Git Credential Manager. Alternatively winget install Git.Git.
  • macOS: brew install git, or trigger Apple's Command Line Tools with xcode-select --install. The system Git is often an old version; Homebrew's is current.
  • Linux: sudo apt install git (Debian/Ubuntu) or sudo dnf install git (Fedora).

Confirm the install before going further:

$ git --version
git version 2.45.1

Identity configuration. Every Git commit permanently records an author name and email in its metadata. If you skip this step, Git either refuses to commit or guesses from your machine's hostname, producing commits attributed to student@LAPTOP-7F3K2. Those commits will not link to your GitHub profile, will not appear in contribution graphs, and — in a graded group project — may not be credited to you at all. Set the identity once, globally:

$ git config --global user.name "Amara Okafor"
$ git config --global user.email "amara.okafor@university.edu"
$ git config --global init.defaultBranch main
$ git config --global pull.rebase false
$ git config --global core.autocrlf input    # on macOS/Linux; use 'true' on Windows
$ git config --list --show-origin            # verify, and see which file each value came from

The email must be one that is registered on your GitHub account (Settings → Emails), otherwise GitHub cannot associate the commit with your profile. If you prefer not to publish a personal address, enable email privacy on GitHub and use the supplied 12345678+username@users.noreply.github.com address instead. For a repository that needs a different identity (e.g. a work account), omit --global inside that repository to set a local override.

SSH key authentication. There are two ways to talk to GitHub: HTTPS, which requires a personal access token typed or cached as a password, and SSH, which uses a public/private key pair. SSH is preferred because the private key never leaves your machine, nothing password-like is transmitted, the key can be protected by a passphrase held in an agent, and you can revoke a single device's key without changing anything else. HTTPS tokens, by contrast, are bearer secrets that can be accidentally pasted into a chat, committed to a file, or captured by a shoulder-surfer; classic GitHub account passwords have not been accepted for Git operations since 2021 at all.

$ ssh-keygen -t ed25519 -C "amara.okafor@university.edu"
# Press Enter to accept ~/.ssh/id_ed25519, then set a passphrase

$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_ed25519

$ cat ~/.ssh/id_ed25519.pub        # copy this PUBLIC key only
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... amara.okafor@university.edu

Paste the public key (the .pub file) into GitHub → Settings → SSH and GPG keys → New SSH key. Never share or commit the private key, which has no extension. Then test the connection:

$ ssh -T git@github.com
Hi amara-okafor! You've successfully authenticated, but GitHub does not provide shell access.

That message is the success case — the "does not provide shell access" part is expected and not an error.

AspectHTTPS + personal access tokenSSH key pair
What is sentA reusable secret tokenA cryptographic signature; the key itself never leaves the device
Setup effortLow — works immediately, token generated on GitHubModerate — generate key, add to agent, upload public half
RevocationRevoke token (may affect several machines)Delete one key; other devices unaffected
Firewall friendlinessWorks on port 443 almost everywherePort 22 sometimes blocked; can fall back to ssh.github.com:443
ExpiryTokens typically expire and must be regeneratedKeys do not expire

Cloning. git clone downloads the full repository — every file, branch, and commit in its history — and sets up a remote named origin pointing back at GitHub. This is how each team member gets their own complete working copy:

$ cd ~/projects
$ git clone git@github.com:team-aurora/inventory-tracker.git
Cloning into 'inventory-tracker'...
remote: Enumerating objects: 248, done.
Receiving objects: 100% (248/248), 1.21 MiB | 4.02 MiB/s, done.

$ cd inventory-tracker
$ git remote -v
origin  git@github.com:team-aurora/inventory-tracker.git (fetch)
origin  git@github.com:team-aurora/inventory-tracker.git (push)
$ git log --oneline -3

If you already cloned over HTTPS and want to switch, you do not need to re-clone: git remote set-url origin git@github.com:team-aurora/inventory-tracker.git.

Cloud Development with GitHub Codespaces

GitHub Codespaces provides a development environment that runs on a GitHub-hosted virtual machine and is accessed either through the browser or by connecting your desktop VS Code to it. The entire toolchain — compilers, runtimes, package managers, Git itself — lives on that remote machine. This changes several things that routinely derail team setups:

  • The local operating system stops mattering. A teammate on a locked-down school Windows laptop, another on an M-series Mac, and a third on a Chromebook all get the same Linux container. Platform-specific breakages — PowerShell versus Bash commands, missing build tools, CRLF line endings, a Python version that is two releases behind — simply do not arise.
  • No local install burden. Nothing has to be installed with administrator rights, which is decisive on managed lab or corporate machines.
  • Built-in GitHub integration. A codespace is created from a repository, so the clone is already done, authentication is already in place via a scoped token, and git push works immediately with no SSH key setup. Forwarded ports let you preview a running web server in the browser, and the port can be shared privately with teammates.
  • Disposability. If an environment gets into a broken state, delete the codespace and recreate it in a couple of minutes.

The trade-offs are real too: codespaces consume a monthly quota of core-hours and storage (generous on free and education plans, but finite), they require a reliable internet connection, and they stop automatically after a period of inactivity, so uncommitted work should not be left sitting indefinitely.

The devcontainer configuration. The mechanism that makes a codespace reproducible is a file at .devcontainer/devcontainer.json, committed to the repository. It declares the base image, additional tooling ("features"), VS Code extensions and settings, forwarded ports, and commands to run after creation. Because it is version-controlled, every teammate — and every future contributor — gets a byte-identical environment, and changes to it are reviewed like any other code change. The same file also works locally with the Dev Containers extension plus Docker, so people can run the identical container on their own machine.

// .devcontainer/devcontainer.json
{
  "name": "Inventory Tracker",
  "image": "mcr.microsoft.com/devcontainers/python:3.12",
  "features": {
    "ghcr.io/devcontainers/features/node:1": { "version": "20" },
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "charliermarsh.ruff",
        "esbenp.prettier-vscode",
        "eamodio.gitlens"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "forwardPorts": [8000],
  "postCreateCommand": "pip install -r requirements.txt && npm ci",
  "remoteUser": "vscode"
}

With this in place, a new team member's onboarding is: open the repository on GitHub → Code → Codespaces → Create codespace on main. Two minutes later they have Python 3.12, Node 20, all dependencies installed, the agreed extensions loaded, and port 8000 forwarded — with no instructions to follow and nothing to get wrong.

Project Folder Structure and Conventions

A repository's layout is a form of documentation. If a newcomer can guess where things live, they can contribute; if files are scattered at the root with names like final_v2_REAL.py, every change becomes archaeology. Agree on a structure in week one, write it into the README.md, and create the directories immediately — even if some are nearly empty — so that the first commits land in the right place.

inventory-tracker/
├── README.md               # what it is, how to set up, how to run, folder map
├── LICENSE
├── .gitignore
├── .editorconfig
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── .devcontainer/
│   └── devcontainer.json
├── .github/
│   └── workflows/ci.yml    # automated tests on every push
├── src/                    # application source code only
│   ├── models/
│   ├── services/
│   └── main.py
├── tests/                  # mirrors src/ structure
│   ├── test_models.py
│   └── test_services.py
├── assets/                 # images, fonts, sample data, icons
├── docs/                   # design notes, meeting minutes, API reference
└── scripts/                # one-off or utility scripts (seeding, deploys)

Why separate source, assets, docs, and tests? Each directory has a different audience and lifecycle. Separating them means you can run the whole test suite with one path (pytest tests/), package or deploy only src/, let non-developers edit docs/ without touching code, keep large binary assets out of the import path, and configure tooling cleanly — linters scan src/ and tests/, the bundler reads assets/. It also makes code review diffs legible: a pull request touching only docs/ obviously carries no runtime risk.

Document it in the README from day one. The README is the first thing anyone reads. It should contain, at minimum: a one-paragraph description of the project, prerequisites, setup commands, how to run the app and the tests, and a short folder map explaining what belongs in each directory. A folder structure that exists only in one person's head is not a convention — it is a bottleneck.

File naming conventions and case sensitivity. This is the single most common source of baffling cross-platform bugs. Linux file systems are case-sensitive: UserCard.js and usercard.js are two different files. Windows and the default macOS file system are case-insensitive but case-preserving: they treat those names as the same file. So a developer on macOS can write import Card from './components/userCard' while the file is actually named UserCard.js, commit it, and everything works locally — then the Linux CI build or the Codespaces container fails with "module not found." Worse, renaming usercard.js to UserCard.js on a case-insensitive system may not even register as a change in Git unless you use git mv or enable core.ignorecase=false.

Practical rules that avoid the whole class of problem:

  • Pick one convention per file type and record it in the README: kebab-case for web assets and URLs (user-card.css), snake_case for Python modules (user_card.py), PascalCase for class/component files where the framework expects it (UserCard.tsx).
  • Never rely on case alone to distinguish two files.
  • Avoid spaces and special characters in filenames — they break shell commands and URLs. Use hyphens or underscores.
  • Keep paths reasonably short; Windows historically limits total path length to 260 characters.
  • Make imports exactly match the on-disk spelling, every time.
  • Use a .gitignore from the start so that node_modules/, __pycache__/, .venv/, .env, dist/, and .DS_Store never enter the history. Committed secrets and build artefacts are painful to remove later.

Verifying the Complete Setup

Installing things is not the same as proving they work together. The purpose of verification is an end-to-end test: a tiny change that travels from the editor, through local Git, over the authenticated connection, into the GitHub repository, and back down to a teammate. Only a round trip proves that all four links in the chain — editor, Git, credentials, repository permissions — are sound.

A workable verification script for each person:

  • Confirm the tools exist: git --version and, if relevant, python --version / node --version.
  • Confirm identity: git config user.name and git config user.email return your real details.
  • Confirm authentication: ssh -T git@github.com greets you by your GitHub username.
  • Clone the team repository and open it in the editor; accept the recommended extensions prompt.
  • Create a branch, make a trivial but real change, commit, and push.
  • Open a pull request, have a teammate review and merge it, then pull the merged result back down.
$ git switch -c setup/amara-verify
$ echo "- Amara Okafor — environment verified $(date +%F)" >> docs/team-roster.md
$ git add docs/team-roster.md
$ git commit -m "chore: verify local environment for Amara"
$ git push -u origin setup/amara-verify
$ gh pr create --fill          # or open the PR in the browser

# after the PR is merged
$ git switch main
$ git pull
$ git log --oneline -1         # your commit should be at the tip

A useful team artefact is a docs/team-roster.md or a checklist issue in which each person appends their own line as part of the exercise. The file itself then becomes the evidence that the verification happened: if a name is missing, that person's setup is unproven.

Catch authentication and permission errors in week one. Setup failures are cheap to fix on day three and expensive to fix the night before a deadline, because they block the delivery of work that is already finished. The most common failures and their usual causes are predictable enough to triage quickly:

SymptomLikely causeFix
Permission denied (publickey)SSH key not generated, not added to the agent, or public key not uploaded to GitHubRe-run ssh-add ~/.ssh/id_ed25519; confirm the key is listed in GitHub settings; test with ssh -T git@github.com
remote: Permission to org/repo.git denied to userNot a collaborator on the repository, or authenticated as the wrong accountRepository owner adds the user as a collaborator; check cached credentials in the OS credential manager
Support for password authentication was removedUsing an account password over HTTPSSwitch the remote to SSH, or use a personal access token
Commits show the wrong author or no avataruser.email not set, or not registered on the GitHub accountgit config --global user.email with a verified or noreply GitHub address
! [rejected] main -> main (fetch first)Remote has commits you do not have locallygit pull (resolve any conflict), then push again
CI passes locally but fails in the cloud with "module not found"Filename case mismatch between the import and the file on diskgit mv the file to the correct casing and fix the import

Everyone verifies independently. It is tempting for the most confident member of a team to set things up, push the first commit, and declare the environment "working." That proves exactly one person's configuration. Authentication, identity, permissions, installed runtimes, and operating-system quirks are all per-machine and per-account, so a single successful push says nothing about the other four people. Make individual verification an explicit deliverable: each member pushes their own branch from their own machine under their own GitHub account, and the team confirms that every name appears in the commit history before any feature work begins. The cost is fifteen minutes each; the alternative is discovering in week six that one teammate has been emailing zip files because their push has never once worked.

Notes<p>Suggested in-class sequence: (1) install/confirm Git and VS Code, (2) configure identity, (3) generate and upload an SSH key, (4) clone the team repo, (5) each student pushes a one-line addition to <code>docs/team-roster.md</code> via a pull request. Completion is checked by inspecting the commit history for every student's verified GitHub identity.</p> <p>Instructor cautions: the <code>core.autocrlf</code> value differs by platform (<code>true</code> on Windows, <code>input</code> elsewhere); committing <code>.vscode/settings.json</code> is a team decision — some teams commit only <code>extensions.json</code> and leave personal preferences uncommitted; Codespaces quotas vary by plan, so confirm the course's allocation before relying on it exclusively.</p> <p>Possible extensions to the material: adding a <code>.gitattributes</code> file to force line endings, enabling branch protection on <code>main</code>, and wiring a minimal GitHub Actions workflow so that the week-one verification push also proves CI works.</p>
2

Videos on This Topic

▶

Before you can design or evaluate an interface, you need a place to build it. This topic walks you through setting up the tools your team will use all semester: a code editor, Git for version control, a GitHub repository for sharing work, and GitHub Codespaces as a cloud-based option when a local setup is inconvenient or when a teammate's machine won't cooperate. You will also establish a sensible project folder structure and naming conventions, then verify that everything works end to end by making a change, committing it, and pushing it.

This matters because your course project is a team effort. Version control is what lets several people edit the same project without overwriting each other, and it gives you a history you can roll back to when an experiment goes wrong. Agreeing on a folder structure and workflow now saves hours of confusion later, and it is a skill employers assume you already have.

As you watch, focus on the sequence of actions rather than memorizing menus: initialize or clone a repository, stage changes, commit with a clear message, push, and pull. Notice where each tool overlaps (the editor's Git panel versus the command line versus the browser) and pick the path you will actually use. Pause and perform each step on your own machine or in a Codespace as you go, and finish by confirming that your commits appear on GitHub.

3

Video 1: Using Git with Visual Studio Code (Official Beginner Tutorial)

▶

Visual Studio Code · 6:56 · 1,982,388 views · 4y ago · captions — Watch on YouTube

About this video

An official Visual Studio Code tutorial that demonstrates Git basics directly inside the editor, including initializing a repository, renaming a branch, and working with the built-in source control interface. The chapter markers suggest a step-by-step walkthrough of the common commit-and-push cycle without needing to memorize terminal commands. It is short and demonstration-driven, so you can follow along in your own editor.

Why this video

It comes from the VS Code team itself, so the interface shown matches the editor most students will install, and it directly covers both the choosing-an-editor and installing-and-configuring-Git-locally subtopics.

4

Video 2: How to create your first GitHub repository: A beginner's guide | Tutorial

▶

GitHub · 9:32 · 332,965 views · 2y ago · captions — Watch on YouTube

About this video

A beginner-oriented guide from GitHub that breaks down creating your first repository, covering the setup options you choose when a repo is made and the first steps of getting content into it. Expect coverage of the repository's role as the shared home for a team's code and files. The pacing is aimed at people who have never used GitHub before.

Why this video

Produced by GitHub, it is authoritative on the platform your team will use for collaboration, and it fills the gap between a local Git setup and a shared remote repository where folder structure and conventions begin to matter.

5

Video 3: VS Code in the Cloud with GitHub Codespaces - CS50 Educator Workshop 2022

▶

CS50 · 16:09 · 16,800 views · 4y ago · captions — Watch on YouTube

About this video

A CS50 workshop session introducing GitHub Codespaces, a browser-based development environment that runs VS Code in the cloud. It is framed for educators and students, so it likely explains why a hosted environment removes installation headaches and how a Codespace connects to a GitHub repository. Expect a tour of launching and working inside a Codespace.

Why this video

It is the clearest fit for the cloud development subtopic and offers a practical fallback for teammates whose local setup fails, delivered by a well-known and reliable course production team.

6

How These Videos Support the Learning Outcomes

▶

These videos are the hands-on counterpart to the module's conceptual outcomes. While MO1 and MO2 ask you to recall HCI principles and distinguish usability, user experience, and accessibility, you need a working environment in which to apply those ideas to the course project, and the VS Code and GitHub tutorials give you that foundation. The Codespaces session supports MO3 most directly: knowing whether your team will work locally, in the cloud, or both is part of defining platform and team roles in your initial project plan, and a shared repository is where scope, task assignments, and project files are recorded and tracked.

7

About These Videos

▶

These videos were chosen from YouTube on October 3, 2026. Each has captions; the player turns them on. Videos on YouTube can be changed or removed — if one no longer plays, tell your instructor. If a player does not appear, use its Watch on YouTube link.