Install
$ agentstack add skill-serverpod-skills-registry-riverpod-faq-and-practices ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Riverpod — FAQ and best practices
FAQ
ref.refresh vs ref.invalidate
ref.refresh = ref.invalidate + ref.read: it invalidates the provider and returns the new value. Use invalidate when you don't need the new value (e.g. "recompute when the user pulls to refresh"). Use refresh when you need the result right away. After invalidate alone, recomputation can happen at the next frame or when the provider is next read; refresh forces immediate recomputation by reading.
Why no shared interface between Ref and WidgetRef?
Ref (in providers) and WidgetRef (in widgets) are kept separate on purpose so you don't write code that conditionally depends on both; they have subtle differences and mixing would be error-prone. Prefer Ref: put logic in a Notifier and call ref.read(notifierProvider.notifier).yourMethod() from the UI; the method uses the Notifier's Ref.
Why ConsumerWidget instead of StatelessWidget?
InheritedWidget (and thus BuildContext) cannot support "on change" listeners like ref.listen, cannot know when widgets stop listening (needed for auto-dispose and family), and has lifecycle quirks (e.g. with GlobalKeys). Riverpod needs a Ref that isn't tied to BuildContext for these features. Hence ConsumerWidget (and Consumer) provide a Ref.
Why doesn't hooksriverpod export flutterhooks?
So each package can be versioned independently; a breaking change in one doesn't force the other to break.
Reset all providers at once?
There is no API to reset all providers; it's considered an anti-pattern. For "logout and clear state", have providers that depend on the current user ref.watch a user provider; when the user logs out, that provider changes and dependents recompute or clear. Only user-dependent state resets; the rest stays.
"Using ref when a widget is about to or has been unmounted is unsafe"
This (or "No ProviderScope found") happens when ref is used after an await in a widget that may have been disposed. After any await, check if (!context.mounted) return; before using ref (same pattern as with BuildContext).
Do / Don't
AVOID initializing providers in a widget
Providers should initialize themselves. Don't call something like ref.read(provider).init() from initState. If initialization depends on user action (e.g. navigation), trigger it from the action (e.g. onPressed before Navigator.push).
AVOID using providers for ephemeral state
Use providers for shared business state, not for: selected tab/item, form state (which should reset on leave/back), animations, or controller-like state (e.g. TextEditingController). For local widget state use flutter_hooks or local state. Storing "selected item" in a global provider can break back navigation (e.g. back from /books/21 should show /books/42, but the provider still holds 21).
DON'T perform side effects during provider initialization
Providers should represent "read" operations. Don't use a provider's build to perform "write" operations (e.g. submitting a form). That can lead to skipped or duplicated side effects. For loading/error of a side effect use mutations (see riverpod-mutations).
PREFER statically known providers with ref.watch/read/listen
Use ref.watch(provider) where provider is a top-level final (or otherwise statically known). Avoid passing a provider as a parameter and then watching it so that static analysis and riverpod_lint can work.
AVOID dynamically creating providers
Define providers as top-level final variables. Don't create them inside classes or as instance fields; that can cause memory leaks and unsupported behavior. Static final in a class is allowed but not supported by code generation.
Enable riverpod_lint (see riverpod-getting-started) to enforce many of these practices.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: serverpod
- Source: serverpod/skills-registry
- License: BSD-3-Clause
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.