10/08/2026

FlutterFlow in production: what it handles, what it never touches, and where you still need engineers

The objection to low-code is always the same, and it isn’t unreasonable: fine for a prototype, but you’ll rebuild it the moment it has to do anything serious.

We’ve shipped a dozen production systems on FlutterFlow: commission management for real estate transactions, identity verification with KYC flows, a storm-data collection platform, an AR toy app with NFT assets, an edtech product on the app stores. So it’s worth being specific about where that objection is wrong, and where it’s exactly right.

We’re a FlutterFlow Expert Agency, so read what follows with appropriate suspicion. It’s written to be the post we’d want someone to have read before the first call, including the parts that argue against using it at all.

What actually changes with FlutterFlow

FlutterFlow generates Flutter. The output is a real Flutter codebase that compiles to native iOS, Android and web. That single fact resolves most of the anxiety, because it means the exit is an export, not a rewrite.

What you’re buying is compression of the layer that consumes the most time and produces the least differentiation: screens, navigation, state wiring, form handling, platform build configuration. That work is genuinely repetitive, and the visual layer does it faster than a person typing it.

What you are not buying is an escape from architecture. Every system below still needed data modelling, integration design, security decisions and someone who understood what happens under load.

Three more things get compressed and they’re worth naming, because vague speed claims are how these projects get mis-scoped. Backend wiring: authentication, a document database, file storage and serverless functions configured from one place with the client generated against them. Firebase is the default and the best-supported path, but Supabase and plain REST APIs are both first-class alternatives, and that choice should follow your data shape rather than the builder’s preference. Build and release plumbing: icons, splash screens, build flavours, platform configuration and store submission artefacts; unglamorous, error-prone, and genuinely faster here. Version control and shared visibility: real-time collaboration means a designer, a developer and a stakeholder can look at the same thing at once, and the GitHub integration means the output still lands in a repository. That second part matters more than the first. An app whose history isn’t in Git isn’t a maintainable asset, whatever it cost to build.

Where it holds up better than people expect

Integration-heavy business applications. Inmopay manages commissions on real estate transactions, and it talks to Unnax for payments, Holded for accounting, HubSpot for CRM, Signaturit for digital signatures and OneSignal for notifications. That’s five external services with different auth models and failure characteristics.

This surprises people, because “low-code” implies you’re confined to whatever the vendor supports. In practice the integration surface is ordinary API work; the visual layer just isn’t where the difficulty lives. The hard part was what it’s always been: what happens when Signaturit says a document was signed but the accounting write fails.

Regulated flows. VerifyGo does identity and document verification for onboarding: KYC, real-time validation, an architecture built around traceability. This is precisely the category people assume rules out low-code. It didn’t. What it ruled out was being careless: audit trails, data handling and failure states had to be designed deliberately, exactly as they would in a hand-written stack.

MVPs that must survive contact with users. Certistrike collects and validates storm reports from smartphones, with geolocation and a contributor points system for data quality. The reason to build that quickly isn’t cost; it’s that you cannot learn whether people will contribute reliable data without putting it in their hands. FlutterFlow gets to that answer sooner, and Certistrike didn’t need rebuilding to keep going.

Products with real device features. Quicine scans receipts to digitise a pantry and recommends recipes from what’s in it. Droyz Toys does AR and NFT assets. Camera, geolocation, push, AR: this is Flutter’s territory, and the visual layer doesn’t obstruct it.

Where you still need engineers

Being straight about this matters more than the sales case.

The data model. Firestore is a document database with a query engine that will happily let you design something that works at a hundred records and collapses at a hundred thousand. Collection structure, denormalisation choices, composite indexes, pagination, and the read patterns you’ll need for reporting are all architecture decisions. The builder will not make them for you, and it will not warn you when you make them badly. This is where most FlutterFlow projects that fail, fail. And it fails silently, months later, under data volume.

Security rules. This is the one that should worry you. A generated client is a client. Anything the client can query, a determined user can query, and “the app doesn’t show that screen to that role” is not access control; it’s the appearance of access control. Enforcement lives in server-side rules and nowhere else. Nearly every FlutterFlow project we’ve taken over from someone else has needed the rules rewritten, and in more than one case they were effectively absent.

Failure behaviour. What the product does when the network is gone, when a write half-succeeds, when a third party times out, when a webhook arrives twice. These are product decisions, and nobody makes them in a visual editor by accident. The Inmopay question (what happens when the signature service confirms a document but the accounting write fails) has no default answer, in any tool.

If you take one thing from this: the visual layer compresses the frontend and leaves the backend exactly as hard as it was.

Backend architecture is not a low-code problem. Firebase sits behind almost everything we’ve built this way, and the difference between a system that scales and one that doesn’t is entirely in data modelling, query patterns and security rules. Nothing in a visual builder saves you from a badly-shaped collection. This is where most FlutterFlow projects that fail, fail. And it fails silently, months later, under data volume.

Complex state gets awkward. Straightforward CRUD and forms are pleasant. Multi-step flows with interdependent conditional state, offline behaviour and conflict resolution get harder to express visually than in code, and past a certain point you should stop fighting it and write custom code, which FlutterFlow supports precisely for this.

Deep platform work. Custom native modules, unusual background processing, tight OS integration: possible, but you’re writing Flutter and native code anyway, so evaluate honestly whether the visual layer is still earning its place.

Very large teams on one codebase. Code review, granular version control and parallel work across many developers are better served by conventional repositories. For small focused teams the trade is favourable; at twenty engineers it inverts.

Payments: the advice in most tutorials is wrong

There is a genre of FlutterFlow tutorial (we published one ourselves, which is part of why this section exists) that shows you how to accept payments by adding an API call in the builder, pasting in your payment provider’s keys, and defining a request body with the amount in it.

Do not do this.

Secret keys must never be in the client. Anything compiled into the app ships to every device that installs it and can be extracted. A payment provider’s secret key in a mobile binary is a live credential in public. Publishable keys are designed for the client; secret keys are not, and no amount of HTTPS changes that, because the problem isn’t the transport.

The amount must never be set by the client either. If the app tells the server what to charge, the app can be modified to say a different number. Price is a server-side fact. The client says what is being bought; the server decides what that costs.

The correct shape is boring and well established. The client collects payment details through the provider’s own SDK or hosted flow, so raw card data never touches your code. A server-side function creates the charge, using the secret key and the server’s own price lookup. The provider confirms the outcome to your backend by webhook, and the webhook, not the client’s success screen, is what marks the order paid. Add an idempotency key so a retried request can’t take the money twice.

In FlutterFlow that means a Cloud Function, not an API call defined in the builder. It is more work than the tutorial version. It is also the difference between a payments integration and a liability.

This holds for every provider: Stripe, Flutterwave, Adyen, a regional payment service provider your market requires. The names change; the shape doesn’t. If a tutorial for any of them has you pasting a secret key into the builder, it is describing the same mistake in a different vocabulary.

The rest of the standard advice survives: use the provider’s test environment properly, validate on the server as well as the client, and monitor failed transactions after launch rather than discovering them in a support ticket.

Commerce and tracking apps: what the step-by-step guides skip

Two of the most common briefs (an online store and an order-tracking app) look like screen problems and are actually state problems.

Inventory is concurrency, not a field. Decrementing stock when a purchase completes is a one-line instruction in a tutorial and a race condition in production. Two buyers, one unit, simultaneous checkout. You need a transactional decrement, an explicit oversell policy, and a decision about whether stock is reserved at cart or at payment.

Something else usually owns the truth. If there’s an ERP, a warehouse system or an existing store platform, it owns stock and price, and your app holds a read model that goes stale on a schedule you choose deliberately. Two systems both believing they own stock is not an edge case; it’s the default outcome of not deciding. The platform-side version of this argument is in our guide to choosing an e-commerce platform.

Carrier data is not real-time. Tracking integrations with the major carriers are poll-and-cache, not a live feed. Design for a status that updates periodically and an interface honest about when it last did. “Out for delivery, as of 40 minutes ago” is information; an unqualified status is an implied promise you can’t keep.

Notifications need a policy before they need a provider. Push through Firebase Cloud Messaging or a service like OneSignal is the easy half. The hard half is deciding which status transitions are worth interrupting someone for, and letting them turn the rest off. Over-notifying is the fastest route to an uninstall.

An admin panel is a roles project. “A screen where staff manage products” means authentication, role assignment, per-role rules enforced server-side, and an audit trail of who changed what. It is also where operational thresholds live (low-stock alerts, failed-payment queues, orders stuck in a status longer than they should be), because the people who need to act on those are the people already in that panel. That’s a real slice of the build and it belongs in scope from the start.

Don’t build reporting over your transactional database. Sales reports and dashboards run aggregate queries that document databases are bad at and that compete with the queries serving your users. Export to somewhere built for it. This is the single most common reason a fast app becomes a slow one.

Test the integration, not the click-through. The failures that matter before launch are a carrier API returning a shape you didn’t anticipate, a webhook arriving twice, a payment confirming after the app has already timed out, and the whole thing running on a device two years older than the one on your desk. None of those appear in a walkthrough of the happy path, and all of them appear in the first week of real use. Usability testing tells you whether people understand the screens; integration and device testing tell you whether the product works.

The question that actually decides it

Not “is FlutterFlow production-ready”; that’s been answered by anyone shipping on it. The useful question is:

Where does the difficulty in this system actually live?

If it lives in the interface (many screens, forms, standard flows, several platforms from one codebase), the visual layer removes real work and you’ll ship materially sooner.

If it lives in the domain (complex calculations, heavy concurrency, unusual data shapes, deep platform integration), then the interface was never your bottleneck, and optimising it buys you little.

Most business applications are the first kind. Most people assume theirs is the second.

You can drop into custom Dart for any of this, but if you’re doing it constantly, you’re maintaining a hand-written app inside a visual tool and paying for both.

What to ask a FlutterFlow agency

  • Can I have the Flutter code? The answer should be immediate and unqualified. If ownership or export is hedged, that’s the whole conversation.
  • What’s behind it, and who designed the data model? If nobody can talk fluently about the backend, the backend is the risk.
  • What have you integrated? Payments, e-signature, CRM, KYC. Ask for specifics. Integration experience is where low-code agencies diverge most.
  • When would you tell me not to use FlutterFlow? An agency without a clear answer will use it for everything, including the projects where it’s wrong.

We’re a FlutterFlow Expert Agency and have shipped it into fintech, identity verification, edtech, AR and climate data. If you want a straight answer on whether it fits your system, describe it to us, including the parts you think might rule it out.

  • Can I have the Flutter code, unconditionally, from day one? The answer should be immediate and unhedged. Ours is that repositories live in the client’s organisation from the start and the client owns all IP outright, with no licence back to us. Ask everyone you shortlist; the answers vary more than buyers expect.
  • Where does every secret live? If any answer is “in the app”, stop and fix that before discussing anything else.
  • Which system owns stock, price and the customer record? One owner each, written down, before the build starts.

We’re a FlutterFlow Expert Agency and a Google Cloud Partner, and we’ve put Flutter into fintech (Inmopay), identity verification and KYC (VerifyGo), AR with NFT assets (Droyz Toys), edtech published through both app stores (Walnutflow) and climate data (Certistrike), as well as SEOaaS, our own AI SEO platform, which means we operate one of these rather than only building them. We’ll also tell you when your product isn’t a fit. Describe what you’re building, including the parts you think rule it out.

Related news

FlutterFlow in production: what it handles, what it never touches, and where you still need engineers
Interface work that holds up: accessibility, restraint, feedback and speed
Choosing an e-commerce platform, and the work that actually decides whether it sells
What to automate first: a practical order of operations for operations teams
La Digitalización de las Pymes en España
The Digitalization of SMEs in Spain
Bienestar Digital: Cómo Encontrar Equilibrio en una Vida Hiperconectada
Digital Wellbeing: How to Find Balance in a Hyperconnected Life