UsefulKey
Plugins

Plugin composition patterns

Ordering, performance considerations, and patterns for composing multiple plugins.

Ordering

  • Plugins run in the order they are provided to usefulkey(..., { plugins }).
  • Early beforeVerify hooks can short-circuit later work by returning { reject: true, reason }.

Performance considerations

  • Each plugin may perform store reads independently. This can lead to multiple reads per verification.
  • Mitigations:
    • Keep the plugin set minimal for your use case.
    • Prefer low-latency stores in production (Redis/SQL near the app).
    • Consider caching common reads in your own layer.

Example composition

const uk = usefulkey({}, { plugins: [
  ratelimit({ default: { kind: 'fixed', limit: 100, duration: '1m' } }),
  ipAccessControlStatic({ allow: ['127.0.0.1'] }),
  permissionsScopesPlugin({ metadataKey: 'scopes' }),
  usageLimitsPerKeyPlugin(),
]});

Recommendations:

  • Put cheap, high-signal blockers first (IP deny, enable/disable) to short-circuit fast.
  • Follow with policy checks (scopes), then usage counters that may update state.

Request-scoped context (roadmap)

  • Future versions may expose a shared, per-request context to reduce duplicate reads across plugins.