Simple Yet Powerful Form State Management (formini)

Simple yet powerful form state management


Working with forms shouldn’t be so hard in Flutter.

Please note that the schemani/formini packages are under development. There are still some issues to resolve before this has any help for real use cases. #roadmap


Formini doesn’t care what inputs you use. It however provides a TextEditingController via state.controller out of the box. For inputs other than TextFields you can use state.onChange and state.field.value.

Values are not limited only to Dart built in types. If you want to store a date field as DateTime and display the value formatted you absolutely can.

Login form using formini

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

class LoginForm extends StatelessWidget {
  Widget build(BuildContext context) {
    return Formini(
      validator: const LoginFormValidator(),
      initialValues: const {'email': 'foo'},
      onSubmit: _authenticate,
      child: Column(children: [
        ForminiStateBuilder(builder: (context, form) {
          return Column(children: [
            Text('Status: ${form.status}'),
            Text('Values: ${form.values}'),
          name: 'email',
          builder: (context, state) => TextField(
            controller: state.controller,
            decoration: InputDecoration(
              labelText: 'Email address',
              errorText: state.field.errorText,
          name: 'password',
          builder: (context, state) => TextField(
            controller: state.controller,
            obscureText: true,
            decoration: InputDecoration(
              labelText: 'Password',
                  state.field.touched ? state.field.error?.toString() : null,
        ForminiStateBuilder(builder: (context, form) {
          return RaisedButton(
            onPressed: form.submit,
            child: Text('Login'),

  Future<bool> _authenticate(Map<String, dynamic> credentials) async {
    // Do what ever you need to do here.

    return true;


Implement the Validator interface on your validator class.

1. Option – Manually

import 'package:formini/formini.dart';

class LoginFormValidator implements Validator {
  const LoginFormValidator();

  Map<String, Exception> validate(Map<String, dynamic> values) {
    final errors = <String, Exception>{};

    if (values['email'] == null || values['email'].isEmpty) {
      errors['email'] = Exception('Email is required');
    } else if (!values['email'].contains('@')) {
      errors['email'] = Exception('Email is invalid');

    if (values['password'] == null || values['password'].isEmpty) {
      errors['password'] = Exception('Password is required');

    return errors;

2. Option – Schemani (recommended)

Use schemani_formini package for validating values using schemani. Or just copy the one simple file to your project.

import 'package:schemani/schemani.dart';
import 'package:schemani_formini/schemani_formini.dart';

const loginFormValidator = SchemaniForminiValidator(MapSchema({
  'email': [Required(), Email()],
  'password': [Required()],

API reference


Please open an issue or pull request in GitHub. Any help and feedback is much appreciated.




  • Support for nested values maps
  • Support for lists
  • Async validation
  • Unit testing after refactoring
    • Separate core out from the Flutter stuff
  • Benchmarking

Source Code

Please Visit Simple yet powerful form state management at this Github Link