February 10, 2023
  • All
  • Perspectives
  • Capacitor

Capacitor: Everything You’ve Ever Wanted to Know

Max Lynch

CEO

What is Capacitor?

Capacitor makes it possible for any web developer to build native iOS, Android, Desktop, and Progressive Web Apps, all with a single standard web codebase. Created in 2018 by us, the team behind Ionic, Capacitor was built initially to replace Cordova as the de facto tool that web developers use for mobile, and its role in our stack.

Recently, there’s been a wave of fresh attention on Capacitor. Over the last two years, developers that invested a considerable amount of time in alternatives like React Native are coming back to the web platform and realizing how far web technologies on mobile have come. Developers are excited to use their favorite web frameworks, like Next.js, and deploy the same code to native mobile. The dream of a single standard web codebase being able to create great apps everywhere is basically here today with Capacitor.

With all this, I wanted to take a step back and re-introduce Capacitor to the broader web development community through a question-and-answer format, compiling a list of some of the best and most common questions we’ve received over the years. With so many new web developers entering the industry each year and teams starting to question the platforms they invested in over the last few years, I realized we need to start from zero and explain what Capacitor is, where it fits, and why you should consider it as a web developer or mobile app development team.

What is Capacitor?

Capacitor is a free and open source (MIT-licensed) platform that enables web developers to build cross-platform apps with standard web technology that runs in modern browsers. Capacitor consists of native platform SDKs (iOS and Android), a command line tool, a plugin API, and pre-made plugins.

Capacitor takes your existing web application and runs it as a native app on each platform, providing hooks into the native platform via JavaScript. These hooks can be built directly into the app, or as standalone plugins to be reused and distributed to others.

Capacitor can run any web app built with any technology stack, making it a general-purpose environment for running web apps natively.

The metaphor I’ve always liked for Capacitor is a “virtualization engine for web apps” that abstracts away the complexities of each platform to enable web apps to run natively, anywhere.

What can you build with Capacitor?

Basically: anything you would build natively or with other cross-platform toolkits you can build with Capacitor, and potentially more because of the ability to run on the web.

Capacitor apps have full access to the native platform under the hood, so generally anything a developer can do natively can be done in Capacitor. For example, displaying Native UI controls over the Web View. The only exception being embedding Native UI controls directly into the the web app view hierarchy (something that can be simulated as we do in our Google Maps plugin, but is more of a challenge and we’ve not yet made that technique abstracted enough for others to use).

Who is Capacitor for?

Capacitor is targeted at web developers who have an HTML, CSS, and JavaScript background. If you build web apps or desktop apps today (Electron/etc) then Capacitor is your solution for building cross-platform apps with an emphasis on mobile.

When should a team choose Capacitor?

Whenever someone asks me this question, I run through this decision making framework (click to expand):

Capacitor Decision Framework.

Can I reuse existing web code and share new code with a web app?

Yes! One of the strengths of Capacitor is that it runs normal web apps natively. In many cases teams have a single codebase for web and mobile using Capacitor. Still other teams reuse pieces of their web app, such as components, logic, or specific experiences.

What is Capacitor really good at? Not so good at?

Capacitor is best-in-class at running standard web apps as native mobile apps, along with extending the web app with any native functionality the app needs. This makes it ideal for teams that are already proficient in web development or have significant existing web investments, but want to deploy native platform apps to reach new users or use native features.

Capacitor is ideal for data-driven apps, such as consumer apps or B2B/E apps. It’s especially great for enterprise apps as Ionic, the company that makes Capacitor, is the only popular mobile platform that offers dedicated enterprise support and features.

Capacitor is not a terrible choice for 3D/2D or graphically-intensive apps, given broad support for WebGL. In fact, it’s used in such apps as Vampire Survivors.

Apps that need to communicate a large amount of data between the Web App and the native layer will find the Capacitor communication bridge adds overhead due to serialization. That being said, Capacitor apps can always run custom native code (Swift/Kotlin/Java) when needed and bring in native experiences written in those languages to bridge any gaps.

Capacitor is a bad fit for teams that want to use a language like Swift, Kotlin/Java, or Dart exclusively or those that wish to build a fully stock iOS or Android app and stay as close to official languages and tooling as possible. (However, our Portals solution is a solid middle-ground when these apps need to bring in web experiences with a micro frontend approach.)

Are Capacitor apps native or native-quality?

Capacitor apps are technically fully native apps. On mobile they use the standard iOS and Android project structure and view hierarchy, of which the Capacitor Web View is a part. However, to get the full value prop of deploying a standard web app everywhere, developers spend most of their time writing code that runs in the Web View control. This makes these apps “hybrid” or “web native.”

For a deeper dive on this topic, I wrote this blog post several years ago describing how Capacitor works under the hood, and it still applies today.

Can I mix Native UI controls with Capacitor?

Yes. Think of your Capacitor Web View as just one native control. The app can display any native control outside of this Web View (such as a modal or a parent-level navigation container). Embedding native controls into the flow of the web view experience is possible as mentioned above, but not available as a technique for others to use just yet.

How are Capacitor and Electron different?

We often describe Capacitor as “Electron for mobile” because Capacitor is basically the mobile-focused analog to Electron. However, there’s nuance here. Capacitor can target Electron as a deployment platform because Capacitor is a higher level abstraction than Electron.

The best way to think about this here is that if you only ever need to target desktop, Electron will do everything you need. But if you’d like to build cross-platform including mobile, web, and desktop, Capacitor will allow you to do that in addition to supporting Electron.

How are Capacitor and Ionic different?

This is one that people are very confused about, and for good reason. This is made worse by the fact that “Ionic” has been overloaded and means a lot of different things to different people.

Here’s a technical definition of each of these terms:

  • Ionic – the company that makes Capacitor, Ionic Framework, Stencil, Appflow, and many other app development-focused products.
  • Capacitor – the toolkit that handles the native side of the app and the communication between the native app and the Web View. Capacitor is completely agnostic of the frameworks and technologies used in the Web View app itself, including Ionic Framework.
  • Ionic Framework – the Mobile UI toolkit that was Ionic’s first product and started it all. Confusingly, Ionic Framework is often referred to just as “Ionic”. Ionic Framework runs in the Web View of a Capacitor app and provides a ton of powerful UI components that enable your web app to look and feel native, including navigation, modals, datetime controls, and more.

Ionic Framework apps historically used Cordova to handle cross-platform deployment and native access, but now use Capacitor. Ionic Framework and Capacitor are not the same thing and one can be used without the other (though it’s very rare for Ionic Framework apps to not use Capacitor, but not so rare for Capacitor apps to not use Ionic Framework).

We know it’s confusing but we deliberately wanted to separate Capacitor’s brand from Ionic to indicate that Capacitor is framework agnostic and a utility that can be used by any web developer using any web development stack. We will be evolving this branding and positioning over time because we don’t think it’s quite there yet.

Do I need to use Ionic Framework with Capacitor?

No! In fact one of the most exciting trends we’re seeing is developers “bringing their own UI” to Capacitor and not using Ionic Framework’s controls. While we still believe Ionic Framework is the best way to make your web app follow native platform conventions and have great performance and user experience, the reality is that you can build a great experience using many modern UI toolkits in the market.

For example, many teams are successful using UI and CSS frameworks like Tailwind, Material UI, Chakra, Quasar, Framework7, or their own homegrown components. Just keep in mind that if you go this route it’s your responsibility to make sure your app looks and feels like a great mobile app.

We’ve recently expanded our documentation to explore the different options for building the UI of your app.

What is Ionic’s strategy with Capacitor?

Fun fact: Capacitor npm installs today now exceed Ionic Framework. This is by design! We built Capacitor years ago because we wanted to create a more frontend-agnostic stack for web developers to build mobile apps. We know that Ionic Framework is highly opinionated, which is great for many teams and use-cases, but is naturally going to make it a fit for only a subset of the web development market.

At Ionic, we view Capacitor as our OSS project with the largest addressable market, and all of Ionic’s commercial products are actually largely based around Capacitor. Our primary goal is to drive Capacitor adoption because that’s what drives adoption of Appflow (our mobile CI/CD service), Ionic Framework (the best UI framework for Capacitor), and our enterprise solutions.

Can I use Capacitor with React and Next.js or Remix?

Capacitor and React are a match made in heaven, and React developers often remark how using Capacitor keeps them closer to standard React web development than React Native because all the normal React libraries and add-ons Just Work in Capacitor (which definitely cannot be said for React Native as it’s not a web environment).

Capacitor can be used with full-stack React frameworks like Next.js and Remix. For Next.js in particular, developers can use the static export approach to bring the Next.js app into the native Capacitor binary that ships to the app stores, or host portions of the app remotely to use the full Next.js SSR features.

For more information, see my Capacitor + Next.js Starter and our Capacitor + Remix Templates. We are also working on an index of starters for other popular web stacks.

How are Capacitor and React Native different?

Surprisingly, Capacitor and React Native are more alike than they are different. For example, both platforms provide tooling and plugin infrastructure to allow JavaScript to communicate with Native iOS/Android/desktop platforms. Developers can build native plugins for each platform and expose them to JavaScript.

The differences start to show when you look at the core of your app. React Native provides a web-like system using JS and React that abstracts away platform Native UI controls. Capacitor, in contrast, provides a Web View so the core of your app is just a standard web app.

This means React Native will actually be quite a bit different from a standard web-based React app than the same app running in Capacitor. Developers who want to use existing React libraries and web technologies like CSS will find Capacitor to be a more typical React environment than React Native.

Capacitor is also far less complex than React Native. Since React Native provides an abstraction over iOS and Android Native UI controls, a significant amount of complexity comes into play managing these controls and syncing them with the JS layer of the app. This complexity can be seen in the relative challenge of keeping a React Native app updated to the latest versions of React Native over time, compared to Capacitor.

Is Capacitor faster than React Native?

It depends! Capacitor can actually execute JavaScript significantly faster than React Native because it has full access to the JIT engine available on iOS and Android. React Native does not have access to this for its main JS execution (on iOS at least) because Apple only allows WKWebView processes to just-in-time compile JS for security reasons. Capacitor uses WKWebView and, thus, benefits from this runtime environment. Some JS workloads benefit significantly from having a JIT engine, and some don’t.

For the UI side, this is where many will say React Native is “faster” or “more performant” than Capacitor because React Native orchestrates Native UI controls while Capacitor apps are mainly running in a Web View. For apps that exclusively use the UI in their Web View, this is probably true in some cases because there is overhead to rendering in the Web View that isn’t there when using Native UI controls. However, things start to get murky here when you consider that Capacitor apps can use Native UI screens when needed, and Web View rendering can maintain consistently high interactive frame rates.

Beyond that, Capacitor is far simpler than React Native (and others) and has way fewer moving parts. Take a look at a standard Capacitor iOS project and you’ll notice that it’s basically the standard Xcode project template with a few extra Capacitor files.

How are Capacitor and Flutter different?

Much like Capacitor is similar in some ways to React Native, so too is it similar to Flutter, though less so. Both Capacitor and Flutter provide tooling and plugin infrastructure to allow cross-platform code to communicate with Native iOS/Android/desktop platforms. However, this is where the similarities end.

Capacitor uses JavaScript and standard web technology, while Flutter uses Dart and has built a fully custom UI and API environment. Of course, while the choice of programming language is critical for long-term maintenance and hiring questions, that will always be an intensely subjective difference.

On the UI side, Flutter and Capacitor apps will both use a “custom” rendering engine by nature (i.e. not the stock iOS/Android UI system). Flutter draws all of its components itself (so no, Flutter UI controls are not “native” in that way), and Capacitor apps will generally have most of their UI rendered by the Web View.

On the web side, Capacitor apps are standard DOM-based web apps with full support for standard web technologies like CSS and any popular web library, while Flutter Web apps render in a custom container (such as canvas) where all controls are drawn by Flutter and can only support the features Flutter specifically enables. This is important for sites that have frequent traffic and must have strong SEO and accessibility, as Flutter Web apps require significant client-side JS to implement these primitives in a custom, Flutter-specific way.

I hesitate to say that Flutter is “more native” than Capacitor, because that starts to get at deep questions about what “native” even means. Technically, a Web View running machine code from JIT-compiled JS and rendering through a browser engine built in C++ looks a lot like a Flutter rendering pipeline to me.

How can I host a web app remotely and load it in Capacitor?

Capacitor supports loading remote web apps. This is a great way to use SSR-ed web apps.

There are a few ways to do this. First, the app can load a remote URL by default, instead of a local app. The other alternative is to use our Portals solution to load multiple remote web apps in the context of an existing mobile app.

Can I embed Capacitor into React Native or traditional native apps to build mobile micro frontends?

Yes! Use Ionic Portals, which is a heavily modified version of Capacitor that comes with cloud services and support to enable teams to bring a true micro frontend approach to mobile. Portals supports React Native or traditional iOS/Android apps built with Swift/Kotlin.

What are my options for high-performance animations in Capacitor?

For pre-baked, optimized components that have mobile-style animations built in, Ionic Framework and other toolkits like Quasar and Framework7 are an option.

For building custom animations, developers have a number of options. Framer Motion is a great option for React, Lottie is popular, and there is a utility inside of Ionic Framework that we use for all of our animations that can be helpful. Your framework of choice also probably has animation utilities available.

Beyond that, CSS animations are a major way that developers animate on the web, and that works great in Capacitor. Provided, of course, developers follow performance best practices and animate properties like transform and opacity.

How many plugins does Capacitor have?

Capacitor has, at the time of this writing, 26 core plugins. The community builds and maintains many additional plugins. See awesome-capacitor for a comprehensive list, the capacitor-community org, and Capawesome for three such community plugin resources.

Is there a VS Code Extension for Capacitor?

Yep! The Ionic VS Code Extension we released last year doubles as a Capacitor extension (I know, the naming is confusing). The extension is awesome and has tons of features like embedded preview, device running, external debugging, project quality linting, security analysis, and more.

Is there enterprise-specific support available?

Yes. Ionic, the company that makes Capacitor, offers Enterprise support and features targeted at use-cases in medium to large companies. This includes dedicated Capacitor support, native plugins for security and authentication, and more.

Where did the name come from?

Capacitor was inspired by the electrical symbol for a capacitor.

How do I get started?

Thought you’d never ask! Check out the Capacitor docs and follow the instructions to install Capacitor in your app. If you’d like to start a more opinionated Capacitor app using Ionic Framework and Angular/React/Vue, follow the Get Started flow on the Ionic Framework site.

Anything else?

If you made it this far, thank you! I hope I’ve helped clarify some of the misconceptions about Capacitor. If I didn’t answer one of your burning questions, please share it in the discussion link below.


Max Lynch

CEO