Skip to content
Tech Stack18 September 2026 · 10 min read

When Pub Packages Break Inside FlutterFlow's Build

Some Flutter packages compile locally and die inside FlutterFlow's cloud build. Here is how I check a dependency on its pub.dev page before designing a widget around it.

When Pub Packages Break Inside FlutterFlow's Build

A package that compiles on my laptop is not a package FlutterFlow will build.

That gap has shaped more of my FlutterFlow work than any decision about Dart. Across eight marketplace templates and more than forty custom widgets, the question I answer before designing anything is not whether the widget can be written. It is whether the dependency it needs will survive the cloud build. When someone searches for why their FlutterFlow custom code package is not working, they are almost never staring at a syntax error. They are standing on the seam between a package that assumes an ordinary Flutter project and a build system that is not one.

If the vocabulary here is new, start with what Flutter actually is and how it differs from a wrapper, then come back.

Why is your FlutterFlow custom code package not working?

Risograph-style print of a padded parcel jammed halfway through a narrow brass letter slot, its crushed corner torn open with tape peeling away, ink layers slightly misregistered

Usually because it needs something the cloud build cannot give: native platform code, missing web support, or a version FlutterFlow has already pinned.

Notice what is absent from that list. Your code. The widget you wrote is usually fine. What fails is the resolution step that runs before your Dart is ever compiled, and the failure surfaces as a build error that names packages you did not add, in versions you did not choose.

FlutterFlow's own guidance on picking a dependency puts platform support first, and it is blunter than most people expect. In the section on choosing the correct package from pub.dev, FlutterFlow's custom code documentation states the requirement plainly: "WEB: It must support Web to run your app in our Run/Test Mode." Not a recommendation. A prerequisite for the editor's own preview to function, which means a package can be perfectly good, perfectly maintained, widely used on mobile, and still unusable to you.

The same page carries a warning people skim past: "The current dependency might depend on other dependencies to work. So make sure you also copy the name and version of all the additional dependencies." Transitive dependencies are where the surprises live.

What FlutterFlow actually does with a pub dependency

Two stacks of printed sheets pressed together into one block on a workbench, several sheets from the left stack protruding at the wrong length where the two meet, a dried coffee ring staining the bench beside them

You are not editing a pubspec. You are handing a name and a version string to a build system that already has opinions about both.

A dependency reaches a FlutterFlow project by one of two routes. You add it globally under Settings and Integrations, in the Custom Dependencies tab, or you paste the name and version into the Pubspec Dependency panel of the custom code editor beside the widget that needs it. Either way the platform merges your request into a pubspec it owns, alongside the packages FlutterFlow itself depends on for auth, storage, navigation and everything else the generated app does.

That merge is the whole story. Pub's version solver has to find one version of every package that satisfies your constraint, FlutterFlow's constraint, and every transitive constraint underneath both. When no such set exists, version solving fails, and it fails for the project rather than for your widget.

The Libraries documentation says the quiet part directly when describing conflicts between a project and an imported library: "if the project and the library share the same dependency, the version must match exactly to avoid conflicts." Exactly. Not compatibly. That is a much narrower target than the caret ranges you are used to writing by hand.

Why pure-Dart packages survive and native plugins do not

A printing press bed holding a heavy bolted iron bracket that has torn a ragged hole through the paper beneath it, next to a flat paper cut-out lying perfectly flush and undamaged

The reliable predictor of whether a package works inside a FlutterFlow custom widget is not its popularity. It is whether it ships native code.

A pure-Dart package is just source. It compiles into the app the same way your widget does, it has no Gradle or CocoaPods surface, and the cloud builder treats it as unremarkable. A plugin is a different animal. It carries Kotlin or Swift, expects entries in the Android and iOS project files, and sometimes requires permissions or capabilities declared at the platform level.

FlutterFlow is explicit about the limit here. Its MethodChannels guide states that the platform "does not allow direct editing of platform-native code (Kotlin, Swift) through its web UI", and the workflow it prescribes for native integrations is to build a Flutter plugin outside FlutterFlow, publish it to a Git repository, and add it to a custom action by Git URL.

Read that as a cost, because it is one. The moment a package needs native code you do not control, the dependency stops being a line in a panel and becomes a repository you maintain, version, and keep compiling against whatever Flutter version the platform is on this month. That is a reasonable trade for a vendor SDK with no alternative. It is an absurd trade for a date picker.

Actually, let me back up. Plenty of plugins do work, because FlutterFlow ships plenty of them itself. The distinction that matters is narrower: a plugin whose native side is already wired into the generated project is fine, and a plugin whose native side you would need to touch is not.

The cloud builder pins dependencies you never chose

Here is the failure mode that catches experienced Flutter developers, because it has no equivalent on a local machine.

The builder carries its own globally pinned dependency set. A package major that resolves cleanly in a local project can be simply unreachable inside FlutterFlow, not because the package is bad but because something below it is held back. A community thread on dependency constraints in the FlutterFlow Cloud Builder describes exactly this shape: a data-sync package's version 2 line requires newer releases of foundational packages than the cloud builder pins, so the upgrade resolves in VS Code and dies in the platform.

The second-order version is worse, because the conflict involves a package you never touched. A FlutterFlow issue opened on 9 September 2026 reports a web deployment failing with a message worth reading twice:

"Because digi_market depends on cloud_functions_web 4.11.2 which depends on web ^1.1.1, web ^1.1.1 is required. So, because digi_market depends on web 1.1.0, version solving failed."

The reporter could not find web 1.1.0 in either the custom or the FlutterFlow dependency list. It was coming from the generated code, introduced by enabling a feature rather than by adding a package. You cannot fix a constraint you cannot see, and you cannot always tell from the error which half of the pubspec is yours.

Which packages are safe inside a FlutterFlow custom widget?

Packages that are pure Dart, declare support for web alongside mobile, and depend on nothing whose major version the platform is already holding down.

Here is how I sort a candidate before it gets anywhere near a design:

Package shapeWhat it touchesBehaviour in the cloud buildWhat to do instead
Pure Dart, no platform codeNothing outside DartSafe. Resolves and compiles like your own widgetNothing. Use it
UI-only package with web supportWidget tree, paintingSafe in practice, and previews correctly in Run/Test ModeNothing. Use it
Plugin already bundled by FlutterFlowNative, but wired by the platformSafe, because the native side already exists in the generated projectPrefer the platform's own integration
Plugin needing Kotlin or Swift you would editAndroid and iOS project filesFails. There is no web UI for native codeWrap it in your own Flutter plugin, add it by Git URL
Package with no web supportTransitive imports pull in dart:io or native-only APIsBreaks Run/Test Mode even where a mobile build succeedsFind a web-capable alternative, or gate the feature per platform
Package pinned back by the builderShared transitive dependenciesVersion solving fails for the whole projectHold at the older major until the platform moves

The fourth row is the one that has cost me the most. Everything in a marketplace template ships together, including instructions, reference documentation, marketplace imagery and iOS screenshots, so a widget that cannot build is not one broken file. It is a submission that does not go out.

A five-minute dependency check before you design the widget

Run this on the pub.dev page, before a single line of widget code exists:

  1. Read the platform chips, not the README. pub.dev computes them rather than taking the author's word: its scoring documentation explains that "the platform support will be detected by analyzing the transitive import graph". If Web is missing from that row, FlutterFlow's Run/Test Mode requirement is already unmet.
  2. Open the Installing tab and count the dependencies. Every transitive package is another constraint the solver has to satisfy against FlutterFlow's own set. Two direct dependencies is a different risk profile from eleven, and the eleven-dependency package is the one that will fail on something three levels down.
  3. Check whether the repository has an android/ or ios/ directory. That single glance tells you whether you are adding a package or adopting a plugin. If those folders exist and contain more than a stub, assume the native path and price it accordingly.
  4. Look at the last publish date. FlutterFlow's documentation makes the same point about maintenance, noting that a regularly updated package "is more likely compatible with the latest Dart/Flutter versions and has fewer bugs". A package last touched two years ago is a package that has not met the current Flutter version.
  5. Weigh the quality score with the platform's own yardstick. FlutterFlow's docs describe Pub Points as telling "the quality of the dependency (out of 130) based on code style, platform support, and maintainability", which is a useful filter precisely because platform support is baked into it.
  6. Add it to a throwaway project and hit Run Mode before you build anything. Five minutes of waiting beats discovering the conflict after the widget is wired into four screens.

Steps one through three kill most bad candidates. Step six is the only one that is actually proof, and it is the one people skip.

What changed in February

FlutterFlow moved the underlying Flutter version to 3.38.5 on Tuesday 3 February 2026. The upgrade announcement promised "updates to dozens of third-party packages used across FlutterFlow" and warned, in the same breath, that "you may need to make changes to custom code or dependencies". Platform upgrades are not neutral events for custom code. They are the day your pinned versions get renegotiated for you.

Where this leaves the widget you wanted to build

Submission day for a batch of templates, with reference docs written and iOS screenshots captured, is the wrong moment to learn that a dependency will not resolve. That is why the check runs first and the design runs second, which feels backwards until the first time it saves you.

There is a related decision underneath all of this, and it deserves its own answer rather than a paragraph here: whether the widget belongs in FlutterFlow at all, or whether this is the point to drop out of FlutterFlow into pure Flutter. If you are earlier than that and still choosing a platform, the honest version of the trade-off is in my notes on which no-code tools hit a ceiling and where, and the assembled version I actually ship paid mobile apps on is FlutterFlow with Firebase and Stripe.

So before your next custom widget: open the pub.dev page for the dependency you have already half-decided on, and check the platform row. Does Web appear? If it does not, you have just saved yourself a week, and you have not written a line of code yet.

Free resource

Free SaaS MVP Scope Template

A Notion document with the full feature checklist, MVP vs. nice-to-have table, pre-build questions, and cost signals — so you walk into any developer call knowing exactly what to ask for.

Get the template →
DL

Dusko Licanin

Full-Stack Developer · Banja Luka, Bosnia

Full-stack developer shipping SaaS MVPs, web apps, and mobile apps using AI-augmented workflows — without agency coordination overhead. Live portfolio: BookBed, Callidus, Pizzeria Bestek.

Frequently Asked Questions

How do I add a pub.dev package to FlutterFlow custom code?

Add it either globally under Settings and Integrations in the Custom Dependencies tab, or locally in the Pubspec Dependency panel beside the custom widget that needs it. Both take a package name and an explicit version string copied from the package's pub.dev page, and both feed the same merged pubspec. The step people miss is transitive dependencies: FlutterFlow's custom code documentation warns that a dependency "might depend on other dependencies to work", so the name and version of those have to be specified too. Add the package first, then run the project once before you write any widget code around it.

Why does my FlutterFlow build fail after adding a package?

Almost always because version solving failed: your package needs a version of something that FlutterFlow's own pubspec, or a transitive dependency, has already fixed at a different number. The error names packages you never added, which is why it reads as nonsense at first. A FlutterFlow issue from September 2026 shows the pattern, with a conflict on the web package that the reporter could not locate in either dependency list because the generated code introduced it. Remove the package you just added and rebuild. If the build goes green, the conflict is between your dependency and something the platform pins, and the fix is a different version or a different package.

Which packages work in a FlutterFlow custom widget?

Pure-Dart packages with declared web support are the reliable category, because they compile into the app with no Gradle or CocoaPods surface for the cloud build to handle. UI-only packages are the sweet spot: charts, editors, viewers, layout helpers. The platform chips on a package's pub.dev listing are the fastest filter, and pub.dev's scoring documentation notes that platform support "will be detected by analyzing the transitive import graph" rather than declared by the author. If Web is absent from that row, FlutterFlow's Run/Test Mode requirement is unmet before you start.

What makes a package unsupported in FlutterFlow?

Two things, mostly: it lacks web support, or it needs native platform code that FlutterFlow gives you no way to edit. On the first, FlutterFlow's package-selection guidance states the requirement as "WEB: It must support Web to run your app in our Run/Test Mode." On the second, the platform's MethodChannels guide confirms it "does not allow direct editing of platform-native code (Kotlin, Swift) through its web UI." A third, quieter case is a package held back by the cloud builder's own pinned versions, where nothing is wrong with the package at all.

Can I use a package that needs native Android or iOS code?

Yes, but not as a pasted dependency. FlutterFlow's documented path is to build the Flutter plugin outside the platform, implement the Kotlin and Swift sides locally, publish it to a Git repository, then add it to a custom action by Git URL rather than by package name. That works, and it is the right call for a vendor SDK with no Dart equivalent. Price it honestly though: you now own a repository that has to keep compiling against whatever Flutter version FlutterFlow is running, and the platform moves that version on its own schedule. For anything with a pure-Dart alternative, take the alternative.