Configuring Codespaces Prebuilds in GitHub Actions
An unprebuilt Codespace does the full build on create, which is slow. This page configures prebuilds so the expensive stages are baked ahead of time for the branches developers open, and refreshed automatically when the base image or Features change.
Prerequisites
You need a repo with Codespaces enabled and admin access.
- Codespaces enabled on the repository/org.
- Admin access to configure prebuilds.
- A committed
.devcontainer/config.
Step-by-Step Implementation
- Enable a prebuild for the branches developers open (repo Settings → Codespaces).
Settings -> Codespaces -> Set up prebuild -> choose branch + region
- Trigger on config changes so the prebuild never drifts.
Trigger: "On configuration change" (rebuilds when .devcontainer changes)
- Keep the config prebuild-friendly — heavy work in onCreateCommand.
{ "onCreateCommand": "npm ci", "remoteUser": "node" }
- Verify a new Codespace on that branch creates fast.
Common Pitfalls
Prebuild issues are stale prebuilds or heavy work outside onCreate.
| Symptom | Root Cause | Remediation |
|---|---|---|
| Create is slow despite prebuild | Prebuild not covering the branch | Add the branch to the prebuild |
| Prebuild uses a stale toolchain | Not triggered on config change | Trigger on configuration change |
| Prebuild storage cost high | Too many branches/regions | Limit to key branches/regions |
| Little speedup | Heavy work in postCreate | Move source-independent work to onCreate |
Conclusion
Prebuilds convert a per-create wait into a shared, cached build. Configure them for the branches developers open, trigger a refresh on .devcontainer changes so they never drift, and put source-independent setup in onCreateCommand so the prebuild captures it. Creates then take seconds.
FAQ
Which branches should I prebuild? The ones developers actually open — usually the default branch and long-lived feature branches — not every push. Prebuilding everything wastes storage; prebuilding the branches people create Codespaces from gives the speedup where it matters.
How do prebuilds stay current with my config?
Set the prebuild to trigger 'on configuration change' so it rebuilds whenever .devcontainer (the base image or Features) changes. That keeps the prebuilt image identical to a fresh build, so developers never get a stale toolchain.
Why isn't my prebuild speeding up create much?
Because most of the setup is in postCreateCommand, which runs after the mount and isn't baked into the prebuild. Move source-independent work (tool installs, Feature setup) into onCreateCommand, which the prebuild captures, leaving only source-dependent installs for create time.
Related
- Up to GitHub Codespaces vs Local DevContainers — the hosting overview.
- Codespaces Prebuild vs Local Rebuild Cost Comparison — the cost math.
- CI/CD Integration with DevContainers — the CI cousin of prebuilds.