restage.dev · Packages on pub.dev · Quickstart
Server-driven UI for Flutter. Build any surface of your app from the widgets you already write and ship changes over the air, no app-store release: what ships is content, not code. Surfaces render as real Flutter widgets inside your widget tree, and every change is versioned, reversible, and auditable.
Write a screen in ordinary Flutter. A build step compiles it to a small data file (a Remote Flutter Widgets blob) and the SDK renders it, using your live theme.
@ScreenSource(id: 'welcome')
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({super.key});
static const next = SurfaceEvent<void>('next');
@override
Widget build(BuildContext context) => Column(children: [
Text('Welcome', style: Theme.of(context).textTheme.headlineMedium),
FilledButton(onPressed: surfaceEvent(next), child: const Text('Get started')),
]);
}dart run build_runner build turns this into a .rfw blob that renders fully offline. Swap @ScreenSource for @PaywallSource or @FlowSource: every surface runs on the same catalog and runtime.
- Your real Flutter UI, over the air. Use your own widgets and design system; what ships is compiled from that exact code. Not a fixed palette, not a JSON dialect, not a webview.
- Your design system comes with it.
Theme.of(context)resolves live at render time. A delivered surface follows your app into dark mode or a rebrand, with no recompile. - No code over the air. An update changes the screens your app shows. It does not run new code, so an update can't do anything your released app couldn't already do. That keeps updates App Store-safe, and makes OTA UI viable where compliance matters.
- Fails safe, not wrong. The build step stops with an error instead of guessing. A surface can't reach a client too old to render it, and a failed fetch falls back to your bundled copy.
- One runtime, any surface. Paywalls, onboarding, messages, surveys, a single card, or a whole screen: anything you author runs on the same runtime. Drop one into your own
Scaffoldand only that region is server-driven. - No lock-in. A surface is just a
.rfwfile. Serve it from your own backend or CDN. The SDK runs fully offline, no hosted service required.
Ship UI over the air: versioned, reversible, auditable.
- The SDK ships the safety half: immutable surface versions, and clients that fail closed to a safe one.
- The delivery service builds the control on top: roll back, freeze, or kill any version, with an exportable audit trail of what changed, when, and by whom.
It's the change control a regulated or enterprise team needs. The hosted service is coming soon.
Copy a starter. The apps/examples README has four minimal, copy-me surfaces: a paywall, an onboarding flow, a one-screen message, and a custom widget. Retitle it, restyle it, ship it.
Prefer building from scratch? The Quickstart writes one step by step.
- A 115-widget catalog across
restage_core,restage_material, andrestage_cupertino. Extend it with your own widgets via@RestageWidget. - Monetization for commerce surfaces: a pluggable billing gateway, purchase and restore, promotional offers, and an entitlement stream. Receipt validation and revenue attribution run on a backend: yours, or the hosted one when it ships.
- A2UI (early): the same source emits a genui A2UI catalog, so AI-generated UI builds from your real widgets.
dependencies:
restage: ^1.0.0
restage_material: ^1.0.0
dev_dependencies:
restage_codegen: ^1.0.0
build_runner: ">=2.4.0 <3.0.0"The restage CLI is optional: dart pub global activate restage_cli.
Note: when you build a release that ships a Restage surface, pass
--no-tree-shake-icons. The blob builds icons from runtime values, which the release tree-shaker can't see. A debugflutter rundoesn't need it.
| Package | What it is | License |
|---|---|---|
restage |
The Flutter SDK that renders surfaces on device | BSD-3 |
restage_core |
Cross-platform widget catalog | BSD-3 |
restage_material |
Material widget catalog | BSD-3 |
restage_cupertino |
Cupertino widget catalog | BSD-3 |
restage_cli |
The restage command-line tool |
BSD-3 |
restage_mcp |
MCP server for agent and tool access | BSD-3 |
restage_a2ui |
App-side capability check for genui A2UI payloads | BSD-3 |
rfw_catalog_schema |
Catalog format and the @RestageWidget annotations |
BSD-3 |
restage_codegen |
Build-time toolchain that lowers your Flutter into render blobs | FSL-1.1-ALv2 |
rfw_catalog_compiler |
Catalog compiler used by the toolchain | FSL-1.1-ALv2 |
apps/examples |
Example surfaces to copy | BSD-3 |
Open source where it runs in your app. Fair-source where it builds your blobs.
- BSD-3-Clause: the SDK, the catalog libraries, the schema, the CLI, the MCP server, the A2UI check, and the examples. The same license Flutter uses.
- FSL-1.1-ALv2: the build-time toolchain (
restage_codegen,rfw_catalog_compiler). Source-available, free for all use including inside your own company, and it converts to Apache-2.0 two years after each release.
The hosted platform is proprietary. Every package carries its own LICENSE.
See CONTRIBUTING.md. The easiest place to start is the widget catalog: adding a widget is a curation entry plus generated registration.
- Quickstart: build your first surface.
apps/examples: copy a starter.