kickin_storage
A Flutter package for simple, reliable local storage. It wraps Hive with three ready-to-use box types: general, encrypted, and lazy-loaded.
Part of the Kickin toolkit for Flutter.
Installation
flutter pub add kickin_storage
Or add it manually to your pubspec.yaml:
dependencies:
kickin_storage: ^0.0.1+1
How it works
Everything goes through a single singleton: KHive.on. It owns three box types, each suited to a different use case:
| Box | Access | Use for |
|---|---|---|
KHive.on.app (AppHive) |
Sync reads, async writes | Preferences, UI state, cached responses |
KHive.on.secure (KSecureHive) |
Sync reads, async writes | Auth tokens, passwords, sensitive data |
KHive.on.lazy (KLazyHive) |
Async reads and writes | Large data you don't want fully in memory |
Quick start
Step 1 — Initialize in main
Call KHive.on.initialize() before runApp, opting in to only the boxes you need:
import 'package:kickin_storage/kickin_storage.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await KHive.on.initialize(
initApp: true, // general storage
initSecure: true, // encrypted storage
initLazy: true, // lazy-loaded storage
);
runApp(const MyApp());
}
Step 2 — Read and write
// General storage
await KHive.on.app.setData(key: 'theme', value: 'dark');
final theme = KHive.on.app.getData(key: 'theme'); // sync
// Encrypted storage
await KHive.on.secure.setData(key: 'token', value: 'my-secret-token');
final token = KHive.on.secure.getData(key: 'token'); // sync
// Lazy storage (large data)
await KHive.on.lazy.setData(key: 'feed', value: ['item1', 'item2']);
final feed = await KHive.on.lazy.getData(key: 'feed'); // async
That's it. No setup beyond initialization.
Box types in detail
AppHive — general purpose
Best for app settings, UI state, and cached data that doesn't need encryption.
- Reads are synchronous (the whole box is in memory).
- Writes are asynchronous.
await KHive.on.app.setData(key: 'onboarded', value: true);
final onboarded = KHive.on.app.getData(key: 'onboarded'); // bool?
await KHive.on.app.deleteData(key: 'onboarded');
resetAllrequires anacknowledgestring to prevent accidental data loss.
KSecureHive — encrypted storage
Uses AES encryption. The encryption key is generated on first use and stored in the platform's secure storage (flutter_secure_storage). On subsequent app starts, the same key is retrieved automatically meaning your data survives restarts.
await KHive.on.secure.setData(key: 'auth_token', value: 'abc123');
final token = KHive.on.secure.getData(key: 'auth_token');
resetAll()deletes both the box contents and the encryption key from secure storage. This is irreversible (the data cannot be recovered).
KLazyHive — lazy-loaded storage
Values are only loaded from disk when you explicitly request them. Use this for large datasets like cached API payloads or media metadata where loading everything into memory upfront is wasteful.
- Reads are asynchronous (fetched from disk on demand).
- Writes are asynchronous.
await KHive.on.lazy.setData(key: 'articles', value: articleList);
final articles = await KHive.on.lazy.getData(key: 'articles');
Reactive updates (watching changes)
Both AppHive and KLazyHive support listening to key changes in real time:
// Emits the current value immediately, then re-emits on every change
KHive.on.app.watchData(key: 'theme').listen((theme) {
print('Theme changed to: $theme');
});
// Emits a raw BoxEvent on every write (no initial value)
KHive.on.app.watchChanges(key: 'theme').listen((_) {
print('theme key was written');
});
KLazyHive.watchData works the same way, but awaits the async read before emitting the initial value.
Initializing boxes on demand
You don't have to initialize all boxes upfront. You can initialize them individually when needed. KHive guards against double-initialization:
if (!KHive.on.app.isInitialized) {
await KHive.on.app.initialize();
}
Full example
import 'package:kickin_storage/kickin_storage.dart';
// Use an enum to avoid raw key strings across your codebase
enum StorageKey { theme, authToken, cachedFeed }
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await KHive.on.initialize(
initApp: true,
initSecure: true,
initLazy: true,
);
// General
await KHive.on.app.setData(key: StorageKey.theme.name, value: 'dark');
final theme = KHive.on.app.getData(key: StorageKey.theme.name);
print('Theme: $theme');
// Secure
await KHive.on.secure.setData(key: StorageKey.authToken.name, value: 'my-secret');
final token = KHive.on.secure.getData(key: StorageKey.authToken.name);
print('Token: $token');
// Lazy
await KHive.on.lazy.setData(key: StorageKey.cachedFeed.name, value: ['a', 'b', 'c']);
final feed = await KHive.on.lazy.getData(key: StorageKey.cachedFeed.name);
print('Feed: $feed');
// Reactive
KHive.on.app.watchData(key: StorageKey.theme.name).listen((v) {
print('Theme updated: $v');
});
runApp(const MyApp());
}
API reference summary
| Class | Purpose |
|---|---|
KHive |
Singleton entry point that initializes and owns all box types |
AppHive |
General-purpose synchronous key-value box |
KSecureHive |
AES-encrypted box backed by flutter_secure_storage |
KLazyHive |
Lazy-loaded box for large or infrequently accessed data |
Shared methods (available on all box types):
| Method | Description |
|---|---|
initialize() |
Opens the box. Must be called before use |
setData(key:, value:) |
Stores a value |
getData(key:) |
Retrieves a value (sync on AppHive/KSecureHive, async on KLazyHive) |
deleteData(key:) |
Removes a key |
resetAll(...) |
Clears all data from the box |
watchData(key:) |
Stream of values for a key (current + future changes) |
watchChanges(key:) |
Stream of raw box events for a key |
Additional storage drivers (SharedPreferences, SQLite via Drift) are planned for future releases.
Libraries
- kickin_storage
- A Kickin package providing simple helpers around Hive for app and secure storage.