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');

resetAll requires an acknowledge string 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.