What is Flutter?
In the early stages of mobile development, you had two options: build your app twice (once for iOS in Swift, once for Android in Kotlin) or compromise on quality by wrapping a web view. The first option doubled your engineering costs and created divergent user experiences. The second option left users with janky interfaces that felt wrong on both platforms.
Flutter changed this equation. It’s Google’s open source UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase. Unlike earlier cross-platform frameworks that wrapped native components, Flutter draws its own pixels, giving you complete control over every frame that renders on screen.
Flutter isn’t experimental anymore. Companies like eBay Motors use it for their vehicle marketplace app. BMW uses it for its connected car experiences. Nubank, one of the world’s largest digital banks, builds its mobile app with Flutter.
This article explains how Flutter works under the hood, why businesses and developers choose it, and the ecosystem of tools around it.
How Flutter works: the architecture
Section titled “How Flutter works: the architecture”Most cross-platform frameworks act as translators. They take your code and convert it into native iOS and Android UI components at runtime. This translation layer creates performance bottlenecks and inconsistencies because iOS buttons don’t behave exactly like Android buttons.
Flutter takes a different approach. It doesn’t use native platform widgets at all. Instead, it draws every pixel itself using a high-performance graphics engine. Think of it like a video game engine, but for building apps. On iOS, Android, desktop, and web, Flutter controls the entire rendering pipeline from your code down to the pixels on screen.
Flutter originally drew with Skia, the 2D graphics library that powers Chrome and Android. Today it uses Impeller, a renderer that compiles its shaders when Flutter itself is built rather than while your app runs, so animations don’t stutter the first time they play. Impeller is the only renderer on iOS, the default on Android API 29 and newer (since Flutter 3.27), and the default on macOS, Windows and Linux (since Flutter 3.47). Flutter on the web still uses Skia. When your Flutter app renders a button, it’s not asking the OS for a button component. It’s drawing the exact pixels that make up that button, down to the shadow and animation curves.
Google chose Dart as the programming language for Flutter for specific technical reasons. Dart compiles to native ARM machine code on mobile, which means your production app runs at full speed without a JavaScript bridge or interpreter. During development, Dart’s Just-in-Time (JIT) compiler powers Hot Reload, one of Flutter’s most praised features. You can change your code and see the result in under a second, without losing your app’s state or restarting.
Flutter’s architecture centers on widgets. Everything in Flutter is a widget, from structural elements like rows and columns to styling properties like padding and margins. You compose these widgets together to build your interface. A button isn’t a single object. It’s a composition of widgets for gesture detection, padding, material effects, and text styling. This composability makes Flutter interfaces predictable and testable.
The framework uses Ahead-of-Time (AOT) compilation for production builds. Your Dart code compiles directly to native ARM code, eliminating the runtime overhead of interpretation or just-in-time compilation. This is why Flutter apps can maintain 60fps (or 120fps on high-refresh displays) consistently. The framework’s rendering pipeline is designed to complete all work for a frame in under 16 milliseconds, the budget for 60fps rendering.
Flutter’s architecture has one more advantage: consistency across platforms. Because Flutter controls its own rendering, a button looks identical on iOS 15, Android 13, and a three-year-old device. You’re not at the mercy of platform differences or OS version fragmentation.
Why developers and businesses choose Flutter
Section titled “Why developers and businesses choose Flutter”Hot Reload changed how mobile developers work. Before Flutter, changing a UI element meant recompiling your app, reinstalling it, and navigating back to the screen you were working on. This cycle took 30-60 seconds. With Hot Reload, you save your file and see the change in a few seconds, with your app’s current state preserved. You can iterate on animations, test edge cases, and experiment with designs at a pace that wasn’t possible before.
For businesses, the math is simple. You write one codebase instead of two. That means one team instead of two separate iOS and Android teams. You don’t need to synchronize features between platforms or maintain parity between codebases. When you fix a bug, it’s fixed everywhere. When you ship a feature, it ships to all your users at once.
Flutter gives you pixel-perfect control over your interface on every screen size. You’re not limited by platform conventions or native component libraries. Companies building design systems appreciate this control. You can match your brand guidelines exactly, animate transitions the way your designers envisioned, and create custom UI components that work identically across mobile, desktop, and web.
Dart’s null safety system, introduced in Dart 2.12, prevents null reference errors at compile time. These errors are responsible for billions of dollars in software failures across the industry. Dart’s type system catches null errors before you ship code to users. The language also supports modern features like async/await for handling asynchronous operations, strong type inference, and extension methods for adding functionality to existing classes.
The business case extends beyond engineering efficiency. Teams shipping Flutter apps report faster time-to-market because they’re not coordinating two platform-specific releases. They can experiment more freely because changes are cheaper to make. Most importantly, they can maintain quality standards across all platforms without fragmenting their engineering resources.
The Flutter ecosystem
Section titled “The Flutter ecosystem”A framework is only useful if you can actually ship production apps with it. Flutter has a commercial ecosystem of tools and consultancies that cover the full application lifecycle.
The tooling stack
Section titled “The tooling stack”Shorebird solves one of mobile development’s biggest frustrations: app store review times. When you find a critical bug, you can’t just push a fix. You have to submit an update, wait 24-48 hours for Apple’s review (longer on weekends), then wait for users to actually install the update. Shorebird enables over-the-air updates for Flutter apps. You can patch bugs and ship changes directly to your users’ devices. It updates your Dart code while your native shell stays unchanged, so the shell still goes through normal App Store and Play Store review.
Codemagic is a CI/CD platform built specifically for mobile apps. Generic CI systems like GitHub Actions work, but they weren’t designed for the specific needs of mobile builds: managing certificates, provisioning profiles, platform-specific signing, and coordinating releases across multiple stores. Codemagic handles these mobile-specific workflows out of the box. It integrates with Shorebird and provides specialized workflows for releasing to the App Store, Play Store, and Firebase App Distribution.
ServerPod lets you build your backend in Dart. Most Flutter apps talk to a backend written in Node.js, Python, or Go. ServerPod lets you write full-stack applications in a single language. It includes an ORM, API generation, authentication, and real-time communication. If you’re building a Flutter app and need a backend, ServerPod means your entire team can work in Dart with shared types and business logic between client and server.
Widgetbook is Storybook for Flutter. It creates a catalog of your UI components where you can develop widgets in isolation, test them with different data, and document their usage. When you’re building a design system or working on a team where designers need to review components, Widgetbook provides a development environment focused purely on UI components, separate from your app’s business logic and navigation.
Consultancies
Section titled “Consultancies”Teams without in-house Flutter experience often start with a consultancy. Very Good Ventures, for example, publishes Very Good CLI for scaffolding projects and writes widely used guidance on structuring large Flutter codebases.
Flutter vs. the competition
Section titled “Flutter vs. the competition”Comparing Flutter with the alternatives shows what its design trades off.
Flutter vs. React Native
Section titled “Flutter vs. React Native”The biggest difference is what draws the UI. A React Native app runs your
JavaScript in a JavaScript engine (Hermes by default) and renders real platform
views: a React Native <Switch> becomes a UISwitch on iOS and a native switch
on Android. Since React Native 0.76, the
New Architecture is the
default: JavaScript calls native code directly through JSI rather than sending
serialized messages over the old asynchronous bridge, and from 0.82 the legacy
architecture can no longer be turned on
(React Native 0.82 release notes).
Flutter compiles your Dart code ahead of time to machine code and draws every pixel itself, so there is no JavaScript engine at runtime and no platform view per widget. That makes rendering identical across OS versions, and puts animation-heavy UIs entirely under the framework’s control.
React Native’s approach has an advantage: because it uses real native components, a new OS look applies to React Native apps without a framework change. The same property means your app can look and behave differently across OS versions. Flutter trades that automatic updating for consistency across platforms and OS versions.
The difference also shapes over-the-air updates. A React Native app’s JavaScript bundle is data the engine loads at startup, so services such as EAS Update replace the bundle. Flutter release builds contain compiled machine code, so updating them needs support in the engine itself, which is what Shorebird adds (see How Flutter builds your app).
Flutter vs. native development
Section titled “Flutter vs. native development”Building native apps in Swift and Kotlin gives you immediate access to every OS API and the latest platform features on day one. Flutter catches up quickly (usually within weeks of a platform update), but native development is always first to new capabilities.
The tradeoff is the maintenance burden. Native development means maintaining separate codebases with duplicated business logic, separate testing, and coordinated releases. For teams that can’t afford dedicated iOS and Android engineers, or for companies where mobile isn’t the core product, this duplication is expensive. Flutter significantly reduces this maintenance cost, though you give up the cutting edge of platform features.
The decision often comes down to your constraints. If you need the absolute latest iOS 26 features and your app’s value is tied to platform-specific capabilities, native development makes sense. If you need to ship across platforms quickly, control your interface precisely, and minimize long-term maintenance, Flutter is the better choice.
Where Shorebird fits in the stack
Section titled “Where Shorebird fits in the stack”The app stores serve a purpose. They enforce security standards, review apps for policy compliance, and give users confidence about the software they install. But every update goes through review, which typically takes a day or two, and then users have to install it. You can’t respond to production issues quickly.
This is the “last mile” problem. Flutter solves the problem of writing once and deploying everywhere. But you still hit the bottleneck of app store review times when you need to update your app.
Shorebird patches this last mile. When you find a bug, you create a patch and ship it directly to your users. The app downloads it in the background and runs it from the next launch, without users reinstalling your app. Shorebird works by separating your Dart code from your native app shell. The shell (which contains platform-specific code) goes through normal store reviews. Your Dart code (which is most of your app) can be updated over-the-air.
Shorebird works alongside the rest of the Flutter ecosystem. You can add
Shorebird commands to your Codemagic workflows to
create patches when you merge to production. Your developers keep their existing
tools: shorebird release takes the place of flutter build in your
deployment process, and
shorebird patch ships fixes.
The philosophy behind Shorebird is that big tech companies like Google, Meta, and Microsoft have solved these problems internally for their own apps. They have systems to update apps directly on users’ devices. Shorebird makes these capabilities available to every Flutter developer, not just teams with the resources to build their own infrastructure.
Next steps
Section titled “Next steps”Now that you understand Flutter and the ecosystem around it, here are practical paths forward:
Start Your First Flutter Project: Download the
Flutter SDK and follow the
Shorebird Quick Start to create a new project with Code
Push capabilities built in. The shorebird create command scaffolds a Flutter
app with Shorebird already integrated.
Set Up Your Development Workflow: Establish a robust development process by following Shorebird’s development workflow guide. Learn how to test patches before deploying them and implement staging environments to catch issues before production.
Implement Continuous Integration: Automate your build and deployment pipeline using Shorebird’s CI documentation. Whether you’re using GitHub Actions, Codemagic, or Fastlane, you can integrate Code Push into your existing workflows.
Prepare for Production Release: Before launching to the app stores, review the platform-specific guidelines in Releasing a Flutter App. Implement patch signing for additional security and set up percentage-based rollouts to gradually deploy updates to your user base.
Scale Your Team’s Usage: If you’re working with a team, set up Shorebird Organizations to manage access and collaborate on releases. Configure your apps to work with build flavors if you maintain multiple app variants, and see White Labeling if you publish the same app under several brands.