Note: This document is a reference pointer. Complete documentation has been moved to the canonical hooks skill.
For comprehensive data lifecycle hooks documentation, see:
→ objectstack-data/references/data-hooks.md
The canonical reference includes:
- All 8 lifecycle events (beforeFind, afterFind, beforeInsert, afterInsert, beforeUpdate, afterUpdate, beforeDelete, afterDelete)
- Complete Hook definition schema
- HookContext API reference
- Registration methods (declarative, programmatic, file-based)
- 10+ common patterns with full examples
- Performance considerations and optimization tips
- Testing strategies (unit and integration)
- Best practices and anti-patterns
import { Hook, HookContext } from '@objectstack/spec/data';
const hook: Hook = {
name: 'my_hook', // Required: unique identifier
object: 'account', // Required: target object(s)
events: ['beforeInsert'], // Required: lifecycle events
handler: async (ctx: HookContext) => {
// Your logic here
},
priority: 100, // Optional: execution order
async: false, // Optional: background execution (after* only)
condition: "status = 'active'", // Optional: conditional execution
};| Event | When Fires | Use Case |
|---|---|---|
beforeFind |
Before any read (find and findOne) |
Filter queries, log access |
afterFind |
After any read (find and findOne) |
Transform results, enrich data |
beforeInsert |
Before creating a record | Set defaults, validate |
afterInsert |
After creating a record | Send notifications |
beforeUpdate |
Before updating a record (single or bulk multi:true) |
Validate changes |
afterUpdate |
After updating a record (single or bulk) | Trigger workflows |
beforeDelete |
Before deleting a record (single or bulk multi:true) |
Check dependencies |
afterDelete |
After deleting a record (single or bulk) | Clean up related data |
One read event, one write event per kind.
beforeFind/afterFindfire forfindOnetoo (the event attaches to record materialization, not the method), and the write events fire on bulkmulti:trueoperations as well — the row-scoping predicate is inctx.input.ast. There is nobeforeFindOne,beforeCount,beforeAggregate, or*Manyevent.Don't reach for a hook when a declarative mechanism already fits:
- Read authorization / row filtering → RLS / permission rules, not a
beforeFindhook.- Field masking → field-level metadata (secret/masked fields), not an
afterFindhook.- Delete guards → a
beforeDeletehook (this is the right tool).
See the full documentation for complete examples of:
- Setting Default Values — Auto-populate fields on insert
- Data Validation — Custom validation rules beyond declarative
- Preventing Deletion — Block deletes based on conditions
- Data Enrichment — Calculate and set derived fields
- Triggering Workflows — Fire notifications and integrations
- Creating Related Records — Maintain referential integrity
- External API Integration — Sync with external systems
- Multi-Object Logic — Cascade updates across objects
- Conditional Execution — Use
conditionproperty - Data Masking — PII protection in read operations
Three methods available:
// objectstack.config.ts
export default defineStack({
hooks: [accountHook, contactHook],
});ctx.ql.registerHook('beforeInsert', async (hookCtx) => {
// Handler logic
}, { object: 'account', priority: 100 });// src/objects/account.hook.ts
export default {
name: 'account_logic',
object: 'account',
events: ['beforeInsert'],
handler: async (ctx) => { /* ... */ },
};✅ DO:
- Use
before*for validation,after*for side effects - Set
async: truefor non-critical background work - Use
ctx.apifor cross-object operations - Handle errors gracefully with meaningful messages
- Test hooks in isolation and integration
❌ DON'T:
- Don't perform expensive operations in
before*hooks - Don't create infinite loops (hooks triggering themselves)
- Don't use
object: '*'unless absolutely necessary - Don't throw in
after*hooks unless critical - Don't assume
ctx.sessionexists
- objectstack-data/SKILL.md#lifecycle-hooks — Complete hooks system overview
- objectstack-data/references/data-hooks.md — Full data hooks documentation
- objectstack-platform/references/plugin-hooks.md — Plugin hook system
- objectstack-automation — Flows and Workflows for advanced automation
For complete documentation with detailed examples, context API reference, testing strategies, and performance optimization, see the canonical reference: