---
description: A look at the most useful changes in Capacitor 8.4.0 — three Android SystemBars fixes, a new getDouble config method, and experimental SPM packageOptions.
title: What's New in Capacitor 8.4.0: SystemBars, getDouble & packageOptions - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/whats-new-in-capacitor-8-4-0.png
---

[ Skip to content](#whats-new-in-capacitor-840-systembars-getdouble-packageoptions) 

[ 🔐 Introducing the **Capacitor Vault** plugin — store secrets behind biometrics or a device passcode.](/blog/announcing-the-capacitor-vault-plugin/) 

* [  Formbricks ](/docs/plugins/formbricks/)
* [  Geocoder ](/docs/plugins/geocoder/)
* [  Google Sign-In ](/docs/plugins/google-sign-in/)
* [  Grafana Faro ](/docs/plugins/grafana-faro/)
* [  libSQL ](/docs/plugins/libsql/)
* [  Live Update ](/docs/plugins/live-update/)
* [  Managed Configurations ](/docs/plugins/managed-configurations/)
* [  Media Session ](/docs/plugins/media-session/)
* [  ML Kit ](/docs/plugins/mlkit/)
* [  Navigation Bar ](/docs/plugins/navigation-bar/)
* [  NFC ](/docs/plugins/nfc/)
* [  OAuth ](/docs/plugins/oauth/)
* [  Pedometer ](/docs/plugins/pedometer/)
* [  Photo Editor ](/docs/plugins/photo-editor/)
* [  PostHog ](/docs/plugins/posthog/)
* [  Printer ](/docs/plugins/printer/)
* [  Purchases ](/docs/plugins/purchases/)
* [  RealtimeKit ](/docs/plugins/realtimekit/)
* [  Screen Orientation ](/docs/plugins/screen-orientation/)
* [  Screenshot ](/docs/plugins/screenshot/)
* [  Secure Preferences ](/docs/plugins/secure-preferences/)
* [  Speech Recognition ](/docs/plugins/speech-recognition/)
* [  Speech Synthesis ](/docs/plugins/speech-synthesis/)
* [  Share Target ](/docs/plugins/share-target/)
* [  Square Mobile Payments ](/docs/plugins/square-mobile-payments/)
* [  SQLite ](/docs/plugins/sqlite/)
* [  Superwall ](/docs/plugins/superwall/)
* [  Torch ](/docs/plugins/torch/)
* [  Vault ](/docs/plugins/vault/)
* [  Wifi ](/docs/plugins/wifi/)
* [  Zip ](/docs/plugins/zip/)
* [  Cloud ](/docs/cloud/)
* [  Live Updates ](/docs/cloud/live-updates/)
* Advanced
* Integrations
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Configuration ](/docs/cloud/native-builds/configuration/)
* [  Environments ](/docs/cloud/native-builds/environments/)
* Guides
* [  Sample Projects ](/docs/cloud/native-builds/sample-projects/)
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  Automations ](/docs/cloud/automations/)
* [  Assist ](/docs/cloud/assist/)
* Account
* Organizations
* [  Organization and User Management ](/docs/cloud/organizations/memberships/)
* [  Single Sign-On (SSO) ](/docs/cloud/organizations/sso/)
* [  Teams ](/docs/cloud/organizations/teams/)
* [  Two-Factor Authentication ](/docs/cloud/organizations/two-factor-authentication/)
* [  Integrations ](/docs/cloud/integrations/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Pricing ](https://capawesome.io/pricing/)
* [  FAQ ](/docs/cloud/faq/)
* [  Support ](/docs/cloud/support/)
* [  Contributing ](/docs/contributing/)
* [  LLMs ](/docs/llms/)
* [  Insiders ](/docs/insiders/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/insiders/support/)
* [  FAQ ](/docs/insiders/faq/)
* [  Blog ](/blog/)
* Categories

# What's New in Capacitor 8.4.0: SystemBars, getDouble & packageOptions[¶](#whats-new-in-capacitor-840-systembars-getdouble-packageoptions "Permanent link")

Capacitor 8.4.0 is out, and most of the work targets clean Android edge-to-edge: three `SystemBars` fixes tighten safe-area behavior. The release also adds a `getDouble` config getter and an experimental CLI option that untangles Swift Package Manager identity collisions, including one our own team ran into.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://capawesome.io/) 

## At a Glance[¶](#at-a-glance "Permanent link")

Here's the full list of changes in this release:

| Change                                             | Platform      | PR                                                         |
| -------------------------------------------------- | ------------- | ---------------------------------------------------------- |
| Safe-area insets exposed on older Android versions | Android       | [#8424](https://github.com/ionic-team/capacitor/pull/8424) |
| show() only toggles the requested bar              | Android       | [#8480](https://github.com/ionic-team/capacitor/pull/8480) |
| insetsHandling: "disable" now respected            | Android       | [#8481](https://github.com/ionic-team/capacitor/pull/8481) |
| New getDouble(...) config getter                   | iOS + Android | [#7638](https://github.com/ionic-team/capacitor/pull/7638) |
| Experimental SPM packageOptions                    | iOS           | [#8471](https://github.com/ionic-team/capacitor/pull/8471) |
| Live-reload config reverted on failed run          | CLI           | [#8485](https://github.com/ionic-team/capacitor/pull/8485) |
| Telemetry captures the iOS package manager         | CLI           | [#8482](https://github.com/ionic-team/capacitor/pull/8482) |

## Three SystemBars Fixes for Android Edge-to-Edge[¶](#three-systembars-fixes-for-android-edge-to-edge "Permanent link")

Most of the work in 8.4.0 sits in the Android `SystemBars` API. Capacitor 8.3.x is where native edge-to-edge support came together: insets read from the platform and injected as `--safe-area-inset-*` CSS variables, separate styling for the status and navigation bars, and the end of the third-party plugin being a hard requirement. The 8.4.0 release cleans up three issues that were left over.

**Safe-area insets are now injected on older Android versions too.** Previously the injected `--safe-area-inset-*` values were only available on newer API levels. As of 8.4.0 they're also exposed on API level 34 and below ([#8424](https://github.com/ionic-team/capacitor/pull/8424)), so the inset values stay consistent whether your app runs on Android 14 or Android 16\. If you've adopted the recommended `var(--safe-area-inset-*, env(safe-area-inset-*))` pattern, this means one less device-version branch to reason about.

**`show()` no longer reveals the wrong bar.** Calling `SystemBars.show({ bar })` to bring back just the status bar used to drag the navigation bar along with it, because the implementation reached for the combined `systemBars()` inset type. The `hide()` path already handled the two bars separately; now `show()` matches it and only touches the bar you asked for ([#8480](https://github.com/ionic-team/capacitor/pull/8480)).

**`insetsHandling: "disable"` is finally respected.** If you opted out of Capacitor's inset handling with `insetsHandling: "disable"`, the setting wasn't actually honored on Android. That's fixed in 8.4.0 ([#8481](https://github.com/ionic-team/capacitor/pull/8481)), so teams that prefer to manage insets entirely on their own get the behavior they configured.

Each fix is minor on its own. Together they remove the inconsistencies that otherwise cost an afternoon of debugging. If you're setting up edge-to-edge from scratch, our [Capacitor Edge-to-Edge & Safe Areas guide](/blog/capacitor-edge-to-edge-and-safe-areas-guide/) walks through the full 2026 setup and now reflects these 8.4.0 changes.

## A New `getDouble(...)` Plugin Config Method[¶](#a-new-getdouble-plugin-config-method "Permanent link")

Native plugins read their configuration through the plugin config API, which already had typed getters for strings, booleans, integers, arrays, and objects — but no way to read a floating-point value directly. You had to grab it as a string or object and convert by hand.

Capacitor 8.4.0 closes that gap with `getDouble(...)` ([#7638](https://github.com/ionic-team/capacitor/pull/7638)), available on both platforms. Say a plugin exposes a `scaleFactor` option in the Capacitor config; reading it now looks like this on Android:

`[](#%5F%5Fcodelineno-0-1)double scaleFactor = getConfig().getDouble("scaleFactor", 1.0);
`

And the same on iOS:

`[](#%5F%5Fcodelineno-1-1)let scaleFactor = getConfig().getDouble("scaleFactor", 1.0)
`

The second argument is the default that's returned when the key is missing, so you always get a usable value back. If you maintain plugins, that's a bit of conversion boilerplate you no longer have to copy-paste.

## Experimental `packageOptions` for Swift Package Manager[¶](#experimental-packageoptions-for-swift-package-manager "Permanent link")

We reported this one. Several teams had hit a Swift Package Manager bug ([#8451](https://github.com/ionic-team/capacitor/issues/8451)), and the Capacitor team shipped a fix in the same release.

Here's the background. When you use SPM instead of CocoaPods, the CLI generates a `Package.swift` that references each plugin as a local-path package. The catch is that SwiftPM derives a package's _identity_ from the last component of its directory path and ignores the `name:` you pass in. Because npm controls those directory names, two plugins can end up with the same identity. In our own [Capacitor Firebase](https://github.com/capawesome-team/capacitor-firebase) plugins this showed up in two flavors ([#959](https://github.com/capawesome-team/capacitor-firebase/issues/959)):

* A hard error when two local plugins collide — for example `@capacitor/app` and `@capacitor-firebase/app`, both resolving to identity `app`.
* A warning that SwiftPM says will become an error, when a local plugin collides with a transitive remote dependency — `@capacitor-firebase/app-check` versus the `google/app-check` package pulled in by the Firebase iOS SDK.

Either way, the build is blocked and there's nothing the plugin author can do about it, since renaming the npm package would break every consumer.

Capacitor 8.4.0 adds an experimental `packageOptions` config ([#8471](https://github.com/ionic-team/capacitor/pull/8471)) to solve exactly this. Setting `symlink: true` for a package tells the CLI to create a uniquely-named symlink, so SwiftPM derives a distinct identity and the collision disappears:

capacitor.config.json

`[](#%5F%5Fcodelineno-2-1){
[](#%5F%5Fcodelineno-2-2)  "experimental": {
[](#%5F%5Fcodelineno-2-3)    "ios": {
[](#%5F%5Fcodelineno-2-4)      "spm": {
[](#%5F%5Fcodelineno-2-5)        "packageOptions": {
[](#%5F%5Fcodelineno-2-6)          "@capacitor-firebase/app-check": {
[](#%5F%5Fcodelineno-2-7)            "symlink": true
[](#%5F%5Fcodelineno-2-8)          }
[](#%5F%5Fcodelineno-2-9)        }
[](#%5F%5Fcodelineno-2-10)      }
[](#%5F%5Fcodelineno-2-11)    }
[](#%5F%5Fcodelineno-2-12)  }
[](#%5F%5Fcodelineno-2-13)}
`

If you also run into a _target_ name conflict — a separate problem where two plugins ship Swift targets with the same name — there's a companion `moduleAliases` option to rename one of them:

capacitor.config.json

`[](#%5F%5Fcodelineno-3-1){
[](#%5F%5Fcodelineno-3-2)  "experimental": {
[](#%5F%5Fcodelineno-3-3)    "ios": {
[](#%5F%5Fcodelineno-3-4)      "spm": {
[](#%5F%5Fcodelineno-3-5)        "packageOptions": {
[](#%5F%5Fcodelineno-3-6)          "@capacitor-community/device": {
[](#%5F%5Fcodelineno-3-7)            "symlink": true,
[](#%5F%5Fcodelineno-3-8)            "moduleAliases": {
[](#%5F%5Fcodelineno-3-9)              "DevicePlugin": "CommunityDevicePlugin"
[](#%5F%5Fcodelineno-3-10)            }
[](#%5F%5Fcodelineno-3-11)          }
[](#%5F%5Fcodelineno-3-12)        }
[](#%5F%5Fcodelineno-3-13)      }
[](#%5F%5Fcodelineno-3-14)    }
[](#%5F%5Fcodelineno-3-15)  }
[](#%5F%5Fcodelineno-3-16)}
`

Both options live under `experimental`, so expect the shape to evolve — but they're available now and they unblock SPM for the plugins that were stuck. We've already documented the required `symlink` setting in each affected [Capacitor Firebase](https://github.com/capawesome-team/capacitor-firebase) plugin's README. Note that this requires `@capacitor/cli` **8.4.0 or later**.

## Honorable Mentions[¶](#honorable-mentions "Permanent link")

A couple of smaller changes round out the release:

* **The CLI reverts your live-reload config when a run fails** ([#8485](https://github.com/ionic-team/capacitor/pull/8485)), so a failed `run` no longer leaves your project pointing at a dev server URL.
* **Telemetry now captures the iOS package manager** ([#8482](https://github.com/ionic-team/capacitor/pull/8482)), which should give the team better insight into CocoaPods-versus-SPM adoption as the ecosystem shifts.

## Get Started[¶](#get-started "Permanent link")

Upgrading takes a few commands:

`[](#%5F%5Fcodelineno-4-1)npm install @capacitor/core@^8.4.0 @capacitor/cli@^8.4.0
[](#%5F%5Fcodelineno-4-2)npm install @capacitor/android@^8.4.0 @capacitor/ios@^8.4.0
[](#%5F%5Fcodelineno-4-3)npx cap sync
`

If you're coming from an older major, the [Updating to Capacitor 8](/blog/updating-to-capacitor-8/) post covers the breaking changes worth knowing about first.

[Subscribe to the Capawesome Newsletter](https://capawesome.io/newsletter)

## Final Thoughts[¶](#final-thoughts "Permanent link")

If you're fighting Android system bars or moving from CocoaPods to Swift Package Manager, Capacitor 8.4.0 is worth the upgrade. The SystemBars fixes make edge-to-edge behavior more predictable across Android versions, `getDouble` removes some plugin boilerplate, and `packageOptions` clears a real blocker for SPM adoption. Credit to the Capacitor team for the quick turnaround on the SPM fix: from reported bug to shipped option in a single release cycle.

To go further from here:

* [Capacitor Edge-to-Edge & Safe Areas: The Complete Guide](/blog/capacitor-edge-to-edge-and-safe-areas-guide/) — the full setup for getting safe areas right on both platforms, updated for 8.4.0.

Got questions or hit an edge case of your own? Drop into the [Capawesome Discord server](https://discord.gg/VCXxSVjefW) — we're always happy to chat. And to catch the next deep-dive in your inbox, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter).

June 2, 2026 

 Back to top 