Capacitor 3 brings crucial updates to the ecosystem and exciting new features.
Read the Capacitor 3.0 beta announcement ›
After upgrading your app to Capacitor 3, would you mind sharing any feedback you have in this discussion? We’d love to hear from you! 💖
If you’re a plugin author looking to upgrade your plugins to newer Capacitor versions, see the Upgrade Guide for Capacitor Plugins.
🚧 This guide is a work-in-progress. Thanks for your patience!
Node 8 has reached end-of-life. Node 10 will reach end-of-life on April 30th, 2021. Capacitor 3 requires NodeJS 12 or greater. (Latest LTS version is recommended.)
npm install @capacitor/cli@next @capacitor/core@nextCapacitor 3 now builds for ES2017 environments, instead of ES5. The plugin template has also been updated to target ES2017, and third-party plugins are encouraged to update their targets.
This change should not affect your app unless you are supporting IE11, which Capacitor does not officially support.
Capacitor 3 uses a newer TypeScript syntax which can only be used in TS 3.8 or later.
All plugins have been removed from Capacitor core and placed into their own npm packages. There are several reasons for this (see #3227) and the core team is confident this is the right way to go.
@capacitor-community/media.openUrl() and canOpenUrl()) moved into
App LaunchershowActions()) moved into
Action Sheetalert(), prompt(), and confirm()) moved into DialogThis change will require you to install each plugin that you were using individually.
Plugins object from @capacitor/coreUsing Ionic Framework?
The Ionic Framework makes use of APIs in the following plugins:
For best performance with Ionic Framework, you should make sure these plugins are installed even if you don’t import them in your app:
npm install @capacitor/app @capacitor/haptics @capacitor/keyboardThe
Plugins object is deprecated, but will continue to work in Capacitor 3. Capacitor plugins should be updated to use the new plugin registration APIs (see the
Upgrade Guide for plugins), which will allow them to be imported directly from the plugin’s package.
Going forward, the
Plugins object from
@capacitor/core should not be used.
// OLD
import { Plugins } from '@capacitor/core';
const { AnyPlugin } = Plugins;Importing the plugin directly from the plugin’s package is preferred, but the plugin must be updated to work with Capacitor 3 for this to be possible.
// NEW
import { AnyPlugin } from 'any-plugin';While many of the plugin APIs remain the same to ease the migration process to Capacitor 3, some will require code updates and manual migrations.
isScreenReaderEnabled() method has been renamed to
isEnabled()'accessibilityScreenReaderStateChange' event has been renamed to
'screenReaderStateChange'speak() will only work if a screen reader is currently active. For text-to-speech capabilities while screen readers are active or not, use
@capacitor-community/text-to-speech.prefetch() has been removed.getInfo() (appVersion, appBuild, appId and appName). Use the App plugin’s getInfo() for this information.HapticsNotificationType enum keys have been switched from upper case to camel case to match other enums.requestPermission() was removed, use requestPermissions().requestPermission() was removed, use requestPermissions().share() method now returns
ShareResult instead of
anyshare() will no longer include
completed. If it was not completed, it will reject instead.migrate(). To update your app without affecting end users, call
migrate() before any other methods.@capacitor/coreIt is a good idea to add an import to
@capacitor/core to the TypeScript file that bootstraps your app. This will include the Capacitor JavaScript bridge into your app.
For example, in a React app, add the following import to
src/index.tsx:
+import '@capacitor/core';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));Capacitor 3 supports iOS 12+. Xcode 12+ is required. CocoaPods 1.8+ is recommended.
It’s recommended to upgrade CocoaPods to the latest stable version.
CocoaPods 1.8 switches to using a CDN, which means running
pod repo update periodically is no longer required.
Check your version of CocoaPods with
pod --version and visit
cocoapods.org for installation instructions.
Do the following for your Xcode project and app target: open the Build Settings tab. Under the Deployment section, change iOS Deployment Target to iOS 12.0.
Then, open
ios/App/Podfile and update the iOS version to 12.0:
-platform :ios, '11.0'
+platform :ios, '12.0'
use_frameworks!If your app is not already using Swift 5, open the Build Settings tab in your Xcode target, then change Swift Language Version to Swift 5 under the Swift Compiler - Language section.
public into the iOS target directoryIt is recommended in Capacitor 3 to move the
ios/App/public directory into
ios/App/App/public. This can be achieved in Xcode:
Remove existing public folder
App project, then the
App group, and select the
public folder.
Recreate public in the new location
App group inside the
App project and click
Add Files to “App”…App target).
It may look the same in Xcode, but the new public folder should now be relative to the App group, not the project root.
gitignore the new public folder
In
ios/.gitignore, change the ignore path from
App/public to
App/App/public. This folder contains a copy of your web assets and should not be committed.
App/build
App/Pods
-App/public
+App/App/public
App/Podfile.lock
xcuserdatanpm install @capacitor/ios@next
npx cap sync iosCAPBridge to
ApplicationDelegateProxy in application eventsIn
ios/App/App/AppDelegate.swift, update the following:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
// Called when the app was launched with a url. Feel free to add additional processing here,
// but if you want the App API to support tracking app url opens, make sure to keep this call
- return CAPBridge.handleOpenUrl(url, options)
+ return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Called when the app was launched with an activity, including Universal Links.
// Feel free to add additional processing here, but if you want the App API to support
// tracking app url opens, make sure to keep this call
- return CAPBridge.handleContinueActivity(userActivity, restorationHandler)
+ return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}CAPNotifications to NSNotification extensionsIn ios/App/App/AppDelegate.swift, update the following:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let statusBarRect = UIApplication.shared.statusBarFrame
guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }
if statusBarRect.contains(touchPoint) {
- NotificationCenter.default.post(CAPBridge.statusBarTappedNotification)
+ NotificationCenter.default.post(name: .capacitorStatusBarTapped, object: nil)
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
- NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: deviceToken)
+ NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
- NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error)
+ NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}DerivedDataAdd
DerivedData to the
ios/.gitignore file. This is where the Capacitor CLI places native iOS builds.
App/Pods
App/App/public
App/Podfile.lock
+DerivedData
xcuserdata
# Cordova plugins for CapacitorCapacitor 3 supports Android 5+ (and now supports Android 11). Android Studio 4+ is required.
npm install @capacitor/android@next
npx cap sync androidIn Capacitor 3, it is preferred to automatically load the Android plugins. In
MainActivity.java, the onCreate method can be removed. You no longer have to edit this file when adding or removing plugins.
public class MainActivity extends BridgeActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Initializes the Bridge
- this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
- // Additional plugins you've installed go here
- add(Plugin1.class);
- add(Plugin2.class);
- }});
- }
}If your app includes custom plugins, you do still have to register the plugins in
onCreate:
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ registerPlugin(PluginInMyApp.class);
}
}We now recommend using Gradle 6.5 with Capacitor projects. In Android Studio, open the File menu, then click Project Structure. In the Project section, change Gradle Version to 6.5 and Android Gradle Plugin Version to 4.1.1. Then, click OK.
You may want to evaluate suggested updates to Android packages in the Suggestions section of the Project Structure dialog.
In android/variables.gradle you can update the following variables:
ext {
minSdkVersion = 21
- compileSdkVersion = 29
- targetSdkVersion = 29
+ compileSdkVersion = 30
+ targetSdkVersion = 30
+ androidxActivityVersion = '1.2.0'
- androidxAppCompatVersion = '1.1.0'
+ androidxAppCompatVersion = '1.2.0'
+ androidxCoordinatorLayoutVersion = '1.1.0'
- androidxCoreVersion = '1.2.0'
- androidxMaterialVersion = '1.1.0-rc02'
- androidxBrowserVersion = '1.2.0'
- androidxLocalbroadcastmanagerVersion = '1.0.0'
- androidxExifInterfaceVersion = '1.2.0'
- firebaseMessagingVersion = '20.1.2'
- playServicesLocationVersion = '17.0.0'
+ androidxCoreVersion = '1.3.2'
+ androidxFragmentVersion = '1.3.0'
- junitVersion = '4.12'
- androidxJunitVersion = '1.1.1'
- androidxEspressoCoreVersion = '3.2.0'
+ junitVersion = '4.13.1'
+ androidxJunitVersion = '1.1.2'
+ androidxEspressoCoreVersion = '3.3.0'
cordovaAndroidVersion = '7.0.0'
}Capacitor 3 supports Android 11 (API 30), so you can update your SDK target to 30. Change
compileSdkVersion and
targetSdkVersion to
30.
A new
androidxActivityVersion variable is available, add it with value
1.2.0.
The
androidxAppCompatVersion can be updated to
1.2.0.
A new
androidxCoordinatorLayoutVersion variable is available, add it with value
1.1.0.
The
androidxCoreVersion can be updated to
1.3.2.
The
androidxMaterialVersion variable was used by Action Sheet and Camera plugins, can be removed if not using them. If using them, check
Camera docs and
Action Sheet docs.
The
androidxBrowserVersion variable was used by Browser plugin, can be removed if not using the plugin. If using the plugin, check the
docs.
The
androidxLocalbroadcastmanagerVersion variable can be removed.
The
androidxExifInterfaceVersion variable was used by Camera plugin, can be removed if not using the plugin. If using the plugin, check the
docs.
The
firebaseMessagingVersion variable was used by Push Notifications plugin, can be removed if not using the plugin. If using the plugin, check the
docs.
The
playServicesLocationVersion variable was used by Geolocation plugin, can be removed if not using the plugin. If using the plugin, check the
docs.
A new
androidxFragmentVersion variable is available, add it with value
1.3.0.
The
junitVersion can be updated to
4.13.1.
The
androidxJunitVersion can be updated to
1.1.2.
The
androidxEspressoCoreVersion can be updated to
3.3.0.
Depending on which plugins you are using, you can optionally remove unused permissions from your app’s
AndroidManifest.xml file.
The manifest in new Capacitor apps only includes
INTERNET because permissions are now meant to be added when plugins are installed. Follow these steps to remove unused permissions:
AndroidManifest.xml file, keep permissions that your plugins require, remove permissions that are unusedThe Haptics and Network plugins are examples of plugins that now include their install-time permissions in their own
AndroidManifest.xml files, which end up
being merged with your app’s. It is safe to remove their permissions from your app’s
AndroidManifest.xml file:
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
- <!-- Network API -->
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <!-- Vibration API -->
- <uses-permission android:name="android.permission.VIBRATE" />
</manifest>