# ADR-002: Sub-Path Exports + Peer Deps for Adapter Isolation **Status**: Accepted **Date**: 2026-04-30 ## Context Each event target adapter has different peer dependencies (ioredis for Redis, @rayhanadev/iroh for Iroh). Consumers that only use in-process or one adapter should not be forced to install peer deps for adapters they don't use. Two approaches: 1. **Barrel + tree-shaking** — single entry point, rely on bundler to drop unused adapters 2. **Sub-path exports** — explicit per-adapter entry points in `package.json` exports map Typemap uses barrel-only. Taskgraph uses plain barrel with no sub-path exports. ## Decision Use sub-path exports with optional peer dependencies. ## Rationale 1. **Explicit dependency declaration** — `import { createRedisEventTarget } from '@alkdev/pubsub/event-target-redis'` makes it clear at the import site that this module needs ioredis. A barrel import doesn't. 2. **No bundler reliance** — sub-path exports don't depend on the consumer's bundler correctly tree-shaking. Not all consumers use bundlers (Deno, Node with `--experimental-strip-types`). 3. **peerDependenciesMeta** — npm treats optional peer deps as install warnings, not errors. `npm install @alkdev/pubsub` installs only the core. `npm install @alkdev/pubsub ioredis` gets Redis support. 4. **Consistent with typemap's philosophy** — typemap's peer deps (zod, valibot, typebox) are each their own module island. Sub-path exports make this explicit at the package boundary. We're adding the package.json entry points that typemap doesn't have. 5. **Incremental** — adapters can be added one at a time. Each new adapter adds one entry to the exports map and one entry point to tsup. ## Consequences - More entries in `package.json` exports — maintenance burden scales with adapter count - Both barrel and sub-path work — barrel re-exports everything for convenience, sub-path for explicitness - tsup must list each adapter as a separate entry point - Consumer docs should recommend sub-path imports for adapter-specific code