Skip to main content

Riverpod CraftAlpha

Solutions and enhancements for Riverpod state management

Clean API

Write less boilerplate. Get full IDE autocomplete from ref. — discover every provider, method, and command without memorizing names.

Side Effects

Stop writing loading/error/success tracking for every API call. Add @command and get independent state management with concurrency control for free.

📄

Pagination

Build infinite scroll lists without managing page state, controllers, or loading indicators yourself. Just define your data source.

🚀

Fast Generation

Save a file, see generated code instantly. No more waiting seconds (or minutes) for code generation to finish.

Write less, do more

Annotate your functions and classes — the generated code gives you a clean, type-safe API.

Define a provider


Future<List<Note>> notes(Ref ref) async {
final response = await http.get(
Uri.parse('https://api.example.com/notes'),
);
return (jsonDecode(response.body) as List)
.map(Note.fromJson)
.toList();
}

Use in widgets

final state = ref.notesProvider.watch();

state.when(
loading: () => CircularProgressIndicator(),
data: (notes) => ListView(...),
error: (e) => Text('Error: $e'),
);

ref.notesProvider.reload();
ref.notesProvider.invalidate();

Define a command



Future<void> saveNote(Ref ref, {
required String title,
required String body,
}) async {
await http.post(
Uri.parse('https://api.example.com/notes'),
body: jsonEncode({'title': title, 'body': body}),
);
}

Handle side effects

// Run the command
ref.saveNoteCommand.run(title: 'Hello', body: '...');

// Watch its state (independent from data)
final state = ref.saveNoteCommand.watch();

state.when(
init: () => Text('Save'),
loading: (_) => CircularProgressIndicator(),
data: (_, __) => Text('Saved!'),
error: (_, e) => Text('Failed: $e'),
);