Hooks and signals let you run code when components are added, changed, or removed. Use hooks when you need a single, definitive lifecycle handler per component. Use signals when you need multiple independent systems to react to the same events.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Ukendio/jecs/llms.txt
Use this file to discover all available pages before exploring further.
Hooks
Hooks are component traits that enforce invariants and run side effects during component mutations. You can configure oneOnAdd, OnRemove, and OnChange hook per component (like a constructor/destructor).
OnAdd Hook
Runs when a component is added to an entity:entity: The entity that received the componentid: The component IDdata: The component data (if any)
OnChange Hook
Runs when a component’s data is modified:OnChange is triggered by world:set() when the component already exists on the entity.OnRemove Hook
Runs when a component is removed from an entity:entity: The entity losing the componentid: The component IDdelete:trueif the entity is being deleted,false/nilif just the component is being removed
The delete Flag
The delete parameter in OnRemove distinguishes between two scenarios:
- Component removal (
delete = false): A single component is removed - Entity deletion (
delete = true): The entire entity is being destroyed
Why It Matters
When an entity is deleted, all its components are removed. Each removal triggersOnRemove. If you try to make structural changes during deletion (like removing related components), you’re fighting against the deletion process.
Proper delete Handling
Check the delete flag and bail early during deletion:
DEBUG Mode
Create a world withDEBUG enabled to catch structural changes during deletion:
- Throws an error if you call
world:add(),world:remove(), orworld:set()insideOnRemovewhendelete = true - Still allows these calls when
delete = false - Helps catch bugs during development
Deletion Order
When entities form a hierarchy, children are cleaned up before parents:This order applies to any relationship with the
(OnDeleteTarget, Delete) trait. See Cleanup Traits for details.Signals
Signals support multiple listeners per component lifecycle event. Each subscription returns an unsubscribe function for cleanup.When to Use Signals
- Multiple independent systems need to react to the same events
- You need to subscribe/unsubscribe dynamically (e.g., UI that only listens while mounted)
- You want decoupled event handling
Added Signal
Subscribe to component additions:Changed Signal
Subscribe to component changes:Removed Signal
Subscribe to component removals:The
delete parameter works the same as in hooks: true for entity deletion, false/nil for component removal.Multiple Listeners
Unlike hooks, signals support any number of subscribers:Unsubscribing
Call the returned function to stop listening:Hooks vs Signals
| Feature | Hooks | Signals |
|---|---|---|
| Listeners per component | One | Unlimited |
| Use case | Enforce component invariants | Multi-system event handling |
| Unsubscribe | N/A (permanent) | Yes (returns function) |
| Performance | Slightly faster | Minimal overhead |
Complete Example
Next Steps
Cleanup Traits
Control what happens when entities are deleted
Query Caching
Optimize repeated queries with caching