flutter-duit-bdui

madteacher/mad-agents-skills · updated Apr 8, 2026

$npx skills add https://github.com/madteacher/mad-agents-skills --skill flutter-duit-bdui
0 commentsdiscussion
summary

Duit enables backend-driven UI in Flutter applications. The server controls both data and layout via JSON, allowing UI updates without app releases.

skill.md

Fluttter Duit Backend-driven UI

Overview

Duit enables backend-driven UI in Flutter applications. The server controls both data and layout via JSON, allowing UI updates without app releases.

Quick Start

  1. Add dependency to pubspec.yaml
  2. Initialize DuitRegistry (optional: with themes/custom widgets)
  3. Create XDriver (HTTP, WebSocket, or static)
  4. Wrap UI in DuitViewHost
  5. Server sends JSON layouts → Duit renders them

Prerequisites

SDK Requirements

- Dart SDK: >=3.4.4 <4.0.0
- Flutter: >=3.24.0

Add Dependency

flutter pub add flutter_duit

Install:

flutter pub get

Basic Integration

Minimal Setup

import 'package:flutter/material.dart';
import 'package:flutter_duit/flutter_duit.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: DuitViewHost.withDriver(
          driver: XDriver.static({
            "type": "Text",
            "id": "1",
            "attributes": {"data": "Hello, World!"},
          }),
        ),
      ),
    );
  }
}

Driver Lifecycle Management

Always dispose drivers to prevent memory leaks:

class MyWidgetState extends State<MyWidget> {
  late final XDriver driver;

  
  void initState() {
    super.initState();
    driver = XDriver.static(/* ... */);
  }

  
  void dispose() {
    driver.dispose();
    super.dispose();
  }
}

Transport Configuration

HTTP Transport

Fetch layouts from REST API endpoints:

final driver = XDriver(
  transportManager: HttpTransportManager(
    options: HttpTransportOptions(
      baseUrl: 'https://api.example.com/view',
      headers: {
        'Authorization': 'Bearer $token',
        'Content-Type': 'application/json',
      },
    ),
  ),
);

WebSocket Transport

Real-time bidirectional communication:

final driver = XDriver(
  transportManager: WSTransportManager(
    options: WSTransportOptions(
      url: 'wss://api.example.com/ws',
      headers: {
        'Authorization': 'Bearer $token',
      },
      reconnectInterval: Duration(seconds: 5),
      heartbeatInterval: Duration(seconds: 30),
    ),
  ),
);

Static/Stub Transport

For testing or local layouts:

final driver = XDriver.static(
  layoutJson,
);

Custom Decoder/Encoder

import 'dart:convert';
import 'dart:typed_data';

class CustomDecoder extends Converter<Uint8List, Map<String, dynamic>> {
  
  Map<String, dynamic> convert(Uint8List input) {
    // Custom decode logic
    return jsonDecode(utf8.decode(input));
  }
}

final driver = XDriver(
  transportManager: HttpTransportManager(
    options: HttpTransportOptions(
      baseUrl: 'https://api.example.com',
      decoder: CustomDecoder(),
    ),
  ),
);

Custom Transport

Create your own transport implementation if needed:

class MyCustomTransportManager with TransportCapabilityDelegate {
  
  void linkDriver(UIDriver driver) {
    // Implement linkDriver method
  }

  
  Stream<Map<String, dynamic>> connect({
    Map<String, dynamic>? initialRequestData,
    Map<String, dynamic>? staticContent,
  }) async* {
    // Implement connect method
  }

  
  Future<Map<String, dynamic>?> executeRemoteAction(
    ServerAction action,
    Map<String, dynamic> payload,
  ) async {
    //Implement executeRemoteAction method
  }

  
  Future<Map<String, dynamic>?> request(
    String url,
    Map<String, dynamic> meta,
    Map<String, dynamic> body,
  ) async {
    //Implement request method
  }

  
  void releaseResources() {
    // Implement linkDriver method
  }
}

Custom Widgets

Create and register Custom Widget

import 'package:flutter_duit/flutter_duit.dart';

// 1. Define custom widget
class MyCustomWidget extends StatelessWidget {
  final ViewAttribute attributes;

  const MyCustomWidget({
    required this.attributes,
    super.key,
  });

  
  Widget build(BuildContext context) {
    final attrs = attributes.payload;
    return Container(
      child: Text(attrs.getString(key: "message")),
    );
  }
}

// 2. Create build factory fn for widget
Widget myCustomBuildFactory(ElementPropertyView model) {
    if (model.isControlled) {
        return MyCustomWidget(
            attributes: model.attributes,
        );
    } else {
        return const SizedBox.shrink();
    }
}

// 3. Register build-fn
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  DuitRegistry.register(
    "MyCustomWidget",
    buildFactory: myCustomBuildFactory,
  );

  runApp(const MyApp());
}

Components

Components registration

Components allow you to create reusable UI templates that can be referenced by a tag and populated with dynamic data.

import 'package:flutter_duit/flutter_duit.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Define component template
  final cardComponent = {
    "tag": "CardComponent",
    "layoutRoot": {
      "type": "Container",
      "id": "cardContainer",
      "controlled": false,
      "attributes": {
        "padding": {"all": 16},
        "margin": {"all": 8},
        "decoration": {
          "borderRadius": 12,
          "color": "#FFFFFF",
          "boxShadow": [
            {
              "color": "#00000033",
              "blurRadius": 6,
              "offset": {"dx": 0, "dy": 2},
            },
          ],
        },
      },
      "children": [
        {
          "type": "Text",
          "id": "cardTitle",
          "controlled": false,
          "attributes": {
            "data": {
              "style": {
                "fontSize": 18,
                "fontWeight": "w600",
                "color": "#333333",
              },
            },
            "refs": [
              {
                "objectKey": "title",
                "attributeKey": "data",
              },
            ],
          },
        },
        {
          "type": "Text",
          "id": "cardDescription",
          "controlled": false,
          "attributes": {
            "data": {
              "style": {
                "fontSize": 14,
                "color": "#666666",
              },
            },
            "refs": [
              {
                "objectKey": "description",
                "attributeKey": "data",
              },
            ],
          },
        },
      ],
    },
  };

  // Register the component
  await DuitRegistry.registerComponents([cardComponent]);

  runApp(const MyApp());
}

// Usage in JSON layout from server:
// {
//   "type": "Component",
//   "id": "card1",
//   "tag": "CardComponent",
//   "data": {
//     "title": "Hello World",
//     "description": "This is a card component"
//   }
// }

Key concepts:

  • tag: Unique identifier for the component
  • layoutRoot: Root element of the component template
  • refs: References to dynamic data passed via the data field
  • objectKey: Key in the data object
  • attributeKey: Attribute in the widget to bind to
  • defaultValue: Optional default value if data key is missing

You can register multiple components at once:

await DuitRegistry.registerComponents([
  cardComponent,
  buttonComponent,
  listItemComponent,
]);

When to Use This Skill

Use this skill when:

  • Integration flutter_duit library into project
  • Custom widet creation
  • Components registration
  • Basic framework behavior overriding via capabilities implementation
  • Need help with the framework API

Resources

Reference Documentation

Discussion

Product Hunt–style comments (not star reviews)
  • No comments yet — start the thread.
general reviews

Ratings

4.538 reviews
  • Ira Yang· Dec 28, 2024

    Solid pick for teams standardizing on skills: flutter-duit-bdui is focused, and the summary matches what you get after install.

  • Ama Chen· Dec 8, 2024

    Useful defaults in flutter-duit-bdui — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • James Khan· Nov 19, 2024

    flutter-duit-bdui has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Li Sharma· Oct 10, 2024

    flutter-duit-bdui fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.

  • Yash Thakker· Sep 25, 2024

    Keeps context tight: flutter-duit-bdui is the kind of skill you can hand to a new teammate without a long onboarding doc.

  • Alexander Nasser· Sep 17, 2024

    flutter-duit-bdui reduced setup friction for our internal harness; good balance of opinion and flexibility.

  • Ira Gonzalez· Sep 1, 2024

    flutter-duit-bdui is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

  • Ishan Ghosh· Aug 20, 2024

    flutter-duit-bdui reduced setup friction for our internal harness; good balance of opinion and flexibility.

  • Dhruvi Jain· Aug 16, 2024

    We added flutter-duit-bdui from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.

  • Noor Brown· Aug 8, 2024

    flutter-duit-bdui is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

showing 1-10 of 38

1 / 4