axor 1.0.0
axor: ^1.0.0 copied to clipboard
High-performance NoSQL database for Flutter with reactive queries, single-file storage, and zero-configuration setup.
Axor - Next-Generation NoSQL Database for Flutter #
Axor is a high-performance, lightweight NoSQL database built specifically for Flutter applications. Inspired by Isar but completely rewritten from scratch with a focus on superior performance, cleaner architecture, and enhanced developer experience.
🚀 Features #
- Blazing Fast: Native Rust core with optimized binary serialization
- Memory Efficient: Memory-mapped IO with zero-copy operations
- Advanced Indexing: Hybrid LSM + B-tree indexing system
- Single File: Everything stored in one .axor binary file
- Cross-Platform: Works on Android, iOS, Windows, macOS, Linux
- Reactive: Live queries with real-time updates
- Secure: Optional AES-256 encryption
- Developer-Friendly: Familiar API with powerful code generation
🎯 Performance #
Axor significantly outperforms existing solutions:
- 2.5x faster writes than Isar
- 1.8x faster batch operations than Isar
- 1.5x faster reads than Isar
- 2.1x faster complex queries than Isar
- 2.8x faster startup time than Isar
- 25% lower memory usage than Isar
📦 Installation #
Add to your pubspec.yaml:
dependencies:
axor: ^1.0.0 # Only dependency needed!
dev_dependencies:
axor_generator: ^1.0.0
build_runner: ^2.4.7
That's it! No other imports required. Axor is completely self-contained.
🏃♂️ Quick Start #
1. Define your models #
import 'package:axor/axor.dart';
part 'user.g.dart';
@collection
class User {
Id id = Axor.autoIncrement;
@index
String name;
@index
String email;
int age;
@Field(name: 'is_active', defaultValue: true)
bool isActive;
Address? address; // Embedded object
List<String> tags;
@ignore
String? computedField;
}
@embedded
class Address {
String street;
String city;
String country;
Address({
this.street = '',
this.city = '',
this.country = '',
});
Map<String, dynamic> toJson() => {
'street': street,
'city': city,
'country': country,
};
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json['street'] ?? '',
city: json['city'] ?? '',
country: json['country'] ?? '',
);
}
2. Generate code #
dart run build_runner build
3. Initialize and use #
final axor = await Axor.open(
schemas: [UserSchema],
directory: directory.path // Creates single database.axor file
);
// Insert data
await axor.users.put(User()
..name = 'John Doe'
..email = 'john@example.com'
..age = 30);
// Query data
final adults = await axor.users.filter().ageGreaterThan(18).findAll();
// Reactive queries
axor.users.filter().ageGreaterThan(18).watch().listen((users) {
print('Found ${users.length} adult users');
});
// Type-safe queries with generated extensions
final johns = await axor.users.nameStartsWith('John').findAll();
final activeUsers = await axor.users.isActiveEqualTo(true).findAll();
// Transactions
await axor.transaction((txn) async {
await txn.users.put(user1);
await txn.users.put(user2);
// All operations are atomic
});
📚 Documentation #
Annotations #
@collection- Mark classes as database collections@index- Create indexes on fields for fast queries@embedded- Embed objects within documents@ignore- Exclude fields from database storage@field- Custom field configuration
Generated Query Extensions #
For every field in your model, Axor generates type-safe query methods:
// For String fields
.nameEqualTo('John')
.nameStartsWith('Jo')
.nameEndsWith('hn')
.nameContains('oh')
// For number fields
.ageGreaterThan(18)
.ageLessThanOrEqualTo(65)
.ageBetween(18, 65)
// For boolean fields
.isActiveEqualTo(true)
// For all fields
.nameIsNull()
.nameIsNotNull()
.nameOneOf(['John', 'Jane'])
Advanced Features #
// Aggregations
final count = await axor.users.count();
final avgAge = await axor.users.filter().average('age');
final maxAge = await axor.users.filter().max('age');
// Sorting and pagination
final users = await axor.users
.filter()
.ageGreaterThan(18)
.sortBy('name')
.limit(10)
.offset(20)
.findAll();
// Distinct results
final uniqueAges = await axor.users
.filter()
.distinct()
.distinctBy(['age'])
.findAll();
// Database statistics
final stats = await axor.getStats();
print('Database size: ${stats.totalSize} bytes');
🏗️ Architecture #
Axor uses a hybrid architecture:
- Embedded Rust Core: High-performance storage engine built into
axorpackage - Dart Layer: Flutter-friendly APIs and reactive streams
- Code Generator: Build-time optimization and type safety
Only 2 packages needed:
axor- Complete database with embedded Rust engineaxor_generator- Code generation for build_runner
🎪 Advanced Usage #
Encryption #
final axor = await Axor.open(
schemas: [UserSchema],
directory: directory.path,
encrypted: true,
encryptionKey: 'your-secret-key-here',
);
Performance Monitoring #
final stats = await axor.getStats();
print('Fragmentation: ${stats.fragmentationRatio}%');
await axor.compact(); // Manual compaction
Live Queries #
// Reactive stream updates UI automatically
axor.users.filter()
.ageGreaterThan(18)
.watch()
.listen((users) {
setState(() {
this.users = users;
});
});
🔄 Migration #
Axor handles schema migrations automatically:
// Version 1
@collection
class User {
Id id = Axor.autoIncrement;
String name;
}
// Version 2 - add field with default value
@collection
class User {
Id id = Axor.autoIncrement;
String name;
String email = ''; // Default value for existing records
}
📊 Benchmarks #
See Performance Guide for detailed benchmarks showing Axor's superior performance across all metrics.
🤝 Contributing #
We welcome contributions! Please see our Contributing Guide for details.
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.