Skip to main content
Copy-paste blueprints for common languages and use cases. Combine them to build your full configuration. Examples use Bash on Linux; replace sample hosts, scopes, and commands with your own. For a full breakdown of every field, see the Blueprint reference.
Secrets: Configure the named secrets in the Secrets tab within each blueprint editor. Build steps receive the applicable blueprint secrets. During a session, ensure each command receives the secrets it needs: repo-scoped secrets require explicit exec environment bindings, such as env={"REGISTRY_TOKEN": "secret:repo:owner/repo:REGISTRY_TOKEN"}. See Secrets. Never hardcode credentials in your blueprint.
Build steps are not session startup hooks. initialize and maintenance run while building snapshots; maintenance is not automatically run at session start. knowledge supplies instructions to Devin, not executable hooks.Keep credentials out of persistent files, including $ENVRC. Snapshot cleanup removes Devin’s injected secret files, not arbitrary files written by your commands. Use literal variable references supported by the consuming tool, or pass credentials in the command’s environment. When a tool requires credential files, create them for one operation and clean them up before it finishes. Repeat that setup explicitly when needed in a session.

Quick start

Minimal blueprints for the most common setups. Copy one, paste it into the blueprint editor, and you’re done.

Repository blueprints

Per-repo build steps, dependency management, and knowledge entries. Set these in Settings > Environment > Blueprints > [your repo].

Python

Node.js

Standard Node.js setup with npm.
Use npm install (not npm ci) in maintenance. It does an incremental update, while npm ci deletes node_modules and reinstalls from scratch each time the command runs.

Go

Standard Go setup with modules.

Java

Java setup with Gradle.
JDK 17 is pre-installed on Devin’s base image. Skip the JDK install step if the default OpenJDK 17 is sufficient.

Ruby on Rails

Rails setup with PostgreSQL.

Rust

Standard Rust setup with cargo.
Rust (via rustup) and Cargo are pre-installed on Devin’s base image. Skip the install step if the default stable toolchain is sufficient. You only need the dependency fetch.

Monorepos

Monorepo with a Node.js frontend and Python backend. Each subproject gets its own knowledge entries.
Use subshells (cd dir && command) instead of cd dir && command so the working directory resets between steps.

Private package registries

Configure package managers to resolve dependencies from private registries. Set these in Settings > Environment > Blueprints > Org-wide setup (or per-repo if only one repo needs it).
Store references, not expanded credentials. Quoted heredoc delimiters such as <<'EOF' preserve variable references in the file. npm, Yarn Berry, Maven, and Gradle can resolve the references shown below when they run. pip does not expand shell variables in pip.conf, so use environment variables instead. Shell setup files must be explicitly sourced in the same command as the tool; do not assume a new shell sources them or refreshes credentials.URLs written directly to persistent configuration, such as a Cargo index, Docker mirror, or APT mirror, must not contain credentials. Keep authentication in the separate secrets shown by each template.If you used an older template that wrote credentials to disk, remove those files and rebuild from a clean base rather than a snapshot that contains them. Rotate credentials that may have been captured.
If your private registry uses a corporate CA, make sure the CA certificate is installed at the enterprise level first. The configuration below assumes HTTPS trust is already established.

Node.js registries

Configure npm to resolve scoped packages (e.g., @myorg/*) from a private registry, while public packages continue to come from the default npm registry.
  • GITHUB_PACKAGES_TOKEN — Personal access token or GitHub App token with read:packages scope
Replace @myorg with your npm scope. Common private registry URLs:
  • GitHub Packages: https://npm.pkg.github.com
  • Artifactory: https://artifactory.example.com/artifactory/api/npm/npm-virtual
  • Nexus: https://nexus.example.com/repository/npm-group
  • GitLab: https://gitlab.example.com/api/v4/packages/npm
  • AWS CodeArtifact: https://<domain>.d.codeartifact.<region>.amazonaws.com/npm/<repo>

Python registries

Configure pip and uv to resolve packages from your private PyPI registry (e.g., Nexus, Artifactory).
  • PYPI_REGISTRY_URL — Full URL of your PyPI index, including credentials if required (e.g., https://user:token@nexus.example.com/repository/pypi-proxy/simple)
To warm dependencies during a build, add the same source ... && command to maintenance after the configuration step. Percent-encode special characters in URL credentials.
Common PyPI registry URL patterns:
  • Artifactory: https://artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple
  • Nexus: https://nexus.example.com/repository/pypi-proxy/simple
  • AWS CodeArtifact: https://aws:TOKEN@domain-owner.d.codeartifact.region.amazonaws.com/pypi/repo/simple/
  • Azure Artifacts: https://pkgs.dev.azure.com/org/project/_packaging/feed/pypi/simple
  • GitLab: https://gitlab.example.com/api/v4/groups/<group-id>/-/packages/pypi/simple

JVM registries

Install JDK and configure Maven to mirror all dependency resolution through your private registry (e.g., Artifactory, Nexus).
JDK 17 is pre-installed on Devin’s base image. Skip the install step if the default OpenJDK 17 is sufficient. You only need the Maven install and registry configuration.
  • MAVEN_REGISTRY_URL — URL of your Maven registry (e.g., https://artifactory.example.com/artifactory/maven-virtual)
  • REGISTRY_USER — Registry username
  • REGISTRY_PASS — Registry password or API token
Common registry URL patterns for Maven:
  • Artifactory: https://artifactory.example.com/artifactory/maven-virtual
  • Nexus: https://nexus.example.com/repository/maven-public
  • Azure Artifacts: https://pkgs.dev.azure.com/org/project/_packaging/feed/maven/v1
  • GitHub Packages: https://maven.pkg.github.com
  • GitLab: https://gitlab.example.com/api/v4/groups/<group-id>/-/packages/maven
  • AWS CodeArtifact: https://<domain>.d.codeartifact.<region>.amazonaws.com/maven/<repo>

Other registries

Install Go and configure it to resolve modules through a private module proxy (e.g., Athens, Artifactory, or a GOPROXY endpoint).
  • GO_PROXY_URL — URL of your Go module proxy (e.g., https://athens.corp.internal)
Connect the Git provider and grant access to the repositories that host your private modules through Git integrations. Use ordinary HTTPS Git URLs with Devin’s configured authentication. Do not embed a token in a Git URL rewrite.
To warm the module cache during builds, add that command to the repository blueprint’s maintenance, where go.mod is available. Do not run it in org-wide setup, which runs before repositories are cloned.
Common Go proxy URL patterns:
  • Artifactory: https://artifactory.example.com/artifactory/go-virtual
  • Nexus: https://nexus.example.com/repository/go-proxy
  • Athens: https://athens.corp.internal
Configure NuGet to resolve packages from a private feed.
  • NUGET_SOURCE_URL — URL of your NuGet feed
  • NuGetPackageSourceCredentials_private — Feed credentials in NuGet’s environment format: Username=any;Password=<PAT> (use your feed’s required username)
Configure Docker to pull from a private container registry.Docker login can write credentials to its config directory. Use an isolated directory for each operation, and remove it even if the pull fails. Run the login-and-pull sequence again when you need another image in a session.
  • DOCKER_MIRROR_URL (optional) — URL of your Docker Hub mirror (e.g., https://mirror.corp.internal)
  • DOCKER_REGISTRY_URL — URL of your private container registry (e.g., registry.corp.internal:5000)
  • DOCKER_REGISTRY_USER — Registry username
  • DOCKER_REGISTRY_PASS — Registry password or API token
To cache an image in the snapshot, put the same complete subshell in a build step. Do not split login and cleanup across steps, and verify cleanup succeeds before imaging. A registry mirror URL must not contain credentials.
Common container registry URLs:
  • Amazon ECR: <account-id>.dkr.ecr.<region>.amazonaws.com
  • Azure Container Registry: <name>.azurecr.io
  • Google Artifact Registry: <region>-docker.pkg.dev
  • GitHub Container Registry: ghcr.io
  • GitLab Container Registry: registry.gitlab.example.com
  • Nexus: https://nexus.example.com:8443
  • JFrog: <name>.jfrog.io
Configure Cargo to resolve crates from a private registry.
Rust (via rustup) and Cargo are pre-installed on Devin’s base image. Skip the install step if the default stable toolchain is sufficient. You only need the registry configuration.
  • CARGO_REGISTRY_INDEX — URL of the private registry index (e.g., sparse+https://cargo.corp.internal/api/v1/crates/)
  • CARGO_REGISTRIES_PRIVATE_TOKEN — Auth token for the registry named private
The registry index URL must not contain credentials. Cargo’s cargo:token provider reads the named registry token from the environment; do not run cargo login in a build step.
If you only need to add a private registry without replacing crates.io, remove the [source.crates-io] and [source.private] sections and use cargo install --registry private or [dependencies] my-crate = { version = "1.0", registry = "private" } in Cargo.toml.
Install Ruby and configure Bundler to resolve gems from a private gem server.
  • GEM_SERVER_URL — URL of your private gem server (e.g., https://artifactory.example.com/artifactory/api/gems/gems-virtual)
  • BUNDLE_ARTIFACTORY__EXAMPLE__COM — username:password for artifactory.example.com; change the variable name to match your gem server
Use a credential-free GEM_SERVER_URL. For Bundler’s credential variable, prefix the uppercase hostname with BUNDLE_, replace each dot with __, and each hyphen with ___.
Common gem server URL patterns:
  • Artifactory: https://artifactory.example.com/artifactory/api/gems/gems-virtual
  • Nexus: https://nexus.example.com/repository/rubygems-proxy
  • Gemfury: https://gem.fury.io/<org>
Install PHP and configure Composer to resolve packages from a private Packagist or Satis registry.
  • COMPOSER_REGISTRY_URL — URL of your private Composer registry (e.g., https://repo.packagist.com/<org>)
  • COMPOSER_AUTH — JSON credentials for the registry host, such as {"http-basic":{"repo.packagist.com":{"username":"<user>","password":"<token>"}}}
Use a credential-free COMPOSER_REGISTRY_URL.
Common Composer registry URL patterns:
  • Artifactory: https://artifactory.example.com/artifactory/api/composer/packagist-virtual
  • Nexus: https://nexus.example.com/repository/packagist-proxy
  • Private Packagist: https://repo.packagist.com/<org>
  • Satis: https://satis.corp.internal
AWS CodeArtifact tokens normally expire after 12 hours. Create a script containing literal references, then explicitly source it in the same shell command as npm, pip, or Maven to obtain a token. Saving the script in a blueprint does not execute it at session start.
awscli is pre-installed on Devin’s base image. You only need the token refresh and registry configuration.
  • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY — IAM credentials with codeartifact:GetAuthorizationToken and sts:GetServiceBearerToken permissions
  • CA_DOMAIN — Your CodeArtifact domain name
  • CA_DOMAIN_OWNER — AWS account ID that owns the domain
  • CA_REGION — AWS region (e.g., us-east-1)
  • CA_NPM_REPO, CA_PYPI_REPO, CA_MAVEN_REPO — Repository names for each ecosystem
To warm a dependency cache in the snapshot, add the appropriate source ... && command as a later build step. The fetched token stays in that shell’s environment; do not persist it with aws codeartifact login, npm config set using an expanded token, or a credential-bearing pip.conf.

Enterprise infrastructure

Machine-level infrastructure that applies across all orgs and repos. Set these in Enterprise Settings > Environments > Blueprint (for enterprise-wide) or Settings > Environment > Blueprints > Org-wide setup (for org-wide).

Network and connectivity

Your organization uses a private certificate authority for internal services. Devin needs the root certificate to reach internal registries and tools over HTTPS.
  • CORP_ROOT_CA_B64 — Base64-encoded PEM certificate from your corporate CA. Generate with: cat corp-root-ca.crt | base64 -w0
These inputs are public certificates. openssl x509 writes only the parsed certificate, so an accidentally included private key is not copied into the trust store. Supply each CA certificate separately, as in the next example.
If your organization uses multiple CA certificates (e.g., separate CAs for different internal services).
  • CORP_ROOT_CA_B64 — Base64-encoded primary CA certificate
  • CORP_INTERMEDIATE_CA_B64 — Base64-encoded intermediate CA certificate
Route all network traffic through a corporate proxy.
  • CORP_HTTP_PROXY — HTTP proxy URL (e.g., http://proxy.corp.example.com:8080)
  • CORP_HTTPS_PROXY — HTTPS proxy URL
  • CORP_NO_PROXY — Comma-separated list of hosts to bypass proxy (e.g., localhost,127.0.0.1,.corp.example.com)
If your corporate proxy requires username/password authentication.
  • PROXY_USER — Proxy username
  • PROXY_PASS — Proxy password
  • PROXY_HOST — Proxy hostname and port (e.g., proxy.corp.example.com:8080)
  • CORP_NO_PROXY — Hosts to bypass proxy
Percent-encode special characters in the proxy username and password. Git and npm can use proxy environment variables; do not copy a credential-bearing proxy URL into their persistent configuration.
Combined setup for environments that need both a corporate CA and a proxy. This is common in enterprise environments where internal services use private certificates and all traffic must route through a proxy.
  • CORP_ROOT_CA_B64 — Base64-encoded corporate CA certificate
  • CORP_HTTP_PROXY, CORP_HTTPS_PROXY — Proxy URLs
  • CORP_NO_PROXY — Hosts to bypass proxy
Your private registries, Git servers, or other internal services are only reachable over VPN. Install the VPN client in the blueprint. Establish the tunnel explicitly for the operations that need it, and disconnect and remove credential files afterward.
OpenVPN:
  • VPN_CONFIG_B64 — Base64-encoded OpenVPN config file (.ovpn). Generate with: cat corp.ovpn | base64 -w0
  • VPN_AUTH_USER (optional) — VPN username, if your VPN requires username/password auth
  • VPN_AUTH_PASS (optional) — VPN password
WireGuard:
  • WG_CONFIG_B64 — Base64-encoded WireGuard config file. Generate with: cat wg0.conf | base64 -w0
OpenVPN:
Run this block explicitly in a session with the VPN secrets available. Replace the curl command with the work that needs the tunnel. The config must contain the required certificates and keys inline and use dev tun0; do not enable a persistent VPN service.
WireGuard:
Run this block explicitly with WG_CONFIG_B64 available, replacing the curl command with your operation:
If a snapshot build needs VPN access, wrap all dependent work in the same block so cleanup completes before imaging. Merely moving credential writes to maintenance does not make them temporary. Do not snapshot an active tunnel or private VPN configuration.
For more details on VPN setup, see VPN configuration.
Your internal services use private DNS names that aren’t resolvable by public DNS.

Identity and security

Your organization requires all Git commits to be signed, and you want GitHub to mark Devin’s commits as Verified.
  • GPG_PRIVATE_KEY_B64 — Base64-encoded GPG private key. Generate with: gpg --export-secret-keys <key-id> | base64 -w0
  • GPG_SIGNING_KEY — Full fingerprint of the signing key
  • GIT_USER_NAME — Git author name (e.g., Devin AI)
  • GIT_USER_EMAIL — Git author email. Must match a UID on the GPG key, otherwise GitHub will not verify the signature.
Also upload the matching public key to the GitHub account whose credentials Devin uses to push (under GitHub Settings > SSH and GPG keys). GitHub only marks commits as Verified when the signing public key is registered on the account that authored the commit.
Do not import private signing keys during snapshot builds. After staging the intended changes, explicitly run this block in a session with the named secrets available. It uses a temporary keyring and Git settings that apply only to this commit:
If your key requires a passphrase, complete its approved GPG agent/pinentry flow during the operation. Do not save the passphrase or keyring in the blueprint or snapshot. Repeat the temporary-keyring setup for later commits or signed tags.
Configure Devin’s Git identity and SSH keys for accessing private Git servers.Prefer Git integrations for supported Git providers. For a server that requires an explicit SSH key, keep the private key out of the blueprint build and use it only for the session operation below.
  • GIT_USER_NAME — Git author name
  • GIT_USER_EMAIL — Git author email
  • SSH_PRIVATE_KEY_B64 — Base64-encoded SSH private key. Generate with: cat ~/.ssh/id_ed25519 | base64 -w0
  • SSH_KNOWN_HOSTS_B64 — Base64-encoded known hosts entries verified against your server administrator’s published host key fingerprints
Run this block explicitly in the session, replacing the Git URL with your server and repository:
If you need custom SSH options, add them to this invocation without copying a private key into a persistent SSH config or home directory. Repeat the setup for each operation.

System configuration

Install system-level packages that aren’t in the default Devin image (e.g., native libraries for image processing or PDF generation).
Set persistent, non-secret environment variables that should be available in every session. Do not write secret values or derived credentials to $ENVRC.The recommended approach is to write KEY=VALUE lines to the $ENVRC file. Variables written to $ENVRC are automatically exported for all subsequent steps and the Devin session (similar to GitHub Actions’ $GITHUB_ENV).
You can also write env vars to /etc/profile.d/ scripts for system-wide availability:
Both approaches work. $ENVRC is simpler and recommended for most cases.
Default base images may have broken locale settings. Configure locale and timezone to prevent warnings from build tools, Java, Python, and Git.
Java, Gradle, and Node.js builds frequently hit the default 1024 open-file limit. Raise it to prevent build failures.
In air-gapped or restricted environments, replace the default Ubuntu APT sources with an internal mirror.
  • APT_MIRROR_URL — URL of your internal APT mirror (e.g., https://artifactory.example.com/artifactory/ubuntu-remote)
Common APT mirror URL patterns:
  • Artifactory: https://artifactory.example.com/artifactory/ubuntu-remote
  • Nexus: https://nexus.example.com/repository/ubuntu-proxy

Advanced patterns

Devin’s base environment includes direnv. Use initialize to create .envrc files. Direnv loads them automatically.
direnv is pre-hooked into Devin’s shell, so .envrc variables load automatically. No manual sourcing needed.
For sensitive environment variables (API keys, tokens, database passwords), use repo secrets instead of .envrc files, and bind them explicitly to session commands that need them. Expanding a secret into a file during a build can still put it in the snapshot.
Use nvm (pre-installed) to switch Node.js versions per repository via .nvmrc.
nvm use reads .nvmrc from the repo root. Make sure your repository has one (e.g., containing 20).
Devin provides a Chrome browser with a CDP endpoint at localhost:29229 during sessions. Use Playwright scripts to automate browser-based login.
The browser is only available during sessions, not snapshot builds. Install Playwright in initialize and keep login scripts in your repo.
Example login script (scripts/login.py):
Store login credentials as secrets, not in source code. For long-lived authentication, commit login scripts to .agents/skills/ so Devin can re-authenticate automatically.
Install system packages, custom binaries, and configure PATH in initialize.
Devin supports running GitHub Actions directly in a blueprint’s initialize section. This is useful for installing specific tool versions via the same actions your CI uses.
Actions like setup-node and setup-python modify PATH and environment variables. Binaries installed by one action are available in all subsequent steps and in maintenance. Node.js and composite actions are supported; Docker actions are supported on Linux builds only. uses steps can’t run in maintenance. See GitHub Actions limitations.
You don’t need GitHub Actions for basic tool setup. Direct shell commands (nvm install 20, curl ... | sh, apt-get install) work just as well and are often simpler. GitHub Actions are most useful when you want to match your CI setup exactly or need the convenience of actions like setup-java which handle multiple distributions.
Run several services behind real-looking hostnames over HTTPS, such as app.example.com, api.example.com, and admin.example.com. Install a single reverse proxy in initialize and route each hostname to a different local upstream port.Caddy handles routing and local TLS in one tool. A Caddyfile maps each hostname to an upstream, and tls internal auto-issues a trusted certificate per hostname from Caddy’s built-in CA. caddy trust installs that CA root into the system trust store, and adding the same root to the NSS database lets the browser accept it.Upload your Caddyfile via the File attachments section of the blueprint editor; it is then available as $FILE_CADDYFILE.
Caddyfile
The /etc/hosts loop is what makes app.example.com resolve to 127.0.0.1 inside the session. Add an entry for every hostname you put in the Caddyfile.
To add a service, append a three-line block to the Caddyfile and one entry to the /etc/hosts loop, then visit its hostname over HTTPS. Caddy mints a certificate on first request, so no per-app cert generation is needed.

Full-stack examples

These examples show how enterprise and org-level configurations combine. In practice, you’d split these across scopes. They’re shown together here for reference.
A complete enterprise environment: corporate CA certificate, proxy, Java (Maven), Python (pip/uv), Node.js (npm), and Docker, all pointed at a single Artifactory instance.
Network & trust (account-wide):
  • CORP_ROOT_CA_B64 — Base64-encoded corporate CA certificate
  • CORP_HTTP_PROXY — HTTP proxy URL
  • CORP_HTTPS_PROXY — HTTPS proxy URL
  • CORP_NO_PROXY — Hosts to bypass proxy
Registry credentials (org-wide):
  • ARTIFACTORY_USER — Artifactory username
  • ARTIFACTORY_TOKEN — Artifactory API token or password
  • ARTIFACTORY_MAVEN_URL — Maven repository URL (e.g., https://artifactory.example.com/artifactory/maven-virtual)
  • ARTIFACTORY_PYPI_URL — PyPI repository URL (e.g., https://user:token@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple)
  • ARTIFACTORY_NPM_URL — npm repository URL (e.g., https://artifactory.example.com/artifactory/api/npm/npm-virtual)
  • ARTIFACTORY_DOCKER_URL — Docker registry URL (e.g., artifactory.example.com)
This would typically be split across three scopes:
  • Account-wide (initialize): Certificate and proxy
  • Org-wide (initialize): Language runtime installs
  • Org-wide (maintenance): Registry configuration containing literal references
  • Session commands: Explicitly supply secrets, source environment setup, and log in for individual Docker operations
Shown here combined for reference:
In this example, all registries point at the same Artifactory instance but use different URL paths. Each package ecosystem has its own endpoint format. Maven, PyPI, npm, and Docker URLs are all different even for the same registry.
When different languages use different private registries (e.g., Maven from Nexus, npm from GitHub Packages, Python from Artifactory).
  • NEXUS_MAVEN_URL — Nexus Maven repository URL
  • NEXUS_USER — Nexus username
  • NEXUS_PASS — Nexus password
  • GITHUB_PACKAGES_TOKEN — GitHub personal access token with read:packages scope
  • ARTIFACTORY_USER — Artifactory username
  • ARTIFACTORY_TOKEN — Artifactory API token
Connect your Git provider and grant access to the repositories that host the Go modules through Git integrations.
In a fully air-gapped environment, Devin cannot reach any public URLs. All tools, runtimes, and packages must come from internal mirrors.
Certificates:
  • CORP_ROOT_CA_B64 — Base64-encoded corporate CA certificate
Mirror access:
  • APT_MIRROR_URL — Internal Ubuntu APT mirror URL
  • MIRROR_USER — Mirror authentication username
  • MIRROR_PASS — Mirror authentication password
  • JDK_TARBALL_URL — URL to download JDK tarball from internal mirror
  • NODE_TARBALL_URL — URL to download Node.js tarball from internal mirror
Package registries:
  • INTERNAL_MAVEN_URL — Internal Maven registry URL
  • INTERNAL_NPM_URL — Internal npm registry URL
  • INTERNAL_PYPI_URL — Internal PyPI registry URL
In air-gapped environments, all tools Devin needs (language runtimes, CLI tools, etc.) must be available on your internal mirrors. Public registries and download sites are unreachable.
A comprehensive enterprise setup combining VPN tooling, certificates, proxy configuration, and multi-language support. The blueprint installs tools and stores configuration with literal references. Connect the VPN explicitly when running operations that need internal access.
VPN:
  • VPN_CONFIG_B64 — Base64-encoded OpenVPN config file
Network & trust:
  • CORP_ROOT_CA_B64 — Base64-encoded corporate CA certificate
  • CORP_HTTP_PROXY — HTTP proxy URL
  • CORP_HTTPS_PROXY — HTTPS proxy URL
  • CORP_NO_PROXY — Hosts to bypass proxy
Registry credentials:
  • MAVEN_REGISTRY_URL — Maven registry URL
  • NPM_REGISTRY_URL — npm registry URL
  • PYPI_REGISTRY_HOST — PyPI registry hostname
  • REGISTRY_USER — Registry username (for Maven and pip)
  • REGISTRY_PASS — Registry password (for Maven and pip)
  • REGISTRY_TOKEN — npm auth token
Bootstrap access is required. The OpenVPN client must be preinstalled or installable before connecting the tunnel. VPN_CONFIG_B64 must contain inline certificates/keys, use dev tun0, and connect without interactive authentication. The runtime downloads run inside one tunnel lifecycle and explicitly load the proxy environment. Repeat the VPN setup/cleanup block under Network and connectivity for session operations; the blueprint does not reconnect the VPN at session start.

Tips for writing good blueprints

  • Test commands in a session first. Run commands manually in a Devin session before adding them to your blueprint. This is faster than waiting for a full build cycle.
  • Use initialize for install-once tools, maintenance for deps. Anything that takes minutes to install (compilers, large binaries, global tools) belongs in initialize. Quick dependency commands (npm install, uv sync) go in maintenance.
  • Keep maintenance commands fast. Aim for under 2 minutes. These run during builds and are surfaced to the agent at session start.
  • Use $ENVRC for non-secret environment variables. Don’t write credentials or derived tokens to $ENVRC, .bashrc, or .profile. Source secret-dependent shell setup explicitly in the command that needs it.
  • Name your steps. The expanded form with name fields makes build log failures much easier to identify.
  • Use subshells for monorepos. (cd packages/foo && npm install) runs in a subshell so subsequent steps aren’t affected by the directory change.
  • Use npm install, not npm ci. npm ci deletes node_modules and reinstalls from scratch, which is slow for maintenance.
  • Use repo secrets for sensitive values. Configure them in the Secrets tab of the repository’s blueprint editor instead of hardcoding in blueprints.
For syntax details, see the Blueprint reference. For troubleshooting build failures, see Declarative configuration > Troubleshooting.