Motivation
The scoped @umpire/* package boundaries are correct by design, but new consumers face a discovery and setup cost. An umbrella package that re-exports the most common subset would lower that bar without changing the architecture of any existing package.
Proposed re-export surface
| Sub-package |
Include? |
Notes |
@umpire/core |
✅ |
Foundation — always |
@umpire/store |
✅ |
Needed for any subscription adapter |
@umpire/json |
✅ |
Common enough to bundle |
@umpire/devtools |
✅ |
Zero-config debugging; tree-shakes in prod |
@umpire/reads |
✅ |
Utility layer used alongside core |
@umpire/testing |
❌ |
Dev-only; consumers add separately |
@umpire/zod |
❌ |
Adds a peer dep; opt-in via @umpire/zod |
@umpire/react |
❌ |
Framework peer dep; use @umpire/react |
@umpire/signals |
❌ |
Same |
@umpire/solid |
❌ |
Same |
@umpire/zustand / redux / pinia / vuex |
❌ |
Same |
All exports are named re-exports with no additional runtime logic. The package sets "sideEffects": false.
Build
Mirror the core/react/solid tsdown pattern exactly:
- Formats: ESM + IIFE
- IIFE globalName: TBD (e.g.
Umpire)
- IIFE strategy: bundle all included sub-packages inline (no
neverBundle / no external globals needed — this is the one place where a fully self-contained drop-in makes sense)
- ESM: named re-exports, tree-shakeable by bundlers
- Outputs:
dist/index.js (ESM), dist/index.browser.js (IIFE), minified with sourcemaps
- Types: single rolled
dist/index.d.ts
tsdown.config.ts skeleton:
import { defineConfig } from 'tsdown'
export default defineConfig([
{
entry: { index: 'src/index.ts' },
format: 'esm',
platform: 'browser',
dts: { merged: true },
},
{
entry: { 'index.browser': 'src/index.ts' },
format: 'iife',
platform: 'browser',
globalName: 'Umpire', // placeholder — resolve at implementation time
minify: true,
sourcemap: true,
dts: false,
},
])
Versioning / changesets
- The umbrella package gets its own version.
- A
@umpire/core bump (minor or major) must trigger a bump of the umbrella. Add the umbrella to a linked group in .changeset/config.json alongside core, or ensure CI enforces a changeset entry whenever core changes.
updateInternalDependencies: "minor" (already set) covers the automatic dep-range updates for the included sub-packages.
Open questions
- Package name
- Whether
@umpire/reads belongs in or out
- IIFE global name
Motivation
The scoped
@umpire/*package boundaries are correct by design, but new consumers face a discovery and setup cost. An umbrella package that re-exports the most common subset would lower that bar without changing the architecture of any existing package.Proposed re-export surface
@umpire/core@umpire/store@umpire/json@umpire/devtools@umpire/reads@umpire/testing@umpire/zod@umpire/zod@umpire/react@umpire/react@umpire/signals@umpire/solid@umpire/zustand/redux/pinia/vuexAll exports are named re-exports with no additional runtime logic. The package sets
"sideEffects": false.Build
Mirror the
core/react/solidtsdown pattern exactly:Umpire)neverBundle/ no external globals needed — this is the one place where a fully self-contained drop-in makes sense)dist/index.js(ESM),dist/index.browser.js(IIFE), minified with sourcemapsdist/index.d.tstsdown.config.tsskeleton:Versioning / changesets
@umpire/corebump (minor or major) must trigger a bump of the umbrella. Add the umbrella to alinkedgroup in.changeset/config.jsonalongsidecore, or ensure CI enforces a changeset entry whenevercorechanges.updateInternalDependencies: "minor"(already set) covers the automatic dep-range updates for the included sub-packages.Open questions
@umpire/readsbelongs in or out