Skip to content

Scope @webjsdev/ui to WebJs apps: drop the project-type detection #1129

Description

@vivek7405

Problem

@webjsdev/ui markets itself as working across Next, Astro, Vite, SvelteKit, Lit, and plain
HTML. The support behind that claim is thinner than the claim, and part of it is simply false.

packages/ui/src/utils/detect-project.js reads package.json and classifies the host project
as one of webjs / next / vite / astro / plain. Lit and SvelteKit are not detected at
all
(both fall through to plain) even though packages/ui/README.md L84 and the docs name
Lit explicitly. What the detection actually decides is two fields written into components.json
at init time: the tailwind.css path and the aliases map. That is the entire extent of
cross-framework support. There is no per-framework import rewriting, no per-framework component
variant, nothing else in the package branches on project type.

So the kit carries a cross-framework promise, a maintenance surface, and a test surface, in
exchange for ~30 lines that pick default paths. The decision is to stop making the promise:
@webjsdev/ui is the component library for WebJs apps. Anyone using it elsewhere can still
point --css and hand-edit components.json, but that is not a supported, tested, or
advertised path.

The website copy was already corrected in #1099 (see website/app/ui/page.ts). This issue is
the package side.

Design / approach

Delete the project-type concept from the package rather than narrowing it. A detectProject()
that only ever returns 'webjs' is a worse artifact than no detection: it keeps the abstraction
and the tests while removing the reason for them.

  1. Delete packages/ui/src/utils/detect-project.js and its re-export.
  2. Inline the WebJs defaults at the one place that consumed them (init), as plain constants.
  3. Drop the Project line from webjsui info, which is the only other consumer.
  4. Correct every doc surface that advertises cross-framework support.

Keep components.json itself unchanged in shape. Existing installs read their values from the
file, so nothing recomputes paths on an already-initialised project and no migration is needed.

Implementation notes (for the implementing agent)

Where to edit:

  • packages/ui/src/utils/detect-project.js (whole file, 63 lines): detectProject() L10-25 and
    defaultsForProject() L32-63. Delete.
  • packages/ui/src/utils/index.js L2: export { detectProject, defaultsForProject } from './detect-project.js';. Remove.
  • packages/ui/src/commands/init.js: L5 imports defaultsForProject, L23 calls it, and
    defaults.tailwindCss is read at ~L28 (the answers.css default) and again at ~L44 (the
    prompts initial value). Replace with the WebJs values that defaultsForProject returned for
    case 'webjs': tailwindCss: 'styles/globals.css' and
    aliases: { components: 'components', utils: 'lib/utils', ui: 'components/ui', lib: 'lib' }.
    Note the comment already on that branch: styles/globals.css, NOT app/globals.css, because
    app/ is routing-only in WebJs. Preserve that reasoning in the new constant.
  • packages/ui/src/commands/info.js: L5 import, L15 const { type } = detectProject(cwd), L19
    prints Project ${type}. Drop the line (the remaining diagnostics, cwd / registry /
    config / base color / css / aliases, are the useful ones).

Landmines / gotchas:

  • The aliases mismatch is real and predates this issue. defaultsForProject() returns
    utils: 'lib/utils', but the scaffold (packages/cli/lib/create.js ~L173-188) writes
    utils: 'lib/utils/cn', with a comment explaining that get-config.js appends '.ts' so the
    alias has to resolve to lib/utils/cn.ts. Those two disagree today. Decide which is correct
    for a WebJs app and make the one remaining default match the scaffold, rather than copying the
    stale value across. Check packages/ui/src/utils/get-config.js for the + '.ts' behaviour
    before choosing.
  • @webjsdev/ui is a published package, so this needs a version bump and a changelog entry,
    and @webjsdev/cli hard-depends on it. Do not bump in the same PR as unrelated work.
  • The @webjsdev/ui changelog historically over-attributes commits from the non-published
    nested website sub-app. Hand-trim on release.
  • This is a behaviour change for non-WebJs users on init (a Next project would now get
    styles/globals.css instead of app/globals.css). Acceptable per the scoping decision, but
    call it out in the changelog as such rather than filing it under "internal".

Invariants to respect:

  • packages/ is plain .js with JSDoc. Never add .ts there (AGENTS.md, "Working in the WebJs
    framework repo itself").
  • AGENTS.md invariant 11 (prose punctuation and WebJs brand casing) applies to every doc line
    touched.

Tests + docs surfaces:

  • Delete packages/ui/test/detect-project.test.js (whole file, it tests only this).
  • packages/ui/test/coverage-extras.test.js L11 import and the detectProject cases at L17-60.
  • packages/ui/test/branch-coverage.test.js L10 import and the cases at L25-62.
  • Add or extend an init test asserting the emitted components.json carries the WebJs defaults,
    so deleting the indirection does not silently change what init writes. That is the
    counterfactual: change a default value and this test must red.
  • packages/ui/README.md L84 ("init auto-detects your project type (Next / Astro / Vite / Lit /
    plain)"), npm-visible.
  • packages/ui/AGENTS.md L104 (module map entry), L110 (test list), L352 and L357 (test prose).
  • packages/cli/README.md L53 and L63 if they carry the same framing.
  • The skill at .agents/skills/webjs/ if any reference mentions cross-framework ui support.
  • The docs site page for the kit (website/app/ui/page.ts) was already corrected in seo: serve the UI gallery at webjs.dev/ui with the marketing site chrome #1099;
    re-check it still matches after this lands.

Acceptance criteria

  • detect-project.js and its re-export are gone, with no remaining importer
  • webjsui init writes the same components.json for a WebJs app as it does today, proven by a test
  • The utils alias default agrees with what webjs create scaffolds, or the divergence is deliberate and documented
  • webjsui info no longer prints a project type
  • No doc surface claims Lit, SvelteKit, Next, Astro, or Vite support
  • A counterfactual proves the new init defaults test actually fires
  • Tests cover the changed behaviour, and the deleted tests are removed rather than skipped

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions