Skip to content

☂️ [RFC] Umbrella package: unified import surface for common packages #82

@sdougbrown

Description

@sdougbrown

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions