achievements-react package to integrate achievements into your React application with hooks and context.
Installation
Install the package
Define your achievements
Create a file (e.g.,
src/achievements.ts) to define and initialize your achievements:Using Hooks
The factory pattern fromcreateAchievements() returns fully-typed hooks that are bound to your achievement IDs. You never need to write useHook<AchievementId>() again.
useAchievements()
Get the engine instance for imperative operations:unlock(id)- Unlock an achievementsetProgress(id, value)- Set absolute progress valueincrementProgress(id)- Increment progress by 1collectItem(id, item)- Add unique item to tracked setsetMaxProgress(id, max)- Update max progress at runtimedismissToast(id)- Remove achievement from toast queuereset()- Clear all stateisUnlocked(id)- Check if unlocked (non-reactive)getProgress(id)- Get current progress (non-reactive)getItems(id)- Get collected items set (non-reactive)getState()- Get full state snapshot (non-reactive)getDefinition(id)- Get achievement definition
useIsUnlocked(id)
Reactive boolean that re-renders only when the specific achievement’s lock state changes:useProgress(id)
Reactive progress tracker that re-renders only when the specific achievement’s progress changes:{ progress: number, max: number | undefined }
useUnlockedCount()
Reactive count that re-renders only when the total number of unlocked achievements changes:useAchievementToast()
Manage achievement unlock notifications:{ queue: ReadonlyArray<TId>, dismiss: (id: TId) => void }
useTamperDetected()
Detect when stored data fails integrity checks:- Tamper detected at module load (before React mounted)
- Tamper detected at runtime during normal operation
Complete Example
Here’s a real-world example from the library’s demo app:achievements.ts
SessionInit.tsx
NodeScanner.tsx
App.tsx
Direct Engine Access
You can also use the engine directly outside of React components:Performance Optimization
The hooks use selector-based subscriptions to minimize re-renders:useIsUnlocked(id)- Only re-renders when that specific achievement’s lock state changesuseProgress(id)- Only re-renders when that specific achievement’s progress changesuseUnlockedCount()- Only re-renders when the total count changesuseAchievementToast()- Only re-renders when the toast queue changes
TypeScript Support
The factory pattern provides full type safety:Next Steps
- Vanilla JS Guide - Use the core package without React
- Custom Storage Guide - Implement custom storage backends
- Custom Hash Guide - Use custom hashing for tamper detection
