---
title: Env Variables & Secrets in Capawesome Cloud
description: Learn how to use environment variables, secrets, and reserved variables to configure your Capacitor and Ionic builds in Capawesome Cloud.
date:
  created: 2026-03-18
  updated: 2026-07-17
authors:
  - djabif
categories:
  - Capacitor
  - Cloud
  - Guides
faq: true
---

# Using Environment Variables and Secrets in Capawesome Cloud Builds

When building mobile apps in the cloud, it's common to need different configuration values depending on the environment. A staging build might use a different API endpoint than a production build, or you might need to inject API keys that shouldn't be committed to your repository.

With [Capawesome Cloud](/){:target="_blank"}, you can define environments, add environment variables and secrets, and customize the build stack using reserved variables—all without changing your source code.

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

In this guide, you'll learn how to:

- Create environments like staging and production
- Add environment variables for configuration
- Store sensitive values as secrets
- Customize the build stack with reserved variables such as `NODE_VERSION` and `XCODE_VERSION`

If you're new to Capawesome Cloud builds, you may want to first explore the [Native Builds](../../cloud/native-builds/index.md) documentation.

<div style="margin-top: 1rem;">
  <iframe width="100%" height="400" src="https://www.youtube.com/embed/aF1xIVZIuN8?si=ZVGc9JrbHV9K_7et?rel=0&modestbranding=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
 </div>

## Create Environments

Environments allow you to manage different configurations for your builds without changing your source code. For example, your staging build may connect to a staging API, while your production build connects to the live API.

Typical environments include:

- `development`
- `staging`
- `production`

Each environment can have its own set of variables and secrets that are automatically injected during the build process. This makes it easy to keep build configurations organized and avoids manually changing values between builds.

To create a custom environment, navigate to the [Environments](https://console.cloud.capawesome.io/apps/_/environments){:target="_blank"} page in the Capawesome Cloud Console. You can then select which environment to use when triggering a build.

## Add Environment Variables

Environment variables are ideal for non-sensitive configuration values. A common example is defining which API endpoint your app should use.

To add a variable, navigate to the [Environments](https://console.cloud.capawesome.io/apps/_/environments){:target="_blank"} page, click on "Manage Variables" in the "Actions" menu of an environment, and create a new variable.

You can configure different values for each environment, for example:

| Environment | Variable                                       |
| ----------- | ---------------------------------------------- |
| Staging     | `VITE_API_URL=https://staging-api.example.com` |
| Production  | `VITE_API_URL=https://api.example.com`         |

During the cloud build, these variables become available to your build process. For example, in an application built with Vite:

```typescript
const apiUrl = import.meta.env.VITE_API_URL;

fetch(`${apiUrl}/users`);
```

When the production environment is selected, the build will automatically use the production API endpoint. The value is replaced during the build step and bundled into your application, so you can configure different environments without modifying your application code.

???+ tip "Bulk Import"

    You can bulk import multiple variables at once by using the "Import" feature in the actions menu. This allows you to paste in multiple `KEY=VALUE` pairs, making it easier to set up your environment.

## Store Sensitive Values as Secrets

Some values should never appear in logs or configuration files. These should be stored as secrets.

Secrets are encrypted at rest and in transit, and their values are never displayed in build logs. This makes them ideal for storing sensitive credentials such as API tokens, authentication credentials, deployment keys, and license keys.

To add a secret, navigate to the [Environments](https://console.cloud.capawesome.io/apps/_/environments){:target="_blank"} page, click on "Manage Secrets" in the "Actions" menu of an environment, and create a new secret. Secrets are added the same way as regular variables, but their values remain hidden throughout the build process.

For example, you might store a Sentry authentication token as a secret:

```
SENTRY_AUTH_TOKEN=your-secret-token
```

This token could be used during the build to upload source maps:

```bash
npx sentry-cli releases new $CI_BUILD_ID
npx sentry-cli releases files $CI_BUILD_ID upload-sourcemaps dist
```

Because the value is stored as a secret, it will not appear in build logs.

## Customize the Build Stack with Reserved Variables

Capawesome Cloud supports reserved variables that allow you to configure the build environment itself. These variables control which tools and versions are used during the build, and **they are added to an environment the same way as regular variables**. Let's see some examples.

### Selecting the Node.js Version

If your project requires a specific Node.js version, you can configure it using the `NODE_VERSION` variable:

```
NODE_VERSION=22
```

During the build, Capawesome Cloud will automatically use that version. This is useful when your project depends on specific Node.js features or when you need to match your local development environment.

### Selecting the Xcode Version

For iOS builds, you can specify which version of Xcode should be used with the `XCODE_VERSION` variable:

```
XCODE_VERSION=16
```

This determines the iOS SDK, Swift version, and build tools used during compilation. This is particularly useful when Apple requires apps to be built with a newer SDK or when your project depends on a specific toolchain.

For the complete list of reserved variables (including `JAVA_VERSION`, `IOS_SCHEME`, `ANDROID_FLAVOR`, and more), see the [Reserved Environment](../../cloud/native-builds/environment-variables.md#reserved-variables) documentation.

## Default Variables

During every build, Capawesome Cloud automatically provides default variables that give you information about the current build context. These include variables like `CI_BUILD_ID`, `CI_GIT_REFERENCE`, `CI_GIT_COMMIT_SHA`, and `CI_PLATFORM`.

You can use these variables in your build scripts to make decisions based on the build context. For example, you might use `CI_BUILD_ID` to tag releases in your error monitoring tool, or use `CI_GIT_REFERENCE` to determine which branch triggered the build.

```bash
echo "Building from branch: $CI_GIT_REFERENCE"
echo "Commit: $CI_GIT_COMMIT_SHA"
```

For the complete list of default variables, see the [Default Environment](../../cloud/native-builds/environment-variables.md#default-variables) documentation.

!!! warning "Reserved Variable Names"

    Variables such as `CI` and any variable starting with `CI_` are reserved and cannot be overridden. They are automatically managed by the build system.

## Common Use Cases

Here are some practical examples of how teams use environment variables and secrets in their builds. These are just a few ideas—the possibilities are endless.

### Switching Payment Provider Environments

Payment providers like Stripe or PayPal typically offer sandbox environments for testing. You can use environment variables to switch between sandbox and live endpoints:

| Environment | Variable                                          |
| ----------- | ------------------------------------------------- |
| Staging     | `VITE_STRIPE_API_URL=https://api.stripe.com/test` |
| Production  | `VITE_STRIPE_API_URL=https://api.stripe.com`      |

You can also store the API keys as secrets:

| Environment | Secret                               |
| ----------- | ------------------------------------ |
| Staging     | `STRIPE_PUBLISHABLE_KEY=pk_test_...` |
| Production  | `STRIPE_PUBLISHABLE_KEY=pk_live_...` |

This ensures your staging builds never accidentally process real payments.

### Uploading Source Maps to Error Monitoring

When using error monitoring tools like Sentry, uploading source maps during the build makes stack traces readable. Store your authentication token as a secret and use default variables to tag releases:

```bash
npx sentry-cli releases new $CI_BUILD_ID
npx sentry-cli releases files $CI_BUILD_ID upload-sourcemaps dist
npx sentry-cli releases set-commits $CI_BUILD_ID --commit "repo@$CI_GIT_COMMIT_SHA"
```

Native crash reporting has the same requirement in a different shape: if you use Crashlytics, the iOS dSYM upload is what makes native stack traces readable — [Crash Reporting in a Capacitor App with Crashlytics](./capacitor-firebase-crashlytics-guide.md) covers it.

### Feature Flags Per Environment

Environment variables can control which features are enabled in each build:

```
VITE_ENABLE_ANALYTICS=true
VITE_ENABLE_DEBUG_MODE=false
```

In your application code:

```typescript
if (import.meta.env.VITE_ENABLE_DEBUG_MODE === 'true') {
  console.log('Debug mode enabled');
}
```

This allows you to enable experimental features in staging while keeping them disabled in production builds.

### Private npm Registry Access

If your project uses private npm packages, you can store the registry token as a secret and configure npm to use it during the build. See the [Private npm Registry](../../cloud/native-builds/npm-private-registry.md) guide for details.

### Conditional Build Logic

Use default variables to customize build behavior based on the target platform or branch:

```bash
if [ "$CI_PLATFORM" = "ios" ]; then
  echo "Running iOS-specific setup..."
fi

if [ "$CI_GIT_REFERENCE" = "main" ]; then
  echo "Production build detected"
fi
```

## Why Environment Variables Matter

Whether you're building with Ionic, Angular, React, or Vue, environment variables allow you to change how your app builds and behaves without modifying source code or committing environment-specific configuration to your repository. This provides several advantages:

- **Safer deployments**: Sensitive values never appear in your codebase
- **Flexible builds**: Easily switch between staging and production configurations
- **Better collaboration**: Team members can work with different environments without conflicts
- **Simpler CI/CD**: No complex scripts or YAML files to manage

## FAQ

### What's the actual difference between a variable and a secret?

Both are injected into the build the same way, but secrets are encrypted at rest and in transit and their values never appear in build logs, even if a script accidentally echoes them. Use variables for anything safe to see in a log (an API URL, a feature flag); use secrets for anything that shouldn't be — API tokens, deployment keys, publishable/private key pairs.

### Can I override a `CI_`-prefixed variable with my own value?

No. `CI` and any variable starting with `CI_` are reserved and automatically managed by the build system — attempting to set your own `CI_BUILD_ID` or `CI_GIT_REFERENCE` in an environment won't take effect, since these are populated from the actual build context.

### Do reserved variables like `NODE_VERSION` need to be set differently from regular environment variables?

No — reserved variables are added to an environment exactly the same way as any other variable or secret, through the Environments page. The difference is only in what they do: instead of being exposed to your app's runtime, variables like `NODE_VERSION` or `XCODE_VERSION` configure the build environment itself (which Node.js or Xcode version compiles your app).

### If I don't set `XCODE_VERSION` or `NODE_VERSION`, what happens?

The build uses the build stack's current default version for that tool. This is worth knowing if you've read about [Xcode 26 becoming the new default](./new-clis-and-xcode-26-in-capawesome-build-stacks.md) — if you haven't pinned `XCODE_VERSION`, your next build will pick up that new default automatically rather than staying on whatever version it used previously.

### Can I set different variable values per environment, or are they global to the app?

They're per environment. You create separate environments (development, staging, production, or custom names), and each one holds its own independent set of variables and secrets — so `VITE_API_URL` can point at a staging endpoint in one environment and the live endpoint in another, without any conditional logic in your source code.

## Try Capawesome Cloud

Ready to simplify your mobile CI/CD workflow? Capawesome Cloud provides a powerful way to manage your build configuration and automate your deployment pipeline for Capacitor and Ionic apps.

[Try Capawesome Cloud Free](/){ .md-button .md-button--primary }

## Conclusion

Environment variables and secrets make it easy to manage build configuration in Capawesome Cloud. By combining environments, variables, and reserved build settings, you can securely store sensitive values, configure builds for different environments, customize the build stack, and simplify your CI/CD workflow.

For more details, check out the [Environments](../../cloud/native-builds/environments.md) documentation.

If you have any questions, join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"}. For the latest updates, subscribe to the [Capawesome newsletter](/newsletter/){:target="_blank"}.
