> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apsio.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload React Native source maps

> Upload a React Native bundle's source map with the apsio CLI so JavaScript crashes and errors show your functions, files and lines.

A release build of a React Native app runs its JavaScript as Hermes bytecode: a crash's stack
reads `crashCheckout (address at main.jsbundle:1:454705)`. Apsio turns that into
`crashCheckout` in `src/App.tsx:100` with the bundle's source map. See
[React Native](/concepts/symbols#react-native-javascript) for how the map is matched.

## Which map

Upload the map React Native composes from Metro's and Hermes' maps, one per bundle and
build:

| Platform | Bundle | Map |
| - | - | - |
| iOS | `main.jsbundle` | the file `SOURCEMAP_FILE` names in the "Bundle React Native code and images" build phase |
| Android | `index.android.bundle` | `app/build/generated/sourcemaps/react/<variant>/index.android.bundle.map` |

On iOS, set `SOURCEMAP_FILE` in that build phase, for example
`export SOURCEMAP_FILE="$DERIVED_FILE_DIR/main.jsbundle.map"`; without it no map is written.

## Upload it after the build

```sh theme={null}
apsio upload sourcemaps app/build/generated/sourcemaps/react/release/index.android.bundle.map --build-id 6f1d2c3b-4a59-4e7f-8a1b-2c3d4e5f6a7b
```

* `--build-id` is what the app reports as `app.build_id`: on Android the build id the Gradle
  plugin writes into the manifest (see [Give the build an id](/symbols/android#1-give-the-build-an-id)),
  on iOS the main binary's UUID, the same UUID as its dSYM (`dwarfdump --uuid` on the app's
  binary). Another string works too, such as the SDK's `<package>@<version>+<code>` fallback,
  but two builds of one version then share it; prefer the build id.
* `--bundle` is the bundle's file name in the app. By default it is the map's file name
  without `.map`: `index.android.bundle.map` uploads for `index.android.bundle`.
* `--bundle-id` is for an over-the-air bundle (EAS Update, CodePush): the id your app passes to
  the SDK (`start({ jsBundleId })`). Crashes from that bundle use only its map, never the
  build's: upload the map of every update you publish.
* The map's `sourcesContent` is removed before upload, so your source code never leaves the
  machine; Apsio shows functions, files and lines, not the code around them.
* Maps are limited to 64 MB and 8 million mappings; larger ones are refused.
* Apsio keeps one map per build and bundle: the same map again is reported as `present`, a
  different one is refused (exit 4) unless `--force`. `--dry-run` checks the map without a
  token, and `--json` prints a report. Like every upload, it goes to the symbol upload URL
  (`APSIO_SYMBOLS_URL`, `https://symbols.apsio.io` by default; see [the CLI](/cli#configuration)).

Crashes and errors that arrived before their map are symbolicated when it lands, and
[grouped again](/concepts/issues#grouping) with your function names.

## What stays unsymbolicated

* Frames in other Hermes segments than the first (bundles split into segments): v0 resolves
  segment 1, the whole bundle in a plain build. Frames in other segments keep their function
  name and offset even with the map uploaded, and the crash counts as not fully symbolicated.
* A map from another build of the bundle: bytecode offsets change with every build.
* Native frames (`(native)`) and Hermes' own code, which have no source.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.