Backend Runtimes and Versions You Can Use
Backend Capsules automatically detect your application's language from project files (for example, package.json for Node.js or requirements.txt for Python), install dependencies, and build a runnable image. This page lists the language versions Code Capsules currently supports.
Runtime versions are resolved at build time, not baked into the platform image. When you pin a version line, each build uses the latest patch available on that line. When you do not pin a version, Code Capsules falls back to the platform default line for that language — again using the latest patch on that line when the build runs.
Each language uses a different pin format. A line pin must use the wildcards or version pattern shown in the table below.
Platform
| Property | Value |
|---|---|
| Operating system | Ubuntu 22.04 LTS |
| Language detection | Automatic — from project configuration files in your repository |
Code Capsules inspects version hints in your project (for example, the engines field in package.json or a .python-version file). Each build resolves a runtime version in this order:
- Your app's explicit pin (project file or environment variable)
- The platform default line for that language (if no pin exists)
Unpinned applications use the latest patch release on the platform default line at build time. This is not a fixed version — if a newer patch is available when your build runs, that version is used. Code Capsules does not move unpinned apps to a new major or minor line when upstream releases one — that only happens when the platform is upgraded.
To receive the latest patch on a specific line automatically, pin using that language's line format from the table below. To lock every build to the same release, pin an exact version instead.
Supported language runtimes
The table below lists each supported version line, the platform default when your project does not specify a version, and the format to use when pinning a line.
| Language | Supported version lines | Unpinned default | Line pin format |
|---|---|---|---|
| Node.js | 18.x.x, 20.x.x, 22.x.x, 24.x.x | Latest patch on 24.x | 24.x.x in package.json |
| Python | 3.10.x, 3.11.x, 3.12.x, 3.13.x | Latest patch on 3.13.x | 3.13 in .python-version |
| Go | 1.x | Latest patch on 1.25.x | 1.25.x via GOOGLE_GO_VERSION |
| Java | 11, 17, 21 | Latest patch on 21 | 21 via GOOGLE_RUNTIME_VERSION |
| Ruby | 3.1.x, 3.2.x, 3.3.x, 3.4.x | Latest patch on 3.4.x | ruby 3.4.9p0 in Gemfile.lock, or 3.4.9 via env var |
| PHP | 8.1.x, 8.2.x, 8.3.x, 8.4.x | Latest patch on 8.4.x | 8.4.* in composer.json |
| .NET | 6.x, 7.x, 8.x | Latest patch on 8.x | 8.*.* in global.json or env var |
If your application requires a runtime or OS package not listed above, deploy with a Docker Capsule and your own Dockerfile.
Pin a runtime version
Where supported, specify the runtime your application needs in your project configuration. Go and Java use an environment variable in the Config tab.
After changing a version pin, trigger a rebuild from the Deploy tab for the change to take effect. For file-based pins, push a new commit first.
Node.js
Add an engines field to package.json. Use the major.minor.x pattern with .x placeholders to receive the latest patch on that line on each build:
{
"engines": {
"node": "24.x.x"
}
}
Pin an exact version when you need every build to use the same release:
{
"engines": {
"node": "24.18.0"
}
}
You can also set GOOGLE_NODEJS_VERSION in the Config tab (for example, 24.x.x). If both are set, the environment variable takes precedence.
Python
Create a .python-version file in your project root. Use a major.minor value to receive the latest patch on that line:
3.13
Pin an exact patch version when you need every build to use the same release:
3.13.7
You can also set GOOGLE_PYTHON_VERSION in the Config tab using the major.minor.x pattern (for example, 3.13.x). If both are set, the environment variable takes precedence.
Go
Go does not support version pinning through project files. In the Config tab, add the GOOGLE_GO_VERSION environment variable. Use the major.minor.x pattern to receive the latest patch on that line (for example, 1.25.x). See Configure for steps.
Trigger a rebuild from the Deploy tab after saving the variable. The updated Go version applies on the next build.
Pin an exact version (for example, 1.25.4) when you need every build to use the same release.
The go directive in go.mod sets the minimum language version for your module but does not select the compiler used during the build.
Java
Java does not support version pinning through project files. In the Config tab, add the GOOGLE_RUNTIME_VERSION environment variable and set it to the JDK feature version you need (for example, 21). See Configure for steps.
Use a major version number only — not a patch release such as 21.0.11. The platform resolves the latest patch on that JDK line at build time.
Trigger a rebuild from the Deploy tab after saving the variable. The updated JDK version applies on the next build.
Maven or Gradle compiler settings control compilation targets but do not select the JDK installed during the build.
Ruby
With Bundler: commit a Gemfile.lock that includes a RUBY VERSION entry. The platform uses the locked version and resolves the latest patch on that line:
RUBY VERSION
ruby 3.4.9p0
Without Bundler: set GOOGLE_RUNTIME_VERSION in the Config tab to an exact patch version (for example, 3.4.9). See Configure for steps.
If you use Bundler, GOOGLE_RUNTIME_VERSION cannot override the version in Gemfile.lock.
PHP
Set the PHP version in composer.json. Use the major.minor.* pattern with an asterisk to receive the latest patch on that line:
{
"require": {
"php": "8.4.*"
}
}
Semver operators such as ^8.4 are not equivalent to a line pin — use the 8.4.* format when you want the latest patch on the 8.4.x line on each build.
.NET
Create a global.json in your project root. Use the major.*.* pattern to receive the latest patch on that SDK line:
{
"sdk": {
"version": "8.*.*"
}
}
Pin an exact SDK version when you need reproducible builds:
{
"sdk": {
"version": "8.0.401"
}
}
You can also set GOOGLE_DOTNET_SDK_VERSION or GOOGLE_RUNTIME_VERSION in the Config tab.
Platform upgrades and pins
| Scenario | Behaviour |
|---|---|
| Platform moves to a new default line, app unpinned | App uses the new default line on the next build |
| Platform moves to a new default line, app pinned to a version line | App continues using the pinned line |
| New major release published upstream, app unpinned | App stays on the current platform default until Code Capsules upgrades the platform |
| Patch release on your pinned line, app pinned to that line | App uses the newer patch on the next build |
| Patch release on your pinned line, app pinned to an exact version | App continues using the exact pinned version |
Common frameworks
These frameworks are commonly deployed on Backend Capsules. Framework versions come from your dependency files, not from the platform.
| Framework | Language | Deployment guide |
|---|---|---|
| Express.js | Node.js | Express.js |
| Django | Python | Django |
| Flask | Python | Flask |
| Java (Spring and others) | Java | Java |
| Go | Go | Go |
Server-side JavaScript frameworks
Applications that need a persistent Node.js server at runtime — including SSR and full-stack frameworks — belong on a Backend Capsule or a Docker Capsule, not a Frontend Capsule.
| Framework | Capsule type | Guide |
|---|---|---|
| Next.js (with server) | Backend Capsule | Next.js |
| Nuxt with Nitro | Backend Capsule | Nuxt3 and Nitro |
Applications outside supported runtimes
If you need a runtime, OS package, or build step not listed above, deploy with a Docker Capsule and your own Dockerfile.
Related
- Build and Deploy — language and framework deployment guides
- Configure — run command, port, and environment variables
- Add a Procfile — custom process definitions for Python and other apps