Lightweight, type-safe, zero-dependency awaitable hook system.
Important: Keep AGENTS.md updated with project info.
- Type: ESM-only (
"type": "module") - Runtime deps: None
- Bundle size: Hookable < 3KB, HookableCore < 630B gzipped
Two classes:
Hookable<HooksT>β Full-featured: deprecation chains, beforeEach/afterEach spies, serial & parallel executionHookableCore<HooksT>β Minimal: onlyhook(),removeHook(),callHook()(~630B)
src/
βββ index.ts # Public exports
βββ types.ts # TypeScript type definitions (generics, inference)
βββ hookable.ts # Hookable & HookableCore classes
βββ utils.ts # flatHooks, mergeHooks, callers (serial/parallel)
βββ debugger.ts # createDebugger utility
// Classes
export { Hookable, HookableCore, createHooks }
// Utilities
export { flatHooks, mergeHooks, parallelCaller, serial, serialCaller }
// Debugger
export { createDebugger }Setup: eval "$(fnm env --use-on-cd 2>/dev/null)" then pnpm install
| Command | Purpose |
|---|---|
pnpm build |
Build with obuild (esbuild) |
pnpm dev |
Vitest watch mode |
pnpm test |
Lint + vitest with coverage |
pnpm lint |
oxlint + oxfmt check |
pnpm lint:fix |
Auto-fix lint/format |
pnpm test:types |
Type check with tsgo |
pnpm bench |
Benchmarks with mitata |
pnpm release |
test β build β changelogen release |
- Framework: Vitest
- Tests:
test/hookable.test.ts,test/types.test.ts,test/debuger.test.ts,test/bundle.test.ts - Run single:
pnpm vitest run test/hookable.test.ts - Uses
expectTypeOffor type-level assertions - Bundle size enforced in
test/bundle.test.ts
- ESM with explicit
.tsextensions in imports - No barrel files β import directly from modules
- Internal helpers at end of file
- Multi-arg functions use options object as 2nd param
- Constructor binds
hook,callHook,callHookWithfor safe destructuring - Unregister functions nullify references for GC cleanup
console.createTask()support for DevTools stack traces
- Linter: oxlint (config:
.oxlintrc.json) - Formatter: oxfmt (config:
.oxfmtrc.json)
- Builder: obuild β
dist/index.mjs+dist/index.d.mts - TypeScript: ESNext target, NodeNext modules, strict,
isolatedDeclarations - CI: GitHub Actions β lint β type check β test + coverage β codecov
- Release:
changelogen --release --publish --push - Only
dist/published to npm