A comprehensive implementation of Server-Driven UI (SDUI) architecture in React Native that allows dynamic UI rendering from JSON configurations. This project demonstrates how to build flexible, maintainable mobile applications where the UI structure and behavior can be controlled by server-side configurations.
Server-Driven UI is an architectural pattern where the user interface is defined and controlled by the server rather than being hardcoded in the client application. This approach offers several benefits:
- Dynamic Updates: UI can be updated without app store releases
- A/B Testing: Easy to test different UI variations
- Personalization: Customize UI based on user preferences or segments
- Rapid Prototyping: Quick UI changes for experimentation
- Consistent Experience: Same UI logic across different platforms
The project is structured around several key components that work together to provide a complete SDUI solution:
The main screen component that handles:
- Fetching UI configuration from the server
- Managing loading and error states
- Initializing application state
- Executing on-load actions
- Rendering the dynamic UI using JsonRenderer
The core rendering engine that:
- Converts JSON configurations into React Native components
- Handles state interpolation in UI elements
- Manages component event handlers (onPress, etc.)
- Recursively renders nested component structures
A centralized registry that maps component types to actual React Native components:
- Maps JSON component types to React components
- Includes custom components like ControlledTextInput
- Supports both native and custom components
- Enables easy addition of new component types
Handles all user interactions and system actions:
- API_CALL: Makes HTTP requests to backend services
- UPDATE_STATE: Updates application state
- NAVIGATE/PUSH/GO_BACK: Navigation actions
- SHOW_TOAST: Display user notifications
- CHAIN_ACTIONS: Execute multiple actions in sequence
- Supports action chaining and error handling
Global state management using Zustand:
- Manages application-wide state
- Supports nested state updates using dot notation
- Provides reactive state updates
- Handles state initialization from server configurations
Handles communication with backend services:
- Fetches UI configurations for screens
- Makes API calls for user actions
- Simulates backend responses for development
- Manages screen data mapping
Centralized navigation management:
- Provides navigation methods (navigate, push, goBack)
- Handles navigation state
- Integrates with React Navigation
- Supports parameter passing between screens
Utility functions for the SDUI system:
- interpolate: Replaces template variables with actual values
- getValueFromPath: Retrieves nested object values using dot notation
- Supports fallback values and complex data structures
User navigates to screen → SduiScreen loads → Fetches JSON config → Initializes state → Renders UI
JSON config → JsonRenderer → Component Registry → React Native Components → User Interface
User action → Action Handler → State update/API call → UI re-render → Updated interface
| Action | Description | Example Use Case |
|---|---|---|
API_CALL |
Make HTTP requests to backend | User login, data fetching |
UPDATE_STATE |
Update application state | Form data, user preferences |
NAVIGATE |
Navigate to different screens | Screen transitions |
PUSH |
Push new screen onto stack | Modal presentations |
GO_BACK |
Return to previous screen | Back button functionality |
SHOW_TOAST |
Display user notifications | Success/error messages |
CHAIN_ACTIONS |
Execute multiple actions | Complex workflows |
{
"body": {
"type": "View",
"props": {
"style": { "flex": 1, "padding": 20 }
},
"children": [
{
"type": "Text",
"props": {
"children": "Welcome {{state.user.name || 'Guest'}}"
}
},
{
"type": "Button",
"props": {
"title": "Login"
},
"onPress": {
"action": "API_CALL",
"payload": {
"endpoint": "/auth/login",
"onSuccess": {
"action": "NAVIGATE",
"payload": { "screen": "Dashboard" }
}
}
}
}
]
}
}The system supports dynamic content through state interpolation:
{
"type": "Text",
"props": {
"children": "{{state.user.mobileNumber || 'No number provided'}}"
}
}- Node.js (v14 or higher)
- React Native development environment
- iOS Simulator or Android Emulator
# Install dependencies
npm install
# For iOS
cd ios && pod install && cd ..
# Run the application
npx react-native run-ios
# or
npx react-native run-android- Define Screen JSON in
src/sdui/apiClient.ts:
const myScreenJson = {
body: {
type: 'View',
children: [
// Your UI components here
],
},
};- Register Screen in the screenData object:
const screenData = {
Login: loginScreenJson,
Dashboard: dashboardScreenJson,
MyScreen: myScreenJson, // Add your screen here
};- Navigate to Screen:
{
"action": "NAVIGATE",
"payload": {
"screen": "MyScreen"
}
}To add custom components:
- Create Component in
src/components/ - Register Component in
src/sdui/registry/componentRegistry.tsx:
export const componentRegistry = {
View,
Text,
Button,
MyCustomComponent, // Add your component
};- Use in JSON:
{
"type": "MyCustomComponent",
"props": {
"customProp": "value"
}
}- Check console logs for detailed action execution
- Use React Native Debugger for state inspection
- Verify JSON configuration syntax
- Test API endpoints independently
src/
├── components/ # Reusable UI components
├── navigation/ # Navigation configuration
├── screens/ # Screen components
└── sdui/ # SDUI core system
├── actions/ # Action handlers
├── core/ # Core rendering logic
├── registry/ # Component registry
├── state/ # State management
└── utils/ # Utility functions
This implementation provides a solid foundation for building server-driven mobile applications with React Native. The modular architecture makes it easy to extend and customize according to your specific requirements.