Hooks are OpenClaw's pressure plates. Something happens inside the Gateway, the plate gets stepped on, and a small script reacts immediately.
That is the appeal. You get event-driven automation without building a full plugin, and without stuffing every tiny reaction into your main agent prompt.
According to the official OpenClaw docs, hooks are small scripts discovered from bundled, managed, plugin, and workspace directories. They stay dormant until you enable hooks or configure at least one hook entry, which is a sensible guardrail. Event-driven glue is useful. Event-driven glue everywhere is how people ruin weekends.
What hooks are actually for
Hooks are best when you need a narrow reaction to a known event.
- capture or log something when a command runs
- inject extra bootstrap files before an agent session starts
- send a visible heads-up before a planned restart
- save memory when a session resets
- react to inbound or outbound messages in a lightweight way
The common pattern is simple: an event fires, a tiny piece of logic runs, and then the system moves on. If that sounds boring, good. Boring infrastructure is usually the infrastructure that survived production.
What can trigger hooks
The official hooks docs split events into a few families.
Command events
Hooks can listen for command:new, command:reset, command:stop, or the general command event. This is useful when a slash command should leave a trace, save context, or run a tiny side action.
Message events
You can hook into message:received, message:transcribed, message:preprocessed, and message:sent. That makes hooks useful for lightweight audits, message shaping, or notifications around channel traffic.
Session and agent lifecycle events
Hooks can also react before and after compaction, when session properties change, and during agent bootstrap. These are the events that help operators keep the runtime tidy without editing every agent by hand.
Gateway lifecycle events
gateway:startup, gateway:shutdown, and gateway:pre-restart matter when the machine itself needs ceremony. A short restart warning or a BOOT.md action belongs here far more than it belongs in a random conversation prompt.
Good hook use cases
The docs ship with bundled examples, and they reveal the intended shape pretty clearly.
Session memory capture
The bundled session-memory hook saves recent session context when /new or /reset happens. That is a classic hook job: small, event-bound, and easier to reason about than a larger plugin.
Bootstrap customization
The bootstrap-extra-files hook injects extra workspace files during agent bootstrap. If you run a monorepo or a multi-package setup, that is a clean place to add context without turning your default workspace files into a junk drawer.
Operational logging
The command-logger hook writes command events to a central log. Hooks are good for this kind of audit trail because the action is narrow and the trigger is unambiguous.
Restart notices
The gateway:pre-restart event is a good example of where hooks feel elegant. A hook can warn people while channels are still alive, instead of leaving them to guess why the assistant went quiet for a moment.
Why hooks are not just small plugins
This distinction matters. Hooks are the quick reaction layer. Plugins are the deeper integration layer.
If you need things like tool interception, prompt shaping, install-time behavior, or reusable packaged logic with a wider lifecycle, the plugin system is the better fit. If you just need, "when this event happens, run this small script," hooks are usually enough.
The easy test is this: if the behavior would look silly as a two-file directory with a HOOK.md and handler.ts, you are probably past hook territory.
How a hook is structured
OpenClaw expects a small directory with metadata and a handler.
my-hook/
├── HOOK.md
└── handler.tsThe metadata declares the hook name, description, events, and requirements. The handler receives the event payload and can react, log, or push a user-visible message.
---
name: restart-warning
description: "Warn before a planned gateway restart"
metadata:
{ "openclaw": { "emoji": "⚠️", "events": ["gateway:pre-restart"] } }
---export default async function handler(event) {
if (event.type !== "gateway" || event.action !== "pre-restart") return;
event.messages.push("Gateway restart expected soon. Save your work if needed.");
}That is the right mental model. Tiny unit, explicit trigger, narrow side effect.
How to inspect and enable hooks
The CLI side is intentionally small. You list, inspect, check, and enable.
openclaw hooks list
openclaw hooks info session-memory
openclaw hooks check
openclaw hooks enable session-memoryThe docs also note an important detail: workspace hooks are disabled by default until you enable them. That is a healthy default because it keeps stray hook folders from becoming surprise production behavior.
The real risk: fragile hook chains
Hooks go wrong when people treat them like a secret workflow engine.
One hook sets a file. Another hook expects the file. A third hook reads that file and sends a message. Then someone forgets which event fires first, a restart lands in the middle, and now you are debugging invisible plumbing at 11:40 p.m. That is not automation. That is a treasure hunt with worse lighting.
The biggest failure patterns are:
- multiple hooks depending on undocumented ordering
- business logic hiding inside event reactions
- side effects that are hard to observe or test
- hooks that grow until they should have been a plugin or TaskFlow job weeks ago
How to keep hooks maintainable
Small hooks age well. Clever hook systems do not.
- Keep one hook focused on one event job. If it needs a diagram to explain, shrink it.
- Prefer explicit names.
restart-warningis better thangateway-helper. - Document requirements in HOOK.md. Missing binaries, env vars, or config should never be a guessing game.
- Use hooks for reactions, not orchestration. If work has waits, retries, and dependent stages, move it to TaskFlow.
- Use plugins for deeper behavior. If you need typed plugin hooks like
before_tool_callorbefore_agent_finalize, stop pretending a simple hook is enough. - Make disabling safe. A good hook can be turned off without breaking the rest of the system.
When hooks are the right answer
Choose hooks when the trigger is already inside OpenClaw and the reaction is small, local, and event-shaped.
- Use a hook for lightweight event reactions.
- Use cron when the trigger is time.
- Use TaskFlow when the work becomes a multi-step durable run.
- Use a plugin when the behavior needs deep, reusable integration.
That sorting rule saves a lot of pain. Hooks are not the star of the show. They are the neat stagehands who move one chair at exactly the right moment and then disappear.
Need help from people who already use this stuff?
Trying to automate reactions without building a mess?
Join My AI Agent Profit Lab if you want help deciding when a hook is enough, when a plugin is smarter, and when a workflow should take over.
FAQ
What is a hook in OpenClaw?
A hook is a small script that runs when a specific Gateway event happens, such as /new, message receipt, compaction, or gateway startup. It is the lightest built-in way to react to events without building a full plugin.
What can trigger OpenClaw hooks?
Hooks can listen to command events, message events, session compaction events, session patch events, agent bootstrap, and gateway lifecycle events like startup, shutdown, and pre-restart. The exact list comes from the official automation hooks docs.
When should I use a hook instead of a plugin?
Use a hook when you need a small, focused reaction to an event inside one workspace or operator setup. Use a plugin when you need deeper in-process integration, richer lifecycle control, broader distribution, or reusable packaged behavior.
Are hooks the same as webhooks?
No. Internal hooks run inside OpenClaw when Gateway events fire. Webhooks are HTTP endpoints that outside systems call. They are both event-driven, but they solve different sides of the automation boundary.
What makes hook setups fragile?
Fragility usually comes from hidden dependencies, long chains of one hook depending on another, and hooks that try to carry business logic that belongs in a workflow, plugin, or normal agent instruction. Good hook setups stay small, explicit, and easy to disable.