Skip to content

fix(core): publish a built @getworkbench/core/ui entrypoint - #50

Open
omarzeineddine-ai wants to merge 5 commits into
pontusab:mainfrom
omarzeineddine-ai:fix/core-ui-export
Open

fix(core): publish a built @getworkbench/core/ui entrypoint#50
omarzeineddine-ai wants to merge 5 commits into
pontusab:mainfrom
omarzeineddine-ai:fix/core-ui-export

Conversation

@omarzeineddine-ai

Copy link
Copy Markdown

Problem

Closes #32

The ./ui and ./ui/styles.css exports point at ./src/ui/... files, but only dist is in the package's files list — so the README-documented import { Dashboard } from "@getworkbench/core/ui" can never resolve from the npm tarball:

Cannot find module .../node_modules/@getworkbench/core/src/ui/index.ts

Even if src were published, the entry wouldn't be consumable: the UI source uses package-internal @/ aliases and a raw Tailwind stylesheet that a consumer's bundler can't process.

Solution

Ship the entrypoint built, per option 2 in the issue:

  • New vite.lib.config.ts bundles src/ui/index.tsdist/ui-lib/index.js (ESM) plus the compiled Tailwind stylesheet dist/ui-lib/styles.css. Only react/react-dom are external — the Dashboard brings its own router and query client — so embedding apps just need React, declared as optional peer dependencies (server-only consumers stay warning-free).
  • tsup gains a dts-only entry emitting dist/ui-lib/index.d.ts. The public createAppRouter re-export is typed opaquely so the shipped declarations don't reference @tanstack/react-router/zod (bundled, not installed by consumers); the d.ts imports nothing but react/jsx-runtime and typechecks under skipLibCheck: false.
  • Export map now points ./ui and ./ui/styles.css at the built files.
  • Lazy router creation in app.tsx: TanStack's createRouter touches window.history at module scope, which crashed any non-browser import of the entry — including the issue's exact node -e repro and SSR frameworks like TanStack Start. The router is now created on first render.
  • Desktop app keeps building the dashboard from source (with HMR) via an explicit vite alias instead of relying on the export map pointing at src.
  • Regression test: every export target in package.json must point into dist/, the only published code directory.

Verification

Against a real npm pack tarball installed into a fresh consumer app:

  • node -e "import('@getworkbench/core/ui')" (the issue's repro) succeeds; all documented exports present; ./ui/styles.css resolves.
  • A consumer .tsx rendering <Dashboard /> typechecks with skipLibCheck: false.
  • Tarball contains dist/ui-lib/{index.js,index.d.ts,styles.css} and no src/ files.
  • bun test (18 pass), tsc --noEmit, biome on changed files, full core build, and the desktop app's build + typecheck all pass.

Note: the lib bundle is ~480 KB gzipped since the Dashboard is self-contained (router, query client, charts, flow renderer). Only apps importing /ui pay that cost.

The desktop app relies on building the dashboard from source (its alias
map already reaches into packages/core/src for the UI's internal @/
imports). Make that source resolution explicit instead of depending on
the package export map pointing at src, so the export map can move to
built dist files for published consumers.
TanStack's createRouter touches window.history, so building the router
at module scope crashed any non-browser import of the embeddable
@getworkbench/core/ui entry (SSR frameworks evaluate the module on the
server before rendering client-side). Defer creation to first render.
The ./ui and ./ui/styles.css exports pointed at src/ files, but only
dist/ is in the published files list, so the README-documented
'import { Dashboard } from "@getworkbench/core/ui"' could never
resolve from the npm tarball.

Build the entrypoint into the package instead:

- vite.lib.config.ts bundles src/ui/index.ts to dist/ui-lib/index.js
  (ESM) plus the compiled Tailwind stylesheet dist/ui-lib/styles.css.
  Only react/react-dom are external — the Dashboard brings its own
  router and query client — so embedding apps just need React, declared
  as optional peer dependencies to keep server-only consumers
  warning-free.
- tsup gains a dts-only entry for dist/ui-lib/index.d.ts. The public
  createAppRouter re-export is typed opaquely so the declarations don't
  reference @tanstack/react-router or zod, which are bundled rather
  than installed by consumers.
- The export map now points ./ui and ./ui/styles.css at the built
  files.

Closes pontusab#32
Regression test for pontusab#32: every package.json export target must point
into dist/, the only code directory included in the published tarball.
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

@omarzeineddine-ai is attempting to deploy a commit to the Pontus Abrahamsson's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@getworkbench/core/ui Dashboard export points to missing src/ui files

1 participant