Try Zema Live
Experiment with schema validation directly in your browser
Zero-Cost Architecture
Zema leverages Dart 3.3+ Extension Types to provide type-safety without the performance penalty of traditional models.
Standard POJOs / Freezed
- Deep Cloning
Every validation creates a full copy of your data.
- GC Pressure
Constant object allocations trigger the Garbage Collector.
- Boxed Types
Adds a wrapper layer between your app and the raw JSON.
The Zema Way
- In-Place Validation
We validate your raw Map directly. No cloning. No lag.
- Identity Preservation
identical(rawData, zemaObject)is always true. - Static Type Casting
Type safety is enforced at compile-time with zero runtime cost.
Code-First Schemas
Define expressive data contracts using pure Dart. No annotations, no build_runner. One schema to rule them all: from API boundaries to UI forms.
Defensive Runtime Safety
Stop TypeError before they reach your business logic. Zema validates raw JSON at the edge, ensuring your models always operate on sanitized, type-safe data.
Zero-Cost & Zero Lock-In
Leverage Extension Types for maximum performance. Integrate seamlessly with Freezed or existing classes. Secure your stack without the rewrite.
Native Integration
Zema is pure Dart. It secures your data flow across the entire stack.
Flutter Forms(Coming Soon)
Bind schemas directly to your UI. Use zema to drive reactive form validation with localized error messages.
Type-Safe I/O(Coming Soon)
Perfect for Dio or Http. Validate incoming JSON at the edge before it touches your business logic.
Server-Side Dart(Coming Soon)
Run the same schemas in Dart Frog or Shelf. Garantie 100% logic sharing between client and server.
Cleaner Code
See the difference with real-world examples
- Without Zema
- With Zema
class User {
final String name;
final String email;
final int age;
User({required this.name, required this.email, required this.age});
factory User.fromJson(Map<String, dynamic> json) {
// 1. Verbose and repetitive manual validation
if (json['name'] == null || (json['name'] as String).isEmpty) {
throw Exception('Name is required');
}
// 2. Fragility of casts (Risk of TypeError at runtime)
final email = json['email'] as String;
if (!RegExp(r'^[w-.]+@([w-]+.)+[w-]{2,4}$').hasMatch(email)) {
throw Exception('Invalid email format');
}
final age = json['age'] as int;
if (age < 18) {
throw Exception('User must be an adult');
}
// 3. No overall vision: stops at the first error found
return User(
name: json['name'],
email: email,
age: age,
);
}
}
final userSchema = z.object({
'name': z.string().min(1),
'email': z.string().email(),
'age': z.int().min(18),
});
extension type User(Map<String, dynamic> _) {
String get name => _['name'];
String get email => _['email'];
String get age => _['age'];
}
void main() {
final result = userSchema.safeParse(json);
if (result is ZemaSuccess) {
// 'user' is now typed and has autocompletion
final user = result.data;
print(user.name);
}
}
Ready to build bulletproof apps?
Join the next generation of Dart developers using zero-cost validation. No build runner, no boilerplate, just pure type safety.
dart pub add zema