π flutter_smart_forms
flutter_smart_forms is a powerful, reactive, and dynamic JSON-driven form builder for Flutter.
It allows developers to create complex forms in minutes with built-in validation, conditional fields, async validation, file uploads, dynamic arrays, barcode scanning, signature capture, and more.
Perfect for:
- Admin dashboards
- CMS-driven forms
- Enterprise applications
- Survey apps
- Workflow systems
- Dynamic configuration based forms
πΈ Demo
Validation Demo

JSON Dynamic Form

Complex JSON Form Layout

File & Image Upload

Dropdown Field Example

Stepper Form Example

β¨ Features
- β JSON-driven forms
- β Widget-driven forms
- β Reactive field updates
- β Real-time value tracking
- β Synchronous validation
- β Async validation
- β Conditional field visibility
- β Enable / disable fields dynamically
- β Readonly fields
- β
showClearIconinput fields - β Stepper form
- β Date / Time / DateTime picker support
- β Icon support
- β Nested array support
- β File / Image upload support
- β Signature pad
- β Barcode scanner
- β Fully customizable UI
- β Simple developer API
- β Extendable architecture
π± Supported Platforms
- β Android
- β iOS
- β Web
- β Windows
- β macOS
- β Linux
Why flutter_smart_forms?
flutter_smart_forms simplifies building complex dynamic forms in Flutter.
Forms can be defined using:
- JSON configuration
- FieldModel objects
- Native Flutter widgets
This makes it ideal for:
β’ Admin dashboards β’ CMS driven apps β’ Enterprise applications β’ Dynamic form APIs
π Comparison
| Feature | flutter_smart_forms | flutter_form_builder | reactive_forms |
|---|---|---|---|
| JSON Forms | β | β | β |
| Conditional Fields | β | β οΈ | β οΈ |
| Async Validation | β | β οΈ | β οΈ |
| Dynamic Arrays | β | β οΈ | β οΈ |
| Barcode Scanner | β | β | β |
| Signature Field | β | β | β |
| File Upload | β | β οΈ | β |
π Architecture
flutter_smart_forms uses a modular architecture.
JSON Schema
β
βΌ
FieldModel Parser
β
βΌ
FormRegistry
β
βΌ
SmartFormController
β
βΌ
Reactive Field Widgets
β
βΌ
Validation Engine
β
βΌ
Submit Result
β‘ JSON-Driven Dynamic Forms
Create entire forms using JSON configuration.
SmartForm(
controller: controller,
json: jsonForm,
onSubmit: (values) {
print(values);
},
)
π§ Reactive Form Controller
SmartFormController manages:
- Field values
- Validation
- Visibility
- Dependencies
- Async validation
- Form reset
- Value listeners
- Conditional fields
π§© Built-in Field Types
| Field | Description |
|---|---|
| text | Basic text input |
| Email input | |
| password | Secure password field |
| phone | Phone number input |
| textarea | Multi-line input |
| number | Numeric input |
| dropdown | Single select dropdown |
| multiSelect | Multi select dropdown |
| suggestion | Auto-complete field |
| checkbox | Boolean checkbox |
| radio | Radio options |
| date | Date picker |
| time | Time picker |
| barcode | Barcode scanner |
| otp | OTP verification |
| signature | Signature capture |
| file | File upload |
| image | Image upload |
| array | Dynamic repeatable forms |
π Installation
Add dependency in pubspec.yaml
dependencies:
flutter_smart_forms: ^1.0.2
Install via CLI
flutter pub add flutter_smart_forms
Then run
flutter pub get
π Getting Started
Import the package:
import 'package:flutter_smart_forms/flutter_smart_forms.dart';
Quick Example
SmartForm(
controller: SmartFormController(),
json: [
{
"type": "text",
"key": "name",
"label": "Name",
"validators": "required"
}
],
onSubmit: (values) {
print(values);
},
)
π Basic Usage
1οΈβ£ Create Controller
final controller = SmartFormController();
2οΈβ£ Build Form
SmartForm(
controller: controller,
json: jsonForm,
submitText: "Submit",
onSubmit: (values) async {
print(values);
},
)
1οΈβ£ Create Controller With Draft Key
final controller = SmartFormController(
draftKey: "profile_form_draft",
autoSaveDraft: true,
);
2οΈβ£ Restore Draft When Screen Opens
@override
void initState() {
super.initState();
controller.restoreDraft();
}
Now if user previously filled the form, values will auto populate.
3οΈβ£ Save Draft Manually
If autoSaveDraft = false, save manually.
ElevatedButton(
onPressed: () async {
await controller.saveDraft();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Draft saved")),
);
},
child: const Text("Save Draft"),
)
4οΈβ£ Auto Save Draft (Recommended)
SmartFormController(
draftKey: "profile_form_draft",
autoSaveDraft: true,
);
5οΈβ£ Clear Draft
await controller.clearDraft();
6οΈβ£ How to Access Draft
final draft = await controller.getDraft();
if (draft != null) {
print(draft);
}
7οΈβ£ If has Draft
if (await controller.hasDraft()) {
print("Draft exists");
}
| Method | Purpose |
|---|---|
saveDraft() |
Save current form values |
restoreDraft() |
Load draft into form |
clearDraft() |
Delete stored draft |
getDraft() |
Read draft without restoring |
hasDraft() |
Check if exists |
π JSON Form Example
[
{
"type": "text",
"key": "firstName",
"label": "First Name",
"validators": "required|min:2"
},
{
"type": "email",
"key": "email",
"label": "Email",
"validators": "required|email"
},
{
"type": "password",
"key": "password",
"label": "Password",
"validators": "required|min:6"
},
{
"type": "password",
"key": "confirmPassword",
"label": "Confirm Password",
"validators": "required|match:password"
}
]
π Remote API Dropdown
flutter_smart_forms supports dynamic dropdown data loaded from API.
{
"type": "dropdown",
"key": "country",
"label": "Select Country",
"extra": {
"api": "https://api.restful-api.dev/objects",
"method": "GET",
"valueKey": "id",
"labelKey": "name",
"cache": true,
}
},
{
"type": "dropdown",
"key": "devices",
"label": "Devices",
"extra": {
"multiSelect": true,
"api": "https://api.restful-api.dev/objects",
"labelKey": "name",
"valueKey": "id",
"cache": true,
'selectedChipTextColor': '0xFFFFFFFF',
}
},
Flutter Smart Form Stepper Example
This example demonstrates how to use the SmartFormStepper widget with section titles displayed correctly.
JSON Sections Example
final jsonSections = [
{
"title": "Personal",
"fields": [
{
"type": "text",
"key": "firstName",
"label": "First Name",
"placeholder": "Enter first name",
"default": "Johna",
"validators": "required|min:2",
"extra": {
"fillColor": "0xFFFFFFFF",
"borderColor": "#1976D2",
"borderRadius": 12,
"padding": {"left": 16, "top": 12, "right": 16, "bottom": 12},
"textColor": "#000000",
}
},
{
"type": "text",
"key": "lastName",
"label": "Last Name",
"placeholder": "Enter last name",
"validators": "required",
"extra": {
"fillColor": "0xFFFFFFFF",
"borderColor": "#1976D2",
"borderRadius": 12,
"padding": {"left": 16, "top": 12, "right": 16, "bottom": 12},
}
}
]
},
{
"title": "Scan & Date",
"fields": [
{
"type": "barcode",
"key": "barcode",
"label": "Scan Product",
"placeholder": "Scan or enter barcode",
"validators": "required",
"extra": {
"scannerTitle": "Barcode Scan",
"scannerAppBarColor": "#1976D2",
"showClearIcon": true,
"clearIcon": "close",
"fillColor": "0xFFFFFFFF",
"borderColor": "#1976D2",
"borderRadius": 12,
"padding": {"left": 16, "top": 12, "right": 16, "bottom": 12},
}
},
{
"type": "date",
"key": "birthday",
"label": "Select Birthday",
"extra": {
"placeholder": "Pick a date",
"format": "dd/MM/yyyy",
"fillColor": "0xFFFFFFFF",
"borderRadius": 10,
"padding": {"left": 12, "top": 10, "right": 12, "bottom": 10},
}
}
]
}
];
Widget buildStepperForm() {
final convertedSections = JsonFormBuilder.fromJsonSections(jsonSections);
return SmartFormStepper(
controller: controller,
field: FieldModel(type: "stepper", key: "mainStepper", extra: {}, label: ''),
sections: convertedSections,
onSubmit: (data) {
print(data);
},
);
}
π§ Access Form Values
final values = controller.values;
print(values["email"]);
π Validate Form
bool valid = await controller.validate();
Get value
controller.getValue("email");
π Update Field Value
controller.setValue("firstName", "John");
π Reset Form
controller.reset();
π Export Analytics
final analytics = controller.analytics.export();
print(analytics);
π Listen to Form Changes
controller.changes.listen((values) {
print(values);
});
π Conditional Fields
Fields can react to other fields.
Example JSON:
{
"type": "text",
"key": "lastName",
"label": "Last Name",
"visibleIf": {
"firstName": "John"
}
}
π§ͺ Async Validation
Register async validator:
AsyncValidationEngine.register(
"emailAvailable",
(value) async {
await Future.delayed(Duration(milliseconds: 500));
if (value == "test@test.com") {
return "Email already registered";
}
return null;
},
);
Use in JSON:
validators: "required|email|async:emailAvailable"
π§© Custom Field Support
Register custom field widget.
FormRegistry.register(
"colorPicker",
(field, controller) => ColorPickerField(
field: field,
controller: controller,
),
);
JSON usage:
{
"type": "colorPicker",
"key": "favoriteColor"
}
πΌ File & Image Upload
Features:
- Multiple file upload
- Image preview
- File validation
- Image compression
- Cropping
- File size limit
- Allowed extensions
β Signature Field
Capture user signature.
Features:
- Draw signature
- Undo / clear
- Preview
- Save as image
- Fullscreen canvas
π· Barcode Scanner
Scan barcodes using device camera.
Features:
- Multi scan support
- Duplicate prevention
- Scan delay
- Pattern validation
π’ OTP Input
Highly customizable OTP input field.
Options:
- Length
- Box size
- Spacing
- Auto focus
- Obscure input
- Success animation
βοΈ Conditional Logic
Fields can depend on other fields.
Example:
{
"type": "dropdown",
"key": "state",
"watchFields": ["country"],
"visibleIf": { "country": "US" }
}
π¨ Styling Fields
Customize styles via JSON.
{
"type": "text",
"key": "name",
"extra": {
"fillColor": "#FFFFFF",
"borderColor": "#1976D2",
"borderRadius": 12
}
}
π¦ Built-in Validators
| Validator | Description |
|---|---|
| required | Required field |
| Email validation | |
| phone | Phone number validation |
| min | Minimum length |
| max | Maximum length |
| number | Only numbers |
| integer | Integer values |
| decimal | Decimal values |
| url | URL validation |
| regex | Regex validation |
| password | Strong password |
| date | Date validation |
| json | JSON validation |
| alpha | Letters only |
| alphaNumeric | Letters + numbers |
Dependent Validators
| Rule | Example | Meaning |
|---|---|---|
same |
same:password |
Must be equal |
different |
different:username |
Must NOT be equal |
in |
in:admin,user,manager |
Value must be in list |
not_in |
not_in:test,guest |
Value must NOT be in list |
confirmed |
confirmed |
Must match field_confirmation |
accepted |
accepted |
Must be true/yes/1 |
π Cross Field Validators
| Validator | Description |
|---|---|
| match | Must match another field |
| same | Same as another field |
| different | Must be different |
| confirmed | Confirmation field |
Smart Error Messages
{
"type": "text",
"key": "username",
"label": "Username",
"validators": "required|min:3|max:10",
"messages": {
"required": "Username is required",
"min": "Username must be at least :min characters",
"max": "Username cannot exceed :max characters"
}
}
π§ͺ Example Project
Example app included.
example/lib/main.dart
Run example:
flutter run
π£ Roadmap
Upcoming features:
- Multi-step forms
- Form wizard
- Remote dropdown APIs
- JSON schema support
- Form persistence
- Visual form builder
- Analytics support
π€ Contributing
Contributions are welcome.
Steps:
- Fork repository
- Create branch
- Commit changes
- Submit pull request
π License
MIT License
β€οΈ Support
If you like this package:
β Star the repository
π Report issues
π‘ Suggest improvements
Maintainers
Raju
Flutter Developer
π Keywords
Flutter dynamic form
Flutter JSON form builder
Flutter dynamic forms
Flutter form generator
Flutter reactive forms
Flutter low code forms
Flutter survey forms
Flutter conditional forms
Flutter async validation forms