GitHub Codespaces and Dev Containers

Start a complete development environment in the cloud with GitHub Codespaces, configure it with a devcontainer.json, forward ports to preview your app, and manage usage and costs.

Lesson 19 of 30Advanced17 min read

Getting a project running on a new computer can take hours. Install the right version of Node.js or Python, set up a database, add editor extensions, copy configuration, and discover that something only works on the original developer's machine. For a new team member, or for a quick fix on a project you don't usually work on, that setup time is a real cost.

GitHub Codespaces gives you a complete development environment in the cloud, created from a repository in about a minute. It runs on a virtual machine with the project's tools already installed, and you work in VS Code, either in your browser or in the desktop app. Your own computer only needs a web browser.

In this lesson you'll create a codespace, configure it with a dev container file, preview a running app, use secrets safely and keep an eye on usage.

Creating a codespace

On a repository page, click the green Code button, open the Codespaces tab and choose Create codespace on main. GitHub then:

  1. Starts a virtual machine for you.
  2. Builds a container from the repository's dev container configuration, or a general-purpose default image with common languages if there isn't one.
  3. Clones the repository and opens VS Code in your browser.

You get a full terminal, Git already signed in as you, and every VS Code feature. Changes stay in the codespace until you commit and push them, just like on your own computer. You can also open the same codespace in desktop VS Code, or create one from the terminal with gh codespace create.

Dev containers

A dev container describes the development environment in a file at .devcontainer/devcontainer.json:

  • image: the base system, such as a Node.js or Python image.
  • features: extra tools added in one line each, such as the GitHub CLI or Docker.
  • postCreateCommand: a command run once after creation, such as npm install.
  • customizations: VS Code extensions and settings to install automatically.
  • forwardPorts: ports to make available, such as 3000 for a web app.

Because the file is committed, every codespace, and every teammate using the Dev Containers extension locally, gets an identical setup. "It works on my machine" becomes "it works in the container".

Ports, secrets and github.dev

When your app starts a server, for example on port 3000, Codespaces forwards the port and offers a link to preview it in your browser. Forwarded ports are private to you by default; you can make one visible to your organization or public for a quick demo.

Store API keys as Codespaces secrets (in your account settings, or the repository's settings for shared ones). They appear as environment variables inside the codespace, never in the repository.

For tiny edits, press . on any repository page to open github.dev: VS Code in the browser with no virtual machine. It can edit, commit and open pull requests, but it has no terminal and can't run code.

Stopping, deleting and costs

Codespaces are billed by compute time (the machine's size multiplied by how long it runs) and storage. Personal accounts include a monthly allowance; organizations set budgets and limits.

  • A codespace stops automatically after a period of inactivity, 30 minutes by default. A stopped codespace keeps your files but uses no compute time.
  • Stop one yourself when you've finished with gh codespace stop or from the codespaces list.
  • Delete codespaces you no longer need: unpushed changes in them are lost, so push first. Inactive ones are deleted automatically after a retention period.

GitHub Codespaces Syntax

Codespaces essentials

gh codespace create --repo samlee/recipe-box
gh codespace list
gh codespace code          # open in desktop VS Code
gh codespace ssh           # open a terminal in it
gh codespace stop
gh codespace delete
.devcontainer/devcontainer.json   environment definition
Code > Codespaces > Create codespace on main
Press . on a repository page      github.dev quick editor

GitHub Codespaces Summary

  • A codespace is a cloud development environment created from a repository, opened in VS Code.
  • .devcontainer/devcontainer.json defines the image, tools, extensions and setup commands.
  • Forwarded ports let you preview running apps; ports are private by default.
  • Store secrets as Codespaces secrets, never in the repository.
  • Codespaces use compute time while running: stop them when idle and delete them when done. Press . for github.dev quick edits.

GitHub Codespaces Examples

Each example shows the code, the output it produces and what each part does.

Example 1

A devcontainer.json for a web project

JSON
{
  "name": "Recipe Box",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "postCreateCommand": "npm install",
  "forwardPorts": [3000],
  "customizations": {
    "vscode": {
      "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
    }
  }
}
Output
Every new codespace for this repository starts with:
  Node.js 20, npm and the GitHub CLI installed
  dependencies already installed by npm install
  ESLint and Prettier extensions in VS Code
  port 3000 ready to preview
Line-by-line explanation
  1. Line 3A ready-made image with Node.js 20, maintained by the dev containers project.
  2. Lines 4 to 6Features add tools on top of the image, here the gh command.
  3. Line 7Runs once after the container is created.
  4. Line 8Port 3000 is forwarded automatically when the app starts.
  5. Lines 9 to 13Extensions every contributor needs are installed for them.
Example 2

Working in a codespace from the terminal

Terminal
gh codespace create --repo samlee/recipe-box --branch main --machine basicLinux32gb
gh codespace list
gh codespace stop --codespace samlee-recipe-box-x7q9
Output
✓ Codespaces usage for this repository is paid for by samlee
samlee-recipe-box-x7q9
NAME                      DISPLAY NAME     REPOSITORY          BRANCH  STATE      CREATED AT
samlee-recipe-box-x7q9    curly broccoli   samlee/recipe-box   main    Available  about 1 minute ago
✓ Stopped codespace samlee-recipe-box-x7q9
Line-by-line explanation
  1. Line 1Create a codespace on a chosen branch and machine size. Bigger machines cost more per hour.
  2. Line 2List your codespaces and their state: Available means running.
  3. Line 3Stop it when you take a break, so it stops using compute time.
Example 3

Previewing an app on a forwarded port

Terminal
npm run dev
Output
  VITE v5.2.0  ready in 412 ms
  ➜  Local:   http://localhost:3000/

[Codespaces] Your application running on port 3000 is available.
             Open in Browser  |  Make Public
Line-by-line explanation
  1. Line 1Start the app inside the codespace as you would on your own computer. Codespaces notices the port and offers a private preview link in a new browser tab; Make Public shares it for a quick demo, so switch it back afterwards.

Common GitHub Codespaces Mistakes

Leaving codespaces running

Don't
Ten codespaces created for quick fixes, never stopped or deleted
Do
Push your work, then stop or delete the codespace; set a short idle timeout

Secrets in devcontainer.json

Don't
{ "containerEnv": { "STRIPE_KEY": "my-real-key-123" } }
Do
Add STRIPE_KEY as a Codespaces secret in the repository or account settings

Deleting a codespace with unpushed work

Don't
gh codespace delete        # commits that were never pushed are gone
Do
git push
gh codespace delete

GitHub Codespaces in Real Projects

Codespaces in practice

Teams use Codespaces so new developers can contribute on their first morning, and educators give every student an identical environment. The same devcontainer.json also works locally with Docker and the VS Code Dev Containers extension.

GitHub Codespaces FAQ

Can I open a codespace in VS Code on my computer?

Yes. Install the GitHub Codespaces extension in VS Code, sign in, and connect to a codespace. The editor runs on your computer while the code, terminal and tools run in the cloud, so you keep your own keyboard shortcuts and settings.

What happens to my work when a codespace stops?

Stopping keeps everything, including uncommitted changes, and you can restart the codespace later. Deleting it removes everything that wasn't pushed. Stopped codespaces are also deleted automatically after a period of inactivity, so push your work regularly.

How long before an idle codespace stops?

By default, a codespace stops after 30 minutes without activity, which saves your free allowance. You can change the default idle timeout in your Codespaces settings. Work in the codespace is kept when it stops.

Can I choose a more powerful machine for a codespace?

Yes. When you create a codespace, you can pick a machine type with more CPU cores and memory, and you can change the machine type of an existing codespace too. Larger machines use your allowance faster, so choose the smallest one that runs your project comfortably.

Can I create a codespace for a repository I don't own?

Yes, for public repositories. You can run and edit the code, but you can't push to the original. When you try to commit and push, Codespaces offers to create a fork for your changes, so you can open a pull request from it.

GitHub Codespaces Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the path of the dev container configuration file.

.devcontainer/
Multiple choiceeasy

What is a codespace?

Multiple choicemedium

Which devcontainer.json setting runs npm install after the container is created?

Multiple choicemedium

What happens to a codespace you stop?

Multiple choicehard

How should an API key be made available inside a codespace?

GitHub Codespaces Quiz

5 questions to check what you learned.

  1. Which key opens github.dev on a repository page?

    • /
    • . (full stop)
    • g
    • Ctrl + G
  2. What can github.dev not do?

    • Edit files
    • Commit changes
    • Open pull requests
    • Run code or open a terminal
  3. Are forwarded ports public by default?

    • Yes
    • Only port 80
    • No, they're private to you unless you change them
    • Only in organizations
  4. How are Codespaces mostly billed?

    • By compute time while running, plus storage
    • Per commit
    • Per repository
    • They're always unlimited
  5. Why commit a devcontainer.json to the repository?

    • It's required for Git
    • It makes the repository private
    • Every codespace and teammate gets the same tools, versions and extensions automatically
    • It replaces package.json