flutter_rust_bridge: generating Dart bindings for Rust without hand-written FFI
Flutter/Dart <-> Rust binding generator, feature-rich, but seamless and simple.
At a glance
- What is it?
- flutter_rust_bridge v2 generates the glue between Dart and Rust so that ordinary Rust functions can be called from Flutter. Here is what the generator actually does, how to run it, and where it stops being the right tool.
- Who is it for?
- Adopt flutter_rust_bridge when you already have Rust code you want to call from a Flutter app and you do not want to hand-write a C ABI, method channels and a serialization layer yourself. Do not adopt it if your Rust has to be replaced by a plain Dart package, if you need a stable non-beta release line right now, or if you are not prepared to commit a build step to your pipeline.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem flutter_rust_bridge removes: hand-written FFI glue
Calling Rust from Dart is possible without this project. Dart FFI plus a C ABI plus a codec plus a way to move errors and streams across the boundary is the manual route, and it is a lot of code that has nothing to do with your product. flutter_rust_bridge is a binding generator aimed at that layer. The README frames the pitch as writing normal Rust and calling it from Flutter as if it were normal Flutter code, with the bridge generating the glue in between.
The audience is Flutter teams that already have, or specifically want, Rust for a piece of the app: a parser, a codec, a computation that is too slow in Dart, or an existing Rust crate they do not want to reimplement. It is not a general interop layer for arbitrary languages, and it is not a way to avoid learning Rust. The Rust you write is the Rust that runs; the generator only removes the plumbing.
How codegen turns Rust signatures into Dart: folders in, bindings out
The mechanism is a code generator, not a runtime shim you configure by hand. You point it at Rust source, it parses the public API, and it writes the Dart side plus the Rust-side glue. The v2 notes list a change that matters for real projects: whole folders can be used as input, where the earlier line accepted a single file such as api.rs. That is the difference between a demo and a codebase.
The type story is where most of the work sits. The README claims arbitrary Rust and Dart types can cross the boundary without manual intervention, including types that are not serializable or not clone. It also lists auto-translatable cases: complex enums and structs, zero-copy big arrays, errors carried as Result, and Streams mapped to Dart streams. Async works in both directions, and Rust can call Dart, not only the reverse.
The repository layout shows the split. frb_codegen holds the generator, frb_rust the runtime crate, frb_macros the procedural macros, frb_dart the Dart package, and frb_example a set of sample projects. The Cargo workspace deliberately excludes every example package, with a comment explaining that this keeps the examples behaving like a typical user's project rather than inheriting workspace behaviour. That is a small detail with a real consequence: the examples are meant to be copied, not consumed as workspace members.
Installing flutter_rust_bridge_codegen and creating a first app
The README gives a one-liner that installs the generator, scaffolds a project and runs it. The command chain is quoted directly from the quickstart: it installs flutter_rust_bridge_codegen from crates.io, creates a project named my_app, enters it and starts Flutter.
cargo install flutter_rust_bridge_codegen && flutter_rust_bridge_codegen create my_app && cd my_app && flutter runWhat you should see is a working Flutter app that already calls into Rust. The starter is described as including small things such as logging and backtraces, so the first run is not a blank scaffold.
The README then gives an optional second step: edit rust/src/api/simple.rs, for example renaming Hello to Hi, and regenerate. The regeneration command is separate from create, which is the important part to internalise.
flutter_rust_bridge_codegen generate && flutter runAfter that you should see the changed output in the running app. The pattern to remember is that create is a one-time scaffold and generate is the command you will run repeatedly, every time the Rust API changes. The README points to a longer quickstart page at fzyzcjy.github.io/flutter_rust_bridge/quickstart for the elaborated version, and the homepage is the place to look for anything the README does not cover.
For an existing project rather than a new one, the README advertises a one-liner integration path, but the truncated text does not spell out the exact command, so check the site before assuming it matches the create flow.
Where flutter_rust_bridge is the wrong tool
The release line is the first thing to weigh. The most recent releases listed are v2.14.0-beta.2 and v2.14.0-beta.1, with v2.13.0 as the last non-beta. A pre-release at the top of the list is normal for a project moving this fast, but it means the newest features may not be what you want in a shipping app.
The second limitation is the generator step itself. A build that depends on generated code has a build that can fail for reasons unrelated to your logic: a Rust signature the parser does not handle, a type that needs a manual serializer, or a regeneration you forgot to run. The README lists user-defined serializers as a feature, which is useful, and also an admission that not every type crosses the boundary untouched. The same applies to the experimental items: parsing third-party Rust packages and lifetime support are both marked experimental in the v2 notes.
The third case is a mismatch of goals. If the Rust side is small and stable, a hand-written FFI layer may be less machinery than a code generator plus a pinned version plus a regeneration step in CI. If your team has no Rust experience, this project does not remove that requirement; it removes the binding work, not the language. And if you only need a native library that already ships a Dart package, adding a Rust build to your pipeline is a cost with no matching benefit.
flutter_rust_bridge compared with writing the FFI layer yourself
The real alternative is not another binding generator so much as doing it manually: declare extern "C" functions on the Rust side, load the dynamic library with Dart FFI, define the structs and pointers, and write the serialization, error mapping and stream handling yourself. That approach has no code generation step and no version coupling to a generator, which some teams prefer precisely because the boundary is visible in their own source.
The difference in approach is where the complexity lives. Manual FFI puts it in your repository, permanently, and it grows with every type you add. flutter_rust_bridge puts it in the generator and in a regeneration command, which is cheaper per type but adds a tool to your build. The README's own framing supports that reading: the value proposition is that you write normal Rust and the bridge generates the glue, not that you avoid thinking about the boundary. For a two-function boundary, manual FFI is defensible. For a Rust crate with structs, enums, errors and streams, the generator is doing work you would otherwise repeat by hand.
Maintenance, versions and the MIT licence
The repository is not archived and the last push was on 2026-09-13, so the project is being worked on. The release cadence shown is fast, with beta releases roughly a week apart. Fast cadence cuts both ways: fixes arrive quickly, and the surface you depend on moves.
Version pinning is visible in the manifest. The workspace uses exact versions for its own crates, for example flutter_rust_bridge_macros and flutter_rust_bridge both pinned with an equals sign to 2.14.0-beta.2. If you follow that convention, an upgrade is a deliberate edit rather than something a resolver does for you. The flip side is that you own the upgrade: read the changelog, which exists as CHANGELOG.md in the repository, and check the what's-new page the README links for the v1 to v2 update guide before moving a major line.
The licence is MIT, stated in the workspace manifest and present as a LICENSE file at the repository root. MIT is permissive, so it generally allows commercial and closed-source use with attribution and the licence text retained, but the file itself is the authority and this is not legal advice. The generator being MIT does not automatically settle the licence of the Rust crates you bring in; those are separate.
Editorial conclusion
Adopt flutter_rust_bridge when you already have Rust code you want to call from a Flutter app and you do not want to hand-write a C ABI, method channels and a serialization layer yourself. Do not adopt it if your Rust has to be replaced by a plain Dart package, if you need a stable non-beta release line right now, or if you are not prepared to commit a build step to your pipeline. Before writing application code, verify three things on your own machine: that flutter_rust_bridge_codegen generate runs cleanly in your existing project, that the platforms you ship to are covered by the current v2 documentation, and that the exact version you pin is one you are willing to keep pinned, because the npm-style version string in the workspace manifest is an exact match, not a range.
Frequently asked questions
How do I use flutter_rust_bridge in a new project?
Install the generator and scaffold with the quickstart one-liner: cargo install flutter_rust_bridge_codegen, then flutter_rust_bridge_codegen create my_app, then cd my_app and flutter run. After editing Rust under rust/src/api, run flutter_rust_bridge_codegen generate and run the app again.
Is flutter_rust_bridge the same thing as ring?
No. flutter_rust_bridge is a binding generator that produces the glue between Dart and Rust so Flutter apps can call Rust functions. The README does not mention ring at all, and nothing in the repository describes a cryptographic library.
What does flutter_rust_bridge_codegen actually do?
It parses Rust source and generates the Dart bindings plus the Rust-side glue, so you write normal Rust and call it from Flutter. In v2 it can take whole folders as input rather than a single file, and the create subcommand scaffolds a working project in one command.
Can Rust call back into Dart with flutter_rust_bridge?
Yes. The v2 notes list Rust calling Dart functions as a change from the earlier version, which only allowed Dart to call Rust. Async Rust functions are supported as well.
Does flutter_rust_bridge support streams and async?
The README lists Streams as an auto-translatable type mapped to Dart streams, along with errors carried as Result. It also describes async and sync modes on both the Dart and Rust sides, including async Rust for IO-bound work and thread pools for CPU-heavy computation.
What platforms does flutter_rust_bridge target?
The README states support for Android, iOS, Windows, Linux, macOS and Web, with Web covering both JavaScript and WebAssembly. The documentation does not describe per-platform differences in the truncated material, so check the project site for platform-specific setup.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fzyzcjy-flutter-rust-bridge)