Languages
Dart
The language you write Flutter in — used well by engineers who run what they ship.
Overview
Dart is Google’s client-optimised, statically-typed language. It has a clean, C-style syntax that JavaScript, Java and C# developers pick up in days, sound null safety that moves a whole class of crashes to compile time, and async/await plus isolates for concurrency. On paper it reads like a sensible, modern general-purpose language, and it is. But you should understand why Dart exists in 2026 before you choose it: it exists to be the language of Flutter. Almost everything interesting about Dart today — its tooling, its ecosystem, its momentum — flows from that one relationship.
The design tells the story. Dart runs two different ways on purpose. During development it uses a JIT compiler with stateful hot reload, so a Flutter developer changes code and sees the running app update in under a second without losing its state — that fast feedback loop is the single best thing about building with Flutter, and Dart was shaped to make it possible. For release, the same code is compiled ahead-of-time (AOT) to fast native machine code on mobile and desktop, and to JavaScript or WebAssembly for the web. You get a productive dynamic-feeling workflow while building and predictable, fast native performance when you ship. Very few languages give you both halves that cleanly.
So here is our honest framing, up front. For us Dart is inseparable from Flutter. We reach for it when a client needs one cross-platform mobile or app codebase — see our Flutter page, which is where the real decision is made. Outside Flutter, Dart has little independent adoption: there is some server-side use through Dart Frog and Shelf, and it is pleasant enough for a small API that shares models with a Flutter front end, but it is a niche choice next to Node, Go or Python and we would not steer you to it on its own merits. Choosing Dart, in practice, means choosing Flutter. If you are not building with Flutter, there is rarely a good reason to pick Dart, and we will say so plainly.
Best for — Teams committed to Flutter for cross-platform mobile or app development — where Dart comes as part of that decision and its hot-reload workflow and native compilation earn their place.
Why teams choose Dart
One language across every target
The same Dart compiles to native ARM and x64 for mobile and desktop, and to JavaScript or WebAssembly for the web. One team writes one codebase and ships to several platforms, which is the whole economic argument for Flutter and, by extension, for Dart.
A development loop that changes how you build
JIT compilation with stateful hot reload means UI changes appear in the running app almost instantly, without restarting or losing state. On a screen-heavy product this compounds into real velocity — you tune layouts and flows by eye, in seconds, not build cycles.
Fewer runtime crashes by construction
Sound null safety pushes null-related failures — one of the most common sources of production crashes in mobile apps — into the compiler, where they are cheap to fix. Combined with static typing, a large amount of what would be runtime debugging simply never reaches your users.
Why businesses choose Dart
- You have chosen, or are choosing, Flutter for a cross-platform app, and you want the language written well rather than treated as an afterthought.
- You value a fast, iterative UI development loop and want a team that uses hot reload as a design tool, not just a convenience.
- You want the crash-resistance that sound null safety and static typing buy, so your mobile app is stable on the failures that most often reach users.
- You want engineers who are honest that Dart’s value is bound to Flutter, and who will tell you when Flutter — and therefore Dart — is the wrong choice before you spend on it.
What we build with Dart
The capabilities this technology is genuinely strong at — and what we most often build with it.
Stateful hot reload via JIT
While developing, Dart runs through a just-in-time compiler that supports stateful hot reload: change source, and Flutter injects the updated code into the running app, preserving its state. We use this deliberately — building UI by rapid iteration rather than rebuild-and-click — because it is where a lot of Flutter’s speed advantage actually comes from.
AOT compilation to native and web
For release, Dart compiles ahead-of-time to native machine code on mobile and desktop, and to JavaScript or WebAssembly for the browser. That is why a Flutter app starts fast and runs at native speed with no interpreter overhead — the same code that felt dynamic while building ships as a compiled binary.
Sound null safety
Dart’s null safety is sound, meaning the compiler can guarantee a non-nullable variable is never null. This is stronger than the opt-in null checks of some languages, and we lean on it hard: nullability is a design decision made once, in the types, not a defensive check scattered through the code.
Isolates for true concurrency
Dart handles concurrency with isolates — independent workers that do not share memory and communicate by message passing — rather than shared-memory threads. This sidesteps a whole class of data races. We use isolates for genuinely heavy work (parsing, image processing) so the UI thread stays smooth, and async/await for the common I/O case.
The pub ecosystem and toolchain
Packages come from pub.dev, resolved and versioned by the pub package manager, with the analyser, formatter and test runner built into a single coherent toolchain. We are conservative about which packages we pull in — every dependency in a Flutter app is code you ship and maintain — and we favour well-supported, Flutter-team-adjacent ones.
Async, streams and the event loop
Dart’s single-threaded event loop with Futures, async/await and Streams is how a Flutter app stays responsive while waiting on the network, disk or platform channels. We model asynchronous data as Streams where it fits (live updates, sensor feeds) and keep the async boundaries explicit so behaviour stays predictable.
Use cases
Cross-platform consumer apps
A single Dart and Flutter codebase serving iOS and Android from one team — the most common and most defensible reason to use Dart at all. One product, two stores, no duplicated native effort.
Internal and field tools
Line-of-business and field apps where a company needs the same tool on every employee’s device without funding parallel native teams. Dart’s productivity and Flutter’s single codebase make these economical to build and keep current.
Design-led, UI-heavy products
Apps with lots of custom screens, motion and branded interface, where hot reload lets engineers and designers tune the UI tightly and quickly. Dart’s development loop is a real advantage on exactly this kind of work.
Shared models with a Dart backend
Occasionally, a small server-side Dart service (via Dart Frog or Shelf) that shares data models and validation with the Flutter app, so one type definition serves both ends. A niche fit we use only when the sharing genuinely pays for itself — not as a default backend choice.
When Dart is the right choice
- Right when you have already decided Flutter is the right way to build your app — one codebase for iOS and Android (and often web and desktop) from a single team. Dart is not really a separate decision here; it is the language Flutter obliges you to write, and it is a good one.
- Right when the fast development loop matters to how you work: Dart’s hot reload lets designers and engineers iterate on UI in seconds, which is a genuine productivity advantage on a UI-heavy product with a lot of screens and states.
- Right when your team’s background is JavaScript, Java, Kotlin, Swift or C#. Dart’s syntax and its sound null safety feel immediately familiar, so the ramp-up cost is spent learning Flutter’s widget model, not the language underneath it.
- Wrong when Flutter is the wrong tool. If you need deep, platform-specific native integration, a genuinely tiny app footprint, or a single-platform build that plays to iOS or Android strengths, native (Swift, Kotlin) is the better answer — and then Dart is simply not in the conversation.
- Wrong as a general-purpose or backend language chosen on its own. If you want Dart for a server, a CLI or data work with no Flutter in the picture, mainstream languages have larger ecosystems, deeper talent pools and more battle-tested libraries. We would talk you out of it.
Dart: pros and cons
Strengths
- Sound null safety and static typing catch a real category of bugs at compile time, so shipped apps crash less on the errors that plague dynamically-typed mobile code.
- The dual JIT-plus-AOT model gives you a fast, stateful-hot-reload development loop and fast native machine code at release — a rare combination you normally have to choose between.
- Clean, familiar C-style syntax with async/await makes Dart easy for JavaScript, Java, Kotlin, Swift and C# developers to read and write productively within days.
- The pub package manager and the Dart toolchain (formatter, analyser, test runner) are cohesive and well-maintained, so day-to-day developer experience is genuinely good.
Trade-offs
- Dart’s ecosystem and mindshare are Flutter-dependent. The packages, tutorials and community energy assume you are building an app; step outside that and the ground gets thin fast.
- The talent pool is smaller than for mainstream languages. Hiring a strong Dart engineer usually means hiring a strong Flutter engineer, and there are fewer of them than there are JavaScript or Java developers.
- It has little independent use outside Flutter. Server-side Dart exists (Dart Frog, Shelf) but is niche, so Dart rarely makes sense as a backend or general-purpose choice on its own.
- Its fortunes are tied to Google’s continued investment in Flutter. Dart’s relevance rises and falls with one company’s strategic commitment to one framework — a concentration risk worth naming before you build on it.
Architecture
Because Dart in practice means Flutter, the architecture that matters is the app’s, and Dart is the material you build it in. The load-bearing decisions are how state is managed, how the widget tree is structured, and where the boundary sits between UI and business logic. We settle these early and keep them consistent, because a Flutter codebase that mixes state-management approaches or leaks logic into widgets becomes hard to reason about at exactly the size where it starts to matter.
We keep business logic out of widgets and in typed, testable Dart — services, repositories and view models — with the chosen state-management layer (commonly Riverpod, Bloc or the framework’s own primitives) as the seam between them. Sound null safety and static types do real work here: contracts between layers are enforced by the compiler, so refactoring a large app is a mechanical, low-fear activity rather than a gamble. Where the app talks to native platform features, that crosses a platform channel, and we treat those boundaries as deliberate, documented interfaces rather than incidental glue.
Performance
Dart’s AOT-compiled native code means a released Flutter app has no interpreter or bridge between your logic and the device — a genuine advantage over some cross-platform approaches. Startup is fast and computation runs at native speed. The performance problems that do arise are almost always in the Flutter layer above Dart: rebuilding too much of the widget tree, expensive work on the UI thread, or oversized images. We profile with Dart DevTools rather than guessing, then fix the specific cause — narrowing rebuilds, moving heavy work to an isolate, caching decoded assets.
The one target to be honest about is the web. Dart compiles to JavaScript (and increasingly WebAssembly), and Flutter web works, but it does not match a purpose-built web front end on first-load size or on behaving like a native web page. We treat Flutter web as viable for app-like experiences behind a login, and we do not pretend it is the right tool for a fast, indexable public site — that is a different job, and we will say so.
Security
Dart’s static typing and sound null safety remove a class of memory and null-related faults before they ship, which is a security benefit as much as a stability one. Beyond the language, security in a Dart app is mostly about the same disciplines any mobile client needs: never trusting the device, keeping secrets off it, and enforcing authorisation on the server rather than in the app, where anyone can inspect the compiled binary. We treat the Flutter app as an untrusted client by default.
Practically, that means secrets and API keys do not live in the Dart source, sensitive data at rest uses the platform’s secure storage rather than plain preferences, and transport is pinned and encrypted. We are careful with pub dependencies — every package is code running with your app’s privileges — keeping the tree small, current and watched for known vulnerabilities. Platform-channel code that reaches native APIs gets the same scrutiny as the Dart around it.
Scalability
For a Dart and Flutter app, scale is about the codebase and the team more than server traffic — the backend carries request load, while the app’s challenge is staying coherent as screens, features and engineers multiply. Feature-based structure, a clear state-management convention applied consistently, a shared widget library, and typed contracts between layers are what let several engineers work in one Flutter codebase without it fragmenting. Dart’s strong typing makes large-scale refactoring safe, which is what keeps a growing app maintainable.
The harder scaling question is organisational, and we are honest about it: the Dart and Flutter talent pool is smaller than for mainstream stacks, so staffing a large or long-lived app takes more deliberate hiring and stronger documentation. We plan for that from the start — readable, conventional code and clear boundaries — so your own team, or the next one, can pick the app up. And because Dart’s trajectory follows Google’s investment in Flutter, we keep the business logic in plain, well-separated Dart, not entangled with framework specifics, so you are never more locked in than the app truly needs to be.
Dart integrations & ecosystem
The technologies we most often pair with it — each links to how we work with it.
How we work
We start by making sure the real decision is the right one — is Flutter the correct way to build this app? Because choosing Dart is choosing Flutter, that conversation happens first, and sometimes it ends with us recommending native or a different approach entirely. Once Flutter is settled, we agree the architecture Dart will express: state management, layer boundaries, and how the app talks to its backend and to native platform features. These are cheap to get right early and expensive to unpick later.
From there we build in thin vertical slices — a real screen or flow, wired to real data, running on real devices — rather than a scaffold that demos well and does nothing. The engineers who design the app write it and keep it running; that is what we mean by operating what we build. We use Dart’s hot reload as a working tool, we lean on its type system to refactor without fear, and we make conservative package choices we will not regret when the app is eighteen months old and still shipping.
The service behind it
Delivered throughCustom Software DevelopmentWhat we build with Dart
The disciplines this technology most often shows up in — from a first build to taking over and stabilising an existing one.
How we deliver
- 01
Discover
We map the system, the constraints and the business it serves — including the parts nobody documented.
Architecture brief
- 02
Architect
Decisions get made, written down and defended before a line of production code exists.
Decision records
- 03
Build
Short cycles against working software. You see progress in the product, not in a status deck.
Shipping increments
- 04
Operate
Monitoring, incident response and iteration. The system is alive, so the engagement is too.
Runbooks & SLOs
Industries we use Dart in
Domain knowledge changes what gets built. A few of the sectors we know before the first meeting.
Also in Languages
Why teams choose us for Dart
Senior engineers only
Dart is written well or written twice. The people building your Flutter app have shipped them before and know how the decisions age — there are no juniors learning the language on your project.
We operate what we build
We run the apps we ship, so we optimise for the maintenance reality, not the demo: conventional Dart, conservative packages, and business logic kept separable from framework specifics.
Honest that Dart means Flutter
We will not sell you Dart as a general-purpose language it is not, and if Flutter is the wrong tool for your product we will tell you before you spend money — even when that means recommending native and no Dart at all.
Typical timeline
- 01
Discovery and decision
One to two weeks confirming Flutter is the right choice, agreeing platforms, and settling the app architecture, state approach and backend contracts before code volume grows.
- 02
First vertical slice
Two to three weeks delivering one real flow end to end on real devices — proving the architecture and the integrations against reality rather than a plan.
- 03
Iterative build
Screen-by-screen delivery in short cycles, each running on iOS and Android, with performance and accessibility checked as we go rather than bolted on at the end.
- 04
Hardening and store release
Final profiling with Dart DevTools, tests on the load-bearing paths, store submission and the documentation your team needs to own and extend the app.
How pricing works
- Fixed-scope app builds for a well-defined Flutter product — a defined set of screens, integrations and platforms — quoted once we understand the flows and the backend it talks to.
- Monthly senior engagement for ongoing app development, where scope evolves across releases and you want a stable team that keeps the codebase healthy rather than a one-off deliverable.
- Focused audits and rescues for existing Dart and Flutter codebases — performance, architecture, or a stalled build — priced by the assessment.
Hire Dart engineers
Need Dart capacity on your own team? We embed named senior engineers into your existing team — reporting to your leads, working in your rituals — so you add capacity without a hiring cycle.
Hire Dart engineersCommon questions
Is choosing Dart the same as choosing Flutter?
In practice, yes. Dart’s tooling, ecosystem and momentum almost all come from Flutter, and outside Flutter it has little independent adoption. So the real decision is whether Flutter is right for your app — if it is, Dart comes with it, and it is a good language to inherit. If Flutter is wrong for you, there is rarely a reason to reach for Dart on its own, and we will say so.
Can I use Dart for backend or server-side work?
You can — Dart Frog and Shelf let you write servers, and it is pleasant for a small API that shares data models with a Flutter app. But it is a niche choice: the ecosystem and talent pool are far smaller than Node, Go or Python. We use server-side Dart only when sharing types with the app genuinely pays for itself, never as a default backend, and we would not steer you to Dart for a server on its own merits.
What actually makes Dart good for building apps?
Two design choices. During development it runs through a JIT compiler with stateful hot reload, so UI changes appear in the running app in under a second — a real productivity gain on screen-heavy work. For release it compiles ahead-of-time to fast native machine code, so the shipped app starts quickly and runs at native speed. Sound null safety and static typing on top remove a common class of crashes before users ever see them.
How hard is Dart to learn for our existing developers?
Not hard, if they know a C-style language. Dart’s syntax is close to JavaScript, Java, Kotlin, Swift or C#, and most developers read and write it productively within days. The genuine learning curve is Flutter’s widget model and its state management, not Dart the language — which is another way of saying the language is rarely the obstacle.
What is the biggest risk in betting on Dart?
Concentration. Dart’s relevance is tied almost entirely to Flutter, and Flutter’s to Google’s continued investment in it. That is a real risk worth naming before you build. We manage it the sensible way: keep business logic in plain, well-separated Dart rather than entangled with framework specifics, so if the landscape shifts your core logic is portable and you are never more locked in than the app truly needs to be.
Building on Dart?
A technical conversation with the engineers who would do the work. If we are not the right fit, we will say so on the call.