DEV Community

Cover image for SonarQube says your React Native app is fine. Here's what it can't see.
alican akyol
alican akyol

Posted on

SonarQube says your React Native app is fine. Here's what it can't see.

I ran a small React Native sample app through SonarQube (Community Build 26.10). SonarQube's own analysis found nothing.

The same app has an AWS access key in the JavaScript bundle, a target SDK that hides it from users on newer Android versions, a signing password committed to the repository, and an AppDelegate that will crash in release builds once the New Architecture is on.

None of that is a code smell. It's mobile: store rules, native build files, React Native versions, what ends up inside the app you ship. A general-purpose analyzer doesn't know about it, and it shouldn't have to.

Putting mobile findings into SonarQube

NativeKeel is the free CLI I build for exactly those checks. As of 0.1.93 it can write its findings in SonarQube's generic issue import format, so they land in the project you already have:

npx nativekeel --sonar nativekeel-sonar.json --fail-on never
sonar-scanner -Dsonar.externalIssuesReportPaths=nativekeel-sonar.json
Enter fullscreen mode Exit fullscreen mode

After that, the same sample project looks like this:

SonarQube summary: Security E, Reliability E

Ten issues, each on its file and line, with SonarQube's own categories:

SonarQube issues imported from NativeKeel

NativeKeel Shows up in SonarQube as
Leaked keys, signing secrets, security findings Security · Vulnerability
Store rules (Xcode 27 UIScene, Google Play target SDK, 16 KB pages, privacy manifest), crash risks Reliability · Bug
Upgrade blockers, New Architecture, performance, accessibility Maintainability · Code smell

In GitHub Actions

steps:
  - uses: actions/checkout@v5
  - uses: AlicanAkyol/nativekeel@v0
    with:
      sonar: nativekeel-sonar.json
      fail-on: never        # let the SonarQube quality gate decide
  - uses: SonarSource/sonarqube-scan-action@v8
    env:
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
    with:
      args: -Dsonar.externalIssuesReportPaths=nativekeel-sonar.json
Enter fullscreen mode Exit fullscreen mode

Two things that tripped me up while testing:

  • Paths. SonarQube attaches each issue to a file it indexed, relative to sonar.projectBaseDir. Run NativeKeel from that same folder, and keep package.json, ios/ and android/ inside sonar.sources. Projects often set sonar.sources=src, and then findings on package.json or Info.plist have nowhere to go.
  • The first analysis passes the gate anyway. SonarQube's default quality gate looks at new code, and on a project's first analysis nothing counts as new. From the next analysis on, a new NativeKeel finding counts like any other new issue.

What stays out of SonarQube

External rules don't appear in SonarQube's quality profiles, so accepted findings are managed on the NativeKeel side: a .nativekeel.json in the repo lists them, each with a reason, and they stay visible in every NativeKeel report. Malware warnings can't be ignored that way.

Your code stays where it is: NativeKeel runs in your pipeline and writes a JSON file. Only package names go to npm and React Native Directory, and --offline sends nothing.

Setup page with the details: nativekeel.com/sonarqube. If your team runs SonarQube on mobile apps, I'd like to hear what else you'd want to see in it.

Top comments (0)