flutter_validators 1.2.0 copy "flutter_validators: ^1.2.0" to clipboard
flutter_validators: ^1.2.0 copied to clipboard

A pure dart package of String validators and sanitizers. Inspired by validator.js.

Flutter Validators Banner

Flutter Validators

The most comprehensive string validation package for Dart & Flutter.

Pub Version CI MIT License Stars

Inspired by validator.js · 40+ validators & sanitizers · Works with Flutter Forms out of the box


Flutter Validators is a pure Dart package with 40+ string validators and 13 sanitizers — from emails and URLs to credit cards, UUIDs, JWTs and strong-password checks. Every validator works three ways:

  • as a top-level functionisEmail('foo@bar.com')
  • as a String extension'foo@bar.com'.isEmail
  • as a Flutter form validatorValidator.email() plugs straight into TextFormField

Zero runtime dependencies. Fully tested. Works with both Dart and Flutter.


📚 Table of Contents #


✨ Features #

  • 40+ validators covering email, URL, numbers, encodings, identifiers, crypto hashes and more.
  • 13 sanitizers for trimming, HTML escaping, character filtering and type conversion.
  • Three usage styles — top-level functions, String extensions, and Flutter form validators — pick whatever reads best.
  • First-class Flutter form support via the Validator class, which returns String? Function(String?) closures with customizable error messages.
  • Pure Dart, zero runtime dependencies — lightweight and safe to add to any project.
  • Fully tested — every validator and sanitizer has dedicated test coverage.

📦 Installation #

Add the package to your pubspec.yaml:

dependencies:
  flutter_validators: ^1.2.0

Then run:

dart pub get

🚀 Quick Start #

Import the package:

import 'package:flutter_validators/flutter_validators.dart';

As String extensions — the most concise style:

'foo@bar.com'.isEmail;           // true
'https://google.com'.isURL;      // true
'4111111111111111'.isCreditCard; // true
'abc123'.isAlphanumeric;         // true

As top-level functions — handy when the value isn't a literal:

isEmail('foo@bar.com');     // true
isURL('https://google.com'); // true
isIP('192.168.1.1');        // true

As Flutter form validators — drop straight into TextFormField:

TextFormField(
  validator: Validator.email(errorMessage: 'Enter a valid email'),
)

🧩 Validators #

Every validator is available both as a top-level function and as a String extension. Parameterized validators accept their options as named/positional arguments.

Contact and Web #

Validator Extension Description
isEmail(str) str.isEmail Valid email address
isURL(str) str.isURL Valid HTTP/HTTPS URL
isFQDN(str) str.isFQDN Fully qualified domain name
isPhone(str) str.isPhone Phone number (international & US formats)
isLatLong(str) str.isLatLong latitude,longitude coordinate pair
'user@example.com'.isEmail;   // true
'https://dart.dev'.isURL;     // true
'sub.example.co.uk'.isFQDN;   // true
'localhost'.isFQDN;           // false (no TLD)
'(123) 456-7890'.isPhone;     // true
'40.7128,-74.0060'.isLatLong; // true

Numbers #

Validator Extension Description
isInt(str) str.isInt Integer (positive or negative)
isNumeric(str) str.isNumeric Number (integer or float)
isFloat(str, {min, max}) str.isFloat({min, max}) Finite float, optionally within a range
isDecimal(str) str.isDecimal Decimal number
isHexadecimal(str) str.isHexadecimal Hexadecimal number
isOctal(str) str.isOctal Octal number
isPort(str) str.isPort Port number (0–65535)
'42'.isInt;                      // true
'3.14'.isNumeric;                // true
'1.5'.isFloat();                 // true
'5'.isFloat(min: 0, max: 2);     // false (out of range)
'.5'.isDecimal;                  // true
'deadBEEF'.isHexadecimal;        // true
'0o17'.isOctal;                  // true
'8080'.isPort;                   // true
'65536'.isPort;                  // false (out of range)

Text and Format #

Validator Extension Description
isAlpha(str) str.isAlpha Letters only (a–z, A–Z)
isAlphanumeric(str) str.isAlphanumeric Letters and numbers only
isAscii(str) str.isAscii ASCII characters only
isLowercase(str) str.isLowercase Entirely lowercase
isUppercase(str) str.isUppercase Entirely uppercase
isLength(str, min, [max]) str.isLength(min, [max]) Length within a range
isByteLength(str, min, [max]) str.isByteLength(min, [max]) UTF-8 byte length within a range
isSlug(str) str.isSlug URL slug (my-blog-post)
isIn(str, values) str.isIn(values) One of an allowed set of values
matches(str, pattern) str.matches(pattern) Matches a Pattern / RegExp
contains(str, seed, {ignoreCase, minOccurrences}) Contains a substring
equals(str, comparison) str.equals(comparison) Exact (case-sensitive) string match
'Hello'.isAlpha;                       // true
'abc123'.isAlphanumeric;               // true
'héllo'.isAscii;                       // false
'hello'.isLowercase;                   // true
'abc'.isLength(2, 5);                  // true
'é'.isByteLength(2, 2);                // true ('é' is 2 bytes in UTF-8)
'my-blog-post'.isSlug;                 // true
'red'.isIn(['red', 'green', 'blue']);  // true
'abc123'.matches(RegExp(r'\d+'));      // true
'foo'.equals('foo');                   // true

// `contains` is a top-level function only (see Behavior Notes)
contains('hello world', 'world');                  // true
contains('Hello World', 'world', ignoreCase: true); // true
contains('a-a-a', 'a', minOccurrences: 3);          // true

Encoding and Data #

Validator Extension Description
isBase32(str) str.isBase32 Base32 encoded
isBase58(str) str.isBase58 Base58 encoded
isBase64(str, {urlSafe}) str.isBase64({urlSafe}) Base64 encoded (standard or URL-safe)
isJson(str) str.isJson Valid JSON
isHexColor(str) str.isHexColor Hex color code (#fff, ff0000)
isBoolean(str) str.isBoolean Boolean string (true/false/1/0)
isDate(str) str.isDate Parseable date string
'JBSWY3DP'.isBase32;             // true
'aGVsbG8='.isBase64();           // true
'a-b_cdef'.isBase64(urlSafe: true); // true
'{"name":"Dart"}'.isJson;        // true
'#ff0000'.isHexColor;            // true
'true'.isBoolean;                // true
'2024-01-15'.isDate;             // true

Identifiers and Crypto #

Validator Extension Description
isUUID(str) str.isUUID UUID (v1, v3, v4, v5)
isMongoId(str) str.isMongoId MongoDB ObjectId (24-char hex)
isMD5(str) str.isMD5 MD5 hash
isJWT(str) str.isJWT JSON Web Token
isCreditCard(str) str.isCreditCard Credit card number (Luhn algorithm)
isMACAddress(str) str.isMACAddress MAC address (EUI-48 / EUI-64)
isSemVer(str) str.isSemVer Semantic version
'550e8400-e29b-41d4-a716-446655440000'.isUUID; // true
'507f1f77bcf86cd799439011'.isMongoId;          // true
'd41d8cd98f00b204e9800998ecf8427e'.isMD5;      // true
'eyJhbGci.eyJzdWIi.SflKxwRJ'.isJWT;            // true
'4111111111111111'.isCreditCard;               // true
'00:1B:44:11:3A:B7'.isMACAddress;              // true
'2.1.0-alpha.1'.isSemVer;                       // true

Security #

Validator Extension Description
isStrongPassword(str, {...}) str.isStrongPassword({...}) Password meets configurable strength rules

isStrongPassword accepts five options, all with sensible defaults:

Option Default Meaning
minLength 8 Minimum total length
minLowercase 1 Minimum lowercase letters
minUppercase 1 Minimum uppercase letters
minNumbers 1 Minimum digits
minSymbols 1 Minimum non-alphanumeric symbols
'Abcd1234!'.isStrongPassword();  // true
'weak'.isStrongPassword();       // false

// Relax the rules — e.g. allow passphrases with no symbols or digits
'abcdefghij'.isStrongPassword(
  minUppercase: 0,
  minNumbers: 0,
  minSymbols: 0,
); // true

🧹 Sanitizers #

Sanitizers transform or coerce strings. Like validators, they're available as both top-level functions and String extensions. Import them via the main library or directly:

import 'package:flutter_validators/flutter_validators.dart';
// or, sanitizers only:
import 'package:flutter_validators/sanitizers.dart';

Trimming #

Sanitizer Extension Description
trim(str, [chars]) str.trimChars(chars) Trim whitespace/chars from both ends
ltrim(str, [chars]) str.ltrimChars(chars) Trim from the start
rtrim(str, [chars]) str.rtrimChars(chars) Trim from the end
trim('  hello  ');        // 'hello'
trim('xxhelloxx', 'x');   // 'hello'
ltrim('00042', '0');      // '42'
rtrim('hello!!!', '!');   // 'hello'

HTML Escaping #

Sanitizer Extension Description
escape(str) str.escape() Escape HTML-unsafe characters
unescape(str) str.unescape() Reverse of escape
escape('<script>alert(1)</script>');
// '&lt;script&gt;alert(1)&lt;&#x2F;script&gt;'

unescape('&lt;b&gt;hi&lt;&#x2F;b&gt;'); // '<b>hi</b>'

Character Filtering #

Sanitizer Extension Description
blacklist(str, chars) str.blacklist(chars) Remove the listed characters
whitelist(str, chars) str.whitelist(chars) Keep only the listed characters
stripLow(str, {keepNewLines}) str.stripLow({keepNewLines}) Remove ASCII control characters
blacklist('hello world', 'lo');              // 'he wrd'
whitelist('a1b2c3', '0123456789');           // '123'
stripLow('line1\nline2');                    // 'line1line2'
stripLow('line1\nline2', keepNewLines: true); // 'line1\nline2'

Type Conversion #

Sanitizer Extension Returns Description
toBoolean(str, {strict}) str.toBoolean({strict}) bool Convert to a boolean
toInt(str, {radix}) str.toInt({radix}) int? Parse to an integer
toFloat(str) str.toFloat() double? Parse to a double
toDate(str) str.toDate() DateTime? Parse to a DateTime
toBoolean('true');             // true
toBoolean('0');                // false
toBoolean('yes', strict: true); // false (strict: only '1'/'true' are true)
toInt('42');                   // 42
toInt('ff', radix: 16);        // 255
toInt('abc');                  // null
toFloat('3.14');               // 3.14
toDate('2024-01-15');          // DateTime(2024, 1, 15)

Email Normalization #

Sanitizer Extension Returns Description
normalizeEmail(str) str.normalizeEmail() String? Canonicalize an email address
normalizeEmail('Test.User+promo@GMAIL.com'); // 'testuser@gmail.com'
normalizeEmail('User@Example.COM');          // 'User@example.com'
normalizeEmail('not-an-email');              // null

📝 Flutter Form Integration #

The Validator class returns String? Function(String?) closures — exactly the type TextFormField.validator expects. A closure returns null when the value is valid, or the error message when it isn't. Every method accepts a custom errorMessage.

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

class SignUpForm extends StatefulWidget {
  const SignUpForm({super.key});

  @override
  State<SignUpForm> createState() => _SignUpFormState();
}

class _SignUpFormState extends State<SignUpForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        children: [
          // Combine `required` with `email` to enforce a non-empty, valid email.
          TextFormField(
            decoration: const InputDecoration(labelText: 'Email'),
            autovalidateMode: AutovalidateMode.onUserInteraction,
            validator: (value) {
              return Validator.required(errorMessage: 'Email is required')(value) ??
                  Validator.email(errorMessage: 'Enter a valid email')(value);
            },
          ),
          TextFormField(
            decoration: const InputDecoration(labelText: 'Website'),
            autovalidateMode: AutovalidateMode.onUserInteraction,
            validator: Validator.url(),
          ),
          TextFormField(
            decoration: const InputDecoration(labelText: 'Password'),
            obscureText: true,
            autovalidateMode: AutovalidateMode.onUserInteraction,
            validator: Validator.strongPassword(
              errorMessage: 'Use 8+ chars with upper, lower, number & symbol',
            ),
          ),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Form is valid!')),
                );
              }
            },
            child: const Text('Sign Up'),
          ),
        ],
      ),
    );
  }
}

A complete, runnable app is in the example/ directory.

Validator API Reference #

Every method on the Validator class returns String? Function(String?):

Validator.required({String errorMessage})
Validator.email({String errorMessage})
Validator.url({String errorMessage})
Validator.ip({int? version, String errorMessage})
Validator.fqdn({String errorMessage})
Validator.phone({String errorMessage})
Validator.latLong({String errorMessage})
Validator.date({String errorMessage})
Validator.numeric({String errorMessage})
Validator.integer({String errorMessage})
Validator.float({double? min, double? max, String errorMessage})
Validator.decimal({String errorMessage})
Validator.hexadecimal({String errorMessage})
Validator.octal({String errorMessage})
Validator.port({String errorMessage})
Validator.alpha({String errorMessage})
Validator.alphanumeric({String errorMessage})
Validator.ascii({String errorMessage})
Validator.lowercase({String errorMessage})
Validator.uppercase({String errorMessage})
Validator.slug({String errorMessage})
Validator.length(int min, {int? max, String errorMessage})
Validator.byteLength(int min, {int? max, String errorMessage})
Validator.contains(String seed, {bool ignoreCase, int minOccurrences, String errorMessage})
Validator.matches(Pattern pattern, {String errorMessage})
Validator.inList(Iterable<String> allowed, {String errorMessage})
Validator.equals(String comparison, {String errorMessage})
Validator.base32({String errorMessage})
Validator.base58({String errorMessage})
Validator.base64({bool urlSafe, String errorMessage})
Validator.json({String errorMessage})
Validator.hexColor({String errorMessage})
Validator.boolean({String errorMessage})
Validator.uuid({String errorMessage})
Validator.mongoId({String errorMessage})
Validator.md5({String errorMessage})
Validator.jwt({String errorMessage})
Validator.creditCard({String errorMessage})
Validator.macAddress({String errorMessage})
Validator.semVer({String errorMessage})
Validator.strongPassword({int minLength, int minLowercase, int minUppercase, int minNumbers, int minSymbols, String errorMessage})

💡 Behavior Notes and FAQ #

Validator methods treat null and empty strings as valid. This is intentional — it lets you compose validators freely. To make a field mandatory, pair it with Validator.required():

validator: (value) {
  return Validator.required()(value) ?? Validator.email()(value);
}

contains is a top-level function only. Dart's String already has a built-in .contains() method, so the package does not add a conflicting extension. Use contains(str, seed) instead of str.contains(...) when you need the case-insensitivity or minOccurrences options.

Trimming extensions are named trimChars / ltrimChars / rtrimChars. Dart's String already provides .trim(), .trimLeft() and .trimRight() for whitespace, so the custom-character variants use distinct names to avoid collisions. The top-level functions keep the plain trim / ltrim / rtrim names.

isURL accepts only http and https schemes. Other schemes such as ftp:// are rejected.

isBase64 has a urlSafe option. By default it validates the standard Base64 alphabet (with padding); pass urlSafe: true to validate the URL- and filename-safe alphabet instead.

isBoolean accepts 'true', 'false', '1' and '0'. Any other value is not a boolean string.

isFloat rejects non-finite values. 'Infinity' and 'NaN' return false, even though Dart's double.tryParse can parse them.

normalizeEmail applies Gmail-specific rules. For gmail.com / googlemail.com addresses it lowercases the local part, removes dots, and strips any +tag suffix. For other providers it only lowercases the domain. It returns null if the input isn't a valid email.


🤝 Contributing #

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.


📄 License #

This project is MIT licensed.

7
likes
160
points
118
downloads

Documentation

API reference

Publisher

verified publisherstac.dev

Weekly Downloads

A pure dart package of String validators and sanitizers. Inspired by validator.js.

Repository (GitHub)
View/report issues

License

MIT (license)

More

Packages that depend on flutter_validators