# Runtime Version — Bundle Drop Docs

> Choose explicit runtime versions, opt-in native fingerprints (Beta), or both to define compatibility for React Native and Expo OTA updates.

Canonical: https://bundledrop.app/docs/runtime-version

## What Runtime Version Is

`runtimeVersion` is the compatibility boundary between an installed native binary and the OTA bundles it can receive.

Bundle Drop only delivers an update when the app and bundle resolve to the same runtime version. This prevents JavaScript from expecting native code that is not present in the installed binary.

## Choose Your Compatibility Approach

Expo and bare React Native can use the same three approaches:

| Approach | Compatibility control |
| --- | --- |
| Manual runtime versions | Your team updates an explicit platform value when native compatibility changes |
| Native fingerprinting | Bundle Drop derives the runtime from collected native inputs |
| Hybrid | A native fingerprint and your explicit platform value form one compatibility identity |

[Native fingerprinting](/docs/native-fingerprinting) is opt-in today and is intended to become the default in a future release. Manual versions remain the current default; existing projects keep their configured behavior unless they opt in.

Use the [compatibility strategy guide](/resources/native-fingerprints-runtime-versions) to choose who maintains the boundary. Hybrid compatibility here means fingerprints plus an explicit runtime boundary; [patch and full-bundle delivery](/resources/patch-delivery-full-bundle-reliability) is a separate transfer decision.

## Automatic Native Fingerprints

To enable automatic compatibility, change the runtime section of your existing config:

**bundle.drop.config.js**

```js
runtimeVersion: {
  compatibilitySource: "fingerprint",
},
```

The binary embeds its fingerprint, and upload independently calculates the identity from the project. Matching identities allow compatible OTA delivery; a detected native change requires a new binary. Rebuild when first enabling this mode.

## Hybrid Runtime Control

Keep explicit versions alongside the fingerprint when your team also wants a release boundary:

**bundle.drop.config.js**

```js
runtimeVersion: {
  compatibilitySource: "fingerprint",
  ios: "1.0.0",
  android: "1.0.0",
},
```

Both values contribute to the final identity. Native changes can separate incompatible updates without a manual bump. Changing your explicit value also creates a different identity and requires a new binary for that platform. Read [Native Fingerprinting](/docs/native-fingerprinting#hybrid-fingerprints-and-explicit-runtime-versions) for the full workflow and limitations.

## Default Literal Runtime Versions

Expo and bare React Native use the same literal runtime model by default:

**bundle.drop.config.js**

```js
module.exports = {
  runtimeVersion: {
    ios: "1.0.0",
    android: "1.0.0",
  },
  // serverUrl, org, and project are generated during login
};
```

The bundle manifest records the platform runtime during bundling. Upload fails closed if no runtime can be resolved, and there is no upload flag that silently overrides it.

## When to Keep or Bump It

In manual mode, your team owns the following compatibility decisions. In fingerprint mode, native input changes are detected automatically within the [collector's coverage](/docs/native-fingerprinting#coverage-and-custom-build-inputs), and an explicit hybrid boundary can force a new compatibility line.

Keep the same platform runtime for changes that remain compatible with the installed native binary, including most JavaScript, styling, copy, and bundled asset updates.

In manual mode, bump the affected platform runtime and create a new native build when compatibility changes, including:

- native iOS or Android code changes
- adding, removing, or incompatibly upgrading a native module
- changing the JavaScript engine or React Native architecture
- changing an Expo config plugin or another native build input

An iOS-only native change only requires a new iOS runtime. Android can remain on its existing compatibility line.

In fingerprint or hybrid mode, collected changes derive a new identity without a manual bump. You still need a native binary containing the change. Uncollected native context needs an explicit source or deliberate boundary change; an unchanged fingerprint does not prove every possible native build input is unchanged.

## How Runtime Lines Behave

- Older binaries continue receiving the last compatible updates on their runtime line.
- Newer binaries receive updates published for their new runtime line.
- A channel can contain builds and bundles for more than one runtime version; compatibility is resolved when the app checks for an update.

Changing the runtime is therefore a native compatibility decision, not a channel reset.

## Strict Expo Fingerprint Authority

Separately from Bundle Drop's native fingerprint mode, Expo projects can delegate runtime authority to the evaluated Expo configuration:

**bundle.drop.config.js**

```js
module.exports = {
  projectType: "expo",
  runtimeVersion: { source: "expo" },
  // serverUrl, org, and project are generated during login
};
```

This strict mode binds uploads to the exact Expo build identity and requires a matching build receipt. It is useful when your release policy requires fingerprint enforcement, but it is not the default. Literal Bundle Drop runtime versions do not require Expo receipts or upload-time fingerprint comparison.

Do not combine `source: "expo"` with `compatibilitySource`, Bundle Drop fingerprint options, or platform literals. Switching authority or compatibility mode requires a matching native build.

See [Expo](/docs/expo#strict-expo-fingerprint-authority) for local and EAS Build behavior.

## Keep Configuration in Source Control

Commit `bundle.drop.config.js` so local builds, CI, uploads, and installed apps resolve the same project identity and compatibility boundary. Its `project.apiKey` is public app configuration, not a Personal Access Token or private signing key. When you bump a platform runtime, build the corresponding native binary from that configuration before publishing updates for the new line.

Also commit `.bundle-drop/runtime-delivery.lock.json`. It pins the public manifest trust configuration embedded into the native build and is safe to keep in source control; it does not contain private signing material. `login` and `init` synchronize it automatically. Refresh, recreate, or migrate the former `runtime-delivery.generated.json` file with `bundle-drop sync`, and rebuild if the pinned project identity or public keys change. See [Installation](/docs/installation#pin-the-runtime-delivery-bootstrap) for the complete lifecycle and backup guidance.

## Related Docs

- [Installation](/docs/installation)
- [Native Fingerprinting](/docs/native-fingerprinting)
- [Expo](/docs/expo)
- [Uploading](/docs/uploading)
- [Channels](/docs/channels)
