A powerful Flutter package for rendering UI dynamically from JSON responses. Build forms, screens, and components from server-driven JSON โ without requiring app updates.
Perfect for: Server-Driven UI (SDUI), Dynamic Forms, A/B Testing, CMS-driven UIs, and White-Label Apps
- โ Print - Debug logging with levels (info/warning/error)
- โ Dialog - Alert dialogs with custom titles and messages
- โ Snackbar - Toast notifications with action buttons
- โ
URL Launch - Open web links in browser (uses
url_launcher) - โ Bottom Sheet - Modal bottom sheets
- โ Navigation - Screen navigation with push/pop strategies
- โ Text - Full styling (size, weight, color, alignment)
- โ Container - Padding, margin, color, dimensions, border radius
- โ Button - Styled buttons with actions
- โ Column - Vertical layouts with alignment
- โ Row - Horizontal layouts with alignment
- โ Type-safe JSON parsing - No runtime surprises
- โ Error handling - Graceful fallbacks with user-friendly messages
- โ Context propagation - Automatic for navigation and dialogs
- โ Extensible architecture - Easy to add custom widgets
- โ Well tested - 90%+ code coverage
- โ Lightweight - Minimal dependencies
Add the dependency to your pubspec.yaml:
dependencies:
dynamic_ui_renderer: ^0.1.0Then run:
flutter pub getNote: The package automatically includes
url_launcherfor web URL support. No additional setup needed!
import 'package:flutter/material.dart';
import 'package:dynamic_ui_renderer/dynamic_ui_renderer.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Dynamic UI Demo')),
body: DynamicUIRenderer.fromJsonString('''
{
"type": "column",
"properties": {
"mainAxisAlignment": "center",
"crossAxisAlignment": "center",
"padding": 16
},
"children": [
{
"type": "text",
"properties": {
"text": "Hello from JSON! ๐",
"fontSize": 24,
"fontWeight": "bold",
"color": "#2196F3",
"textAlign": "center"
}
},
{
"type": "container",
"properties": {
"margin": [0, 20, 0, 0],
"padding": 16,
"color": "#E3F2FD",
"borderRadius": 8
},
"children": [
{
"type": "text",
"properties": {
"text": "This entire UI is rendered from JSON!",
"color": "#1565C0"
}
}
]
},
{
"type": "button",
"properties": {
"text": "Click Me",
"backgroundColor": "#4CAF50",
"foregroundColor": "#FFFFFF",
"borderRadius": 8,
"margin": [0, 20, 0, 0]
},
"actions": {
"type": "showDialog",
"parameters": {
"title": "Welcome! ๐",
"message": "Button clicked successfully!",
"buttonText": "OK"
}
}
}
]
}
''', context),
),
);
}
}{
"type": "text",
"properties": {
"text": "Your text here", // Required
"fontSize": 16, // Optional
"fontWeight": "bold", // Optional: bold, normal, w100-w900
"color": "#FF0000", // Optional: hex color (#RGB or #RRGGBB)
"textAlign": "center" // Optional: left, center, right
}
}{
"type": "container",
"properties": {
"padding": 16, // Optional: number or [L,T,R,B]
"margin": [8, 16, 8, 16], // Optional: number or [L,T,R,B]
"color": "#F5F5F5", // Optional: hex color
"width": 200, // Optional: number
"height": 100, // Optional: number
"borderRadius": 8 // Optional: number
},
"children": [] // Optional: child components
}Padding/Margin Examples:
- Single value:
"padding": 16โ applies to all sides - List:
"padding": [8, 16, 8, 16]โ [left, top, right, bottom]
{
"type": "button",
"properties": {
"text": "Click Me", // Optional (use if no children)
"backgroundColor": "#4CAF50", // Optional: hex color
"foregroundColor": "#FFFFFF", // Optional: text/icon color
"borderRadius": 8, // Optional: number
"elevation": 4, // Optional: number
"padding": [8, 16, 8, 16] // Optional: number or list
},
"children": [ // Optional: custom button content
{
"type": "text",
"properties": {
"text": "Click Me",
"color": "#FFFFFF"
}
}
],
"actions": { // Required for interactivity
"type": "navigate", // Action type
"parameters": { // Action-specific parameters
"route": "/details",
"type": "push",
"arguments": {
"id": 123,
"name": "Product"
}
}
}
}| Type | Description | Required Parameters | Example |
|---|---|---|---|
print |
Print to console | message, level (info/warning/error) |
{"message": "Hello", "level": "info"} |
showDialog |
Show alert dialog | title, message, buttonText |
{"title": "Alert", "message": "Hello"} |
showSnackbar |
Show snackbar | message, duration, actionLabel |
{"message": "Saved!", "duration": 3} |
launchUrl |
Open URL in browser | url, mode (inApp/external) |
{"url": "https://flutter.dev"} |
showBottomSheet |
Show modal bottom sheet | title, message, buttonText |
{"title": "Options", "message": "Choose"} |
navigate |
Navigate to route | route, type (push/pushReplacement/pop) |
{"route": "/home", "type": "push"} |
{
"type": "column", // or "row"
"properties": {
"mainAxisAlignment": "center", // Optional: alignment along main axis
"crossAxisAlignment": "stretch", // Optional: alignment along cross axis
"padding": 16, // Optional: padding around the whole column/row
"margin": [8, 16, 8, 16] // Optional: margin around the whole column/row
},
"children": [] // Required: list of child components
}MainAxisAlignment Options:
start- Children at the startcenter- Children centeredend- Children at the endspaceBetween- Space evenly between childrenspaceAround- Space evenly around childrenspaceEvenly- Space evenly including ends
CrossAxisAlignment Options:
start- Children at the startcenter- Children centeredend- Children at the endstretch- Children stretch to fill
String loginFormJson = '''
{
"type": "column",
"properties": {
"crossAxisAlignment": "stretch",
"padding": 20
},
"children": [
{
"type": "text",
"properties": {
"text": "Welcome Back! ๐",
"fontSize": 28,
"fontWeight": "bold",
"color": "#1976D2",
"textAlign": "center"
}
},
{
"type": "container",
"properties": {
"padding": 20,
"margin": [0, 20, 0, 0],
"color": "#FFFFFF",
"borderRadius": 12
},
"children": [
{
"type": "column",
"properties": {
"crossAxisAlignment": "stretch"
},
"children": [
{
"type": "text",
"properties": {
"text": "Email",
"fontSize": 14,
"fontWeight": "bold",
"color": "#757575"
}
},
{
"type": "container",
"properties": {
"padding": 16,
"margin": [0, 4, 0, 16],
"color": "#F5F5F5",
"borderRadius": 8
},
"children": [
{
"type": "text",
"properties": {
"text": "user@example.com",
"color": "#212121"
}
}
]
},
{
"type": "text",
"properties": {
"text": "Password",
"fontSize": 14,
"fontWeight": "bold",
"color": "#757575"
}
},
{
"type": "container",
"properties": {
"padding": 16,
"margin": [0, 4, 0, 0],
"color": "#F5F5F5",
"borderRadius": 8
},
"children": [
{
"type": "text",
"properties": {
"text": "โขโขโขโขโขโขโขโข",
"color": "#212121"
}
}
]
}
]
}
]
},
{
"type": "button",
"properties": {
"text": "Login",
"backgroundColor": "#1976D2",
"foregroundColor": "#FFFFFF",
"borderRadius": 8,
"margin": [0, 20, 0, 0],
"padding": 16
},
"actions": {
"type": "showDialog",
"parameters": {
"title": "Success! ๐",
"message": "Logged in successfully",
"buttonText": "Continue"
}
}
}
]
}
''';
Widget loginForm = DynamicUIRenderer.fromJsonString(loginFormJson, context);import 'package:http/http.dart' as http;
Future<Widget> fetchUIFromServer(BuildContext context) async {
try {
final response = await http.get(
Uri.parse('https://api.example.com/ui/home')
);
if (response.statusCode == 200) {
return DynamicUIRenderer.fromJsonString(response.body, context);
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error_outline, color: Colors.red, size: 48),
const SizedBox(height: 16),
Text('Failed to load UI: ${response.statusCode}'),
],
),
);
} catch (e) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.wifi_off, color: Colors.orange, size: 48),
const SizedBox(height: 16),
Text('Network error: $e'),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () {
// Retry logic
},
child: const Text('Retry'),
),
],
),
);
}
}Check out the /example folder for a complete Flutter app demonstrating all features:
cd example
flutter runThe example app includes:
- ๐ฏ Button Actions Demo - Test all 6 action types
- ๐ฑ Core Widgets Demo - Basic widgets showcase
- ๐จ Styling Properties Demo - Colors, fonts, padding, margins
- ๐ Layout Examples Demo - Different alignments and arrangements
โ ๏ธ Error Handling Demo - Graceful fallbacks for unsupported widgets
JSON โ UIComponent (Model) โ WidgetFactory โ Flutter Widget
โ
Properties Parser
โ
Action Handler (Navigation, Dialogs, etc.)
The package follows a clean, modular architecture:
- JSON Parsing - Converts JSON to type-safe models
- Widget Factory - Maps component types to Flutter widgets
- Property Parsers - Safely converts JSON values to Flutter types
- Action Handler - Executes user interactions
- Context Propagation - Automatically passes BuildContext for navigation
# Run all tests
flutter test
# Run with coverage
flutter test --coverage
# Generate coverage report (requires lcov)
genhtml coverage/lcov.info -o coverage/html
# Then open coverage/html/index.htmlContributions are welcome! Whether it's:
- ๐ Reporting bugs
- ๐ก Suggesting features
- ๐ Improving documentation
- ๐ง Submitting pull requests
Steps to contribute:
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m "Add some amazing feature" - Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Please ensure your code:
- Passes all tests (
flutter test) - Follows Dart style guidelines (
dart format .) - Includes tests for new features
- Updates documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by server-driven UI patterns at Airbnb, Lyft, and Prowork
- Built with โค๏ธ for the Flutter community
- Thanks to all contributors and users
| Metric | Value |
|---|---|
| Latest Version | v0.1.0 |
| Published | February 2026 |
| License | MIT |
| Platforms | Android, iOS, Web, macOS, Linux, Windows |
| Dependencies | url_launcher (automatically included) |
- ๐ง Email: webdevjash6@gmail.com
- ๐ Issues: GitHub Issues
- โญ Star: GitHub Repository
- โ Forms & Validation - Form widgets with built-in validation
- โ Network Fetching - Load UI directly from URLs
- โ Caching - Cache UI definitions locally
- โ Custom Widget Registry - Register your own widgets
- โ Theme Support - Dynamic theming from JSON
Made with โค๏ธ by Jashwanth Gowda R
If you find this package useful, please consider:
- โญ Starring the GitHub repository
- ๐ข Sharing it with others
- ๐ Reporting issues
- ๐ก Suggesting features