Architecture Guide
Conceptual Model
react-native-toast-system is a provider-owned runtime with host-based rendering.
ToastProvider: lifecycle owner for state, templates, and global bridge binding- toast store/controller layer: receives commands, resolves host config, updates toast state
ToastHost/ToastViewport: render layer for a single host stacktoastanduseToast: command entrypoints into the same runtime
Mental Model
Think in this order when designing toast behavior:
- choose host (
root,modal-host,sheet-host, nested host IDs) - choose identity behavior (
id/dedupeKey) - choose flow behavior (
groupId/groupBehavior) - choose ordering behavior (
priority, hostpriorityMode)
This keeps host isolation, flow updates, and ordering predictable.
Lifecycle: Provider -> Command -> Render -> Dismiss
- Provider mounts and binds a runtime bridge for global
toast. - App issues command via
toastoruseToast(hostId?). - Store resolves host, dedupe/group/priority rules, and inserts or updates toast records.
- Matching host stack re-renders and animates toast item lifecycle.
- Dismiss/update flows feed back through the same controller/store path.
- Provider unmount unbinds the global bridge for safety.
Event, State, and Render Separation
- Event/command layer:
toast,useToast, controller methods (show,update,dismiss,promise)
- State layer:
- host-scoped toast records, config resolution, stack ordering
- Render layer:
- host viewport rendering, gesture + animation + keyboard-aware visual behavior
This separation keeps API ergonomics stable while preserving flexibility in host rendering behavior.
Provider and Host Boundaries
- One provider controls one runtime subtree.
- Hosts are identified by
hostIdand can coexist (root,modal,sheet, nested IDs). ToastViewportis an alias ofToastHostused as ergonomic default naming.- Runtime isolation should use nested providers only when isolation is intentional.
Host Isolation and Routing Rules
- Global
toast.*defaults to providerdefaultHostIdunless you calltoast.host("..."). useToast(hostId?)returns a host-bound controller.- Host IDs are exact string keys; mismatches silently route nowhere if the target host is not mounted.
Grouping vs Dedupe vs Priority
These are separate concerns:
- dedupe (
id,dedupeKey,dedupeMode): identity resolution - grouping (
groupId,groupBehavior): flow/channel evolution - priority (
priority, hostpriorityMode): ordering significance
Use all three deliberately in async workflows: dedupe for idempotency, grouping for flow updates, priority for prominence.
Integration Playbook Mapping
Use these architecture patterns by scenario:
- standard app flow:
- one provider + one root viewport
- modal-specific UX:
- modal-local host (
hostId="modal-host") inside modal surface boundary
- modal-local host (
- sheet/container UX:
- container-local host (
hostId="sheet-host") inside that container
- container-local host (
- navigation persistence:
- mount root host above transient route content
- keyboard-heavy bottom actions:
- enable
keyboardAvoidanceand tunekeyboardOffset
- enable
- gesture-heavy stacks:
- verify gesture config thresholds and pause behavior
See Advanced Recipes for copy-paste scenarios.
Global API vs Hook API
toastis best for:- non-component call sites
- centralized event handlers
- explicit host routing with
toast.host("...")
useToast(hostId?)is best for:- component-scoped interactions
- feature-local controller ergonomics
Both route through the same provider runtime and host resolution logic.
Public API vs Internal Modules
Supported API surface is package root only:
import { ToastProvider, ToastViewport, toast, useToast } from "react-native-toast-system";
Do not depend on internal folder paths (src/core/*, src/components/*, etc.). Internal modules are implementation details and may change without semver guarantees.
Compatibility Guidance
- Compatibility target: modern React Native + peer dependency alignment from
package.json. - Expo compatibility: supported through standalone demo workspace and equivalent consumer setup.
- Recommended rollout order:
- provider + root host
- simple show/dismiss flows
- host-targeted modal/sheet flows
- promise/template customization
Runtime Behavior Without Provider
When no active provider is mounted, global toast calls remain safe:
show/success/error/...return fallback IDsupdate/dismiss/isVisiblereturn no-op values (false/0/void)
This avoids crashes during startup/unmount windows but also means no visible toasts until provider is mounted.
Performance Characteristics
- Operations are host-scoped and lightweight (
showappend,update/dismissscan host stack). - Host stack growth is bounded by
maxStackSize. - Host unmount unregisters host state and timer resources.
- Interaction pauses (
pauseOnPress,pauseOnDrag) prevent auto-dismiss races during user interaction.
Validation Boundaries
Current repository confidence comes from:
- automated checks:
typecheck,build,test,example:validate - scenario-driven manual protocols for cross-surface behavior
- explicit known limitations documented in Troubleshooting