Get Started π
Welcome to Stac (formerly Mirai), a Server-Driven UI (SDUI) framework for Flutter. Stac empowers developers to build dynamic, cross-platform applications by utilizing JSON in real time. This innovative approach to UI development allows for flexible, efficient, and seamless updates, minimizing the need for frequent AppStore/PlayStore releases and ensuring your application always looks and feels fresh.
Packagesβ
The Stac ecosystem consists of the following packages:
Package | Description | Link |
---|---|---|
stac | The core package that provides the foundation for building server-driven UIs in Flutter. | |
stac_framework | A framework that extends the functionality of the core package and provides additional features for building server-driven UIs. | |
stac_webview | A package that enables you to embed web views in your server-driven UIs. |
Installationβ
To get started with Stac, follow the installation instructions below:
- Add the Stac dependency to your
pubspec.yaml
file:
Run this command:
flutter pub add stac
This will add stac into your package's pubspec.yaml (and run an implicit flutter pub get):
Alternatively, you can manually add the dependency to your app from within your pubspec.yaml:
dependencies:
stac: ^<latest-version>
Please replace <latest-version>
with the latest version of Stac. You can find the latest version on the Stac pub.dev page.
- Run the following command in your terminal to install the package:
flutter pub get
- Import the Stac package in your Dart file:
import 'package:stac/stac.dart';
Now, you're ready to start using Stac in your Flutter project.
How to use Stac?β
Now that you have successfully installed Stac, let's dive into how you can use it to build dynamic, server-driven UIs in your Flutter project.
1. Import the Stac packageβ
To start using Stac, you need to import the package in your Dart file. Add the following import statement to your main.dart
:
import 'package:stac/stac.dart';
This import allows you to access all the classes and functions provided by Stac.
2. Initialize Stacβ
In the main
function, initialize Stac to set up the necessary configurations and prepare your app for rendering UI from JSON.
Basic Initializationβ
void main() async {
await Stac.initialize();
runApp(const MyApp());
}
3. Use Stac to Render UIβ
You can use Stac.fromJson
to load and render the UI from a JSON object. Hereβs how you can integrate it into your Flutter app:
import 'package:flutter/material.dart';
import 'package:stac/stac.dart';
void main() async {
await Stac.initialize();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'StacDemo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Stac.fromJson(json, context),
);
}
}
Rendering UI from JSON File in Assetsβ
You can also use Stac.fromAssets
to load and render the UI from a JSON file stored in the assets folder:
Widget build(BuildContext context) {
return MaterialApp(
title: 'StacDemo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Stac.fromAsset('assets/ui.json', context),
);
}
Rendering UI from Networkβ
Alternatively, use the Stac.fromNetwork
method to load and render the UI from a JSON file stored on a server:
Widget build(BuildContext context) {
return MaterialApp(
title: 'StacDemo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Stac.fromNetwork(
request: StacNetworkRequest(
url: 'https://example.com/ui.json',
),
context: context,
),
);
}
By following these steps, you can effectively integrate Stac into your Flutter project and start building dynamic, server-driven UIs.
Example: Stac Form Screenβ
Here's an example of how you can use Stac to render a form screen in your Flutter app:
JSON Dataβ
{
"type": "scaffold",
"appBar": {
"type": "appBar",
"title": {
"type": "text",
"data": "Text Field",
"style": {
"color": "#ffffff",
"fontSize": 21
}
},
"backgroundColor": "#4D00E9"
},
"backgroundColor": "#ffffff",
"body": {
"type": "singleChildScrollView",
"child": {
"type": "container",
"padding": {
"left": 12,
"right": 12,
"top": 12,
"bottom": 12
},
"child": {
"type": "column",
"mainAxisAlignment": "center",
"crossAxisAlignment": "center",
"children": [
{
"type": "sizedBox",
"height": 24
},
{
"type": "textField",
"maxLines": 1,
"keyboardType": "text",
"textInputAction": "done",
"textAlign": "start",
"textCapitalization": "none",
"textDirection": "ltr",
"textAlignVertical": "top",
"obscureText": false,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"hintText": "What do people call you?",
"filled": true,
"icon": {
"type": "icon",
"iconType": "cupertino",
"icon": "person_solid",
"size": 24
},
"hintStyle": {
"color": "#797979"
},
"labelText": "Name*",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
},
{
"type": "sizedBox",
"height": 24
},
{
"type": "textField",
"maxLines": 1,
"keyboardType": "text",
"textInputAction": "done",
"textAlign": "start",
"textCapitalization": "none",
"textDirection": "ltr",
"textAlignVertical": "top",
"obscureText": false,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"hintText": "Where can we reach you?",
"filled": true,
"icon": {
"type": "icon",
"iconType": "cupertino",
"icon": "phone_solid",
"size": 24
},
"hintStyle": {
"color": "#797979"
},
"labelText": "Phone number*",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
},
{
"type": "sizedBox",
"height": 24
},
{
"type": "textField",
"maxLines": 1,
"keyboardType": "text",
"textInputAction": "done",
"textAlign": "start",
"textCapitalization": "none",
"textDirection": "ltr",
"textAlignVertical": "top",
"obscureText": false,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"hintText": "Your email address",
"filled": true,
"icon": {
"type": "icon",
"iconType": "material",
"icon": "email",
"size": 24
},
"hintStyle": {
"color": "#797979"
},
"labelText": "Email",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
},
{
"type": "sizedBox",
"height": 24
},
{
"type": "sizedBox",
"height": 100,
"child": {
"type": "textField",
"expands": true,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"filled": true,
"hintStyle": {
"color": "#797979"
},
"labelText": "Life story",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
}
},
{
"type": "sizedBox",
"height": 24
},
{
"type": "textField",
"maxLines": 1,
"keyboardType": "text",
"textInputAction": "done",
"textAlign": "start",
"textCapitalization": "none",
"textDirection": "ltr",
"textAlignVertical": "top",
"obscureText": true,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"filled": true,
"suffixIcon": {
"type": "icon",
"iconType": "cupertino",
"icon": "eye",
"size": 24
},
"hintStyle": {
"color": "#797979"
},
"labelText": "Password*",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
},
{
"type": "sizedBox",
"height": 24
},
{
"type": "textField",
"maxLines": 1,
"keyboardType": "text",
"textInputAction": "done",
"textAlign": "start",
"textCapitalization": "none",
"textDirection": "ltr",
"textAlignVertical": "top",
"obscureText": true,
"cursorColor": "#FC3F1B",
"style": {
"color": "#000000"
},
"decoration": {
"filled": true,
"suffixIcon": {
"type": "icon",
"iconType": "cupertino",
"icon": "eye",
"size": 24
},
"hintStyle": {
"color": "#797979"
},
"labelText": "Re-type password*",
"fillColor": "#F2F2F2"
},
"readOnly": false,
"enabled": true
},
{
"type": "sizedBox",
"height": 48
},
{
"type": "elevatedButton",
"child": {
"type": "text",
"data": "Submit"
},
"style": {
"backgroundColor": "#4D00E9",
"padding": {
"top": 8,
"left": 12,
"right": 12,
"bottom": 8
}
},
"onPressed": {}
}
]
}
}
}
}
Flutter Codeβ
import 'package:flutter/material.dart';
import 'package:stac/stac.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return StacApp(
title: 'Stac Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Stac.fromNetwork(
StacRequest(
url: _url,
method: Method.get,
),
),
);
}
}
That's it with just few lines of code your SDUI app is up and running.
![Form screen example](/img/form_screen_image.png)
For more detailed examples and advanced usage, refer to the Stac Gallery App.