So, in a sense, when you are building, and this is just a simplification for React native, when you're building a React native app, you have your app over here in this blue box being ran inside of a JavaScript runtime. It could be V8, something else. But essentially, that is running your JavaScript, and that runtime will communicate through a bridge layer. Any time that bridge layer tries to access device features, it's going to proxy out to the actual device features, get the results, serialize that to JSON, and then return that to the JavaScript runtime and that is going to be sent back to your app.
As the UI gets evaluated, the bridge layer is also going to communicate to the native runtime and render out all the controls essentially on the fly. So, all of the UI elements, the buttons, cards, tab navigation, is all getting rendered on the fly internally via react native. And this is actually a pretty similar infrastructure to other projects. It is not specific to react native so don't assume that. There is a very similar architecture to Cordova here. The only difference is that instead of a JavaScript runtime, it is a full browser ecosystem, and we separate out the rendering process and just use the browser to render. So these are very similar architectures.
My and this is a bit of my own personal opinion towards it, where it kind of breaks down is having this idea of different, having to learn a new syntax that isn't essentially the same stuff that you've learned for web development. Having to learn how to redo h1, h2, paragraph tags, anchor tags is kind of kind of frustrating. I get why they did that, but it is yet another thing to learn. If you have an existing web app where you are trying to get that into the native runtime or the native stores, you're unfortunately going to need to rewrite that app to support this React Native runtime. Some people will do that, and they will say it's okay, but it's still just a frustrating feeling. And then finally, if there's a third-party library that you really, really like, if it does not support React Native out-of-the-box, you can't use it. So, I have one of my favorite libraries out there is fill.js, which is a rich text editor. You can't use that in React Native because of how it's built and how it works. You have to find one that's specific to React Native in order to get it to work in a React Native app, which seems not right, in my opinion.
Yeah, I mentioned it earlier, but the idea that it's truly native is a bit misleading. Architecturally, it is still running JavaScript, controls are rendered on the fly, there's essentially a custom rendering agent. This last point for folks who are interested in Flutter, this is something that you do need to deal with is that the rendering is not actually rendering native controls, it's rendering things in the loosest sense on a canvas. And then you're just interacting and re-implementing all of the native interactions. Take that for what it's worth, it is just the fact. So moving on, what are the other options here? Ideally, we want something that kind of bridges the native development life cycle, but also still very much in this web developer mentality where I am just writing HTML, CSS and JavaScript. I can bring not only React, but any framework into my toolkit and I can just ship whatever I want. So that is what we'll focus on today, and that is Capacitor.
So, in a runtime, Capacitor is a native runtime and a JavaScript library. It is at first a way for you to import packages that provide access to the native device features. So similar to Cordova in that sense. Except that each package itself allows it to wrap various different APIs and we'll look at how that works. The APIs that you as a developer actually interface with are streamlines. That way you have this one particular way of accessing the file system and then the packages that you will interact with know how to send those options and call certain methods that fit on iOS or Android. And when you want to include a new package, it's basically just pulling that in from the native package managers inside of the respective projects. So if I install, say, our file system API, it's an npm install for me, but behind the scenes it's using CocoaPods to fetch the dependencies for iOS, using Android libraries for Android. So the package management story here and how the code gets from your node modules to the native project feels at home for those respective platforms.
So let's take a look at the architecture because I think this is actually pretty important. So we have our web app here in the blue box again, and it gets rendered inside of a native web view. This native web view is basically just an optimized version of Chrome, Safari, what-have-you without any of the browser UI elements in there. When you go ahead and make a call from your web app through capacitors API, that native web view is going to be able to hear that call, or at least know that something inside of it is trying to call a capacitor API. It'll get the information that you're trying to call for the certain device that you're trying to call, and it will send that to the bridge layer. The bridge layer will then proxy out to the native features, whether they are operating system-level features or hardware features. Serialize the results, return it back, send it to the native web view, and then that will get returned to your JavaScript code. So architecturally, this is very similar to how React Native works, with the exception that we are rendering our own UI. So if you have a UI library, or if you have your own design system in place, you can bring that to a capacitor project and still have the same experience between your website, your native iOS app, and your native Android app. So great experience all around. How this is different is that, as I said, you could reuse your existing web apps and your existing web skills. This includes third party libraries, frameworks, again, we're looking at it with React today, but this is framework independent. So if down the road, you work in a project, and you have to use something like Svelte or solid, or view in The runtime loads instantly, so as your app is booting up, it is essentially able to call native APIs right away.
Comments