How to generate an SBOM for a React Native app
Updated 6 November 2026 · 8 min read
In short
- The JavaScript side is in
package-lock.jsonoryarn.lock. A typical React Native app has hundreds of packages there. - Leave out what does not ship, such as test and build tools, and add the native side from
ios/Podfile.lockand the Android Gradle build. - With Expo, generate the native folders first with
npx expo prebuild.
Why it matters for React Native in particular
The EU Cyber Resilience Act (Regulation (EU) 2024/2847) applies to software placed on the EU market as part of a commercial activity, which covers most apps published by companies. Annex I, Part II requires a software bill of materials (SBOM) in a commonly used, machine-readable format, covering at least the top-level dependencies. Since 11 September 2026, actively exploited vulnerabilities must be reported to ENISA within 24 hours, and the full requirements apply from 11 December 2027.
React Native apps are a special case because they sit on two supply chains at once: the npm ecosystem for JavaScript and the native ecosystems of iOS and Android. A vulnerability can arrive through either one, so the SBOM has to cover both.
Step 1. Use the lockfile, not package.json
package.json lists version ranges such as ^1.6.0. Only the lockfile records the exact versions that were installed, including every transitive package:
| Package manager | Lockfile |
|---|---|
| npm | package-lock.json |
| Yarn (classic or Berry) | yarn.lock |
| pnpm | pnpm-lock.yaml |
Make sure the lockfile is committed. Without it, two builds of the same commit can contain different code, and no SBOM can describe either of them reliably.
Step 2. Separate what ships from what does not
Jest, ESLint, Babel plugins and other devDependencies help you build the app but are not part of the released product. In package-lock.json they are marked with "dev": true. Keep them out of the SBOM, or mark them as excluded, so that the document describes what users actually install.
Step 3. Generate the SBOM
Option A: in your browser
Drop package-lock.json or yarn.lock on the Shipmark free scanner. It builds a CycloneDX 1.6 SBOM with a package URL (pkg:npm/…) for every component and checks each version against OSV.dev. With package-lock.json, it also marks development-only packages as excluded. The file never leaves your browser.
Option B: with npm itself
Recent versions of npm can write an SBOM directly from the installed project:
npm sbom --sbom-format cyclonedx > app.cdx.json
To check the lockfile for known vulnerabilities, Google's OSV-Scanner reads it directly:
osv-scanner scan -L package-lock.json
Step 4. Add the native side
Libraries such as react-native-maps, payment SDKs, analytics or push notifications include native code and pull in their own iOS and Android dependencies. None of those appear in the JavaScript lockfile.
- iOS:
ios/Podfile.locklists every CocoaPod, including the ones added by React Native itself. - Android: enable Gradle dependency locking and commit the result. Running
./gradlew dependencies --write-locksin theandroidfolder createsgradle.lockfile.
Using Expo?
In the managed workflow the ios and android folders are generated at build time, so the native lockfiles are not in your repository. Generate them locally from the same commit you release:
npx expo prebuild
cd ios && pod install
The resulting ios/Podfile.lock describes the native iOS libraries that go into the build. The Shipmark scanner accepts it, as well as gradle.lockfile.
Step 5. Make it part of every release
- Generate the SBOM from the exact commit you tag for the store release.
- Keep one file per platform and per version, for example
orderly-ios-4.2.0.cdx.json. - Store it with the technical file, which the CRA requires you to keep for ten years or for the support period, whichever is longer.
- Re-check old releases regularly. npm advisories are published every week, and an SBOM is only useful if someone looks at it again.
Common questions
Our app has 900 npm packages. Do they all go in the SBOM?
The CRA asks for at least the top-level dependencies, but in practice it is easier to include every package that ships, transitive ones too. Many vulnerabilities in the npm ecosystem sit deep in the tree, not in the packages you installed yourself.
Is React Native itself a component?
Yes. react-native is an npm package in your lockfile, and its native parts, such as the Hermes engine, appear in Podfile.lock. Both belong in the SBOM.
We are an agency. Who is responsible?
Legally, the manufacturer, usually the company that publishes the app under its own name. In practice, the team that maintains the code is the one that can produce the SBOM, so clients will turn to their agency.
Generate the SBOM of your React Native app in seconds. No account, and the file stays in your browser.
Open the free scannerAlso see: How to generate an SBOM for a Flutter app. This guide summarises Regulation (EU) 2024/2847 for practical use. It is not legal advice.