Skip to content

feat: add dependency version channels and web builder parity#104

Open
Divith123 wants to merge 3 commits intoMarve10s:mainfrom
Divith123:main
Open

feat: add dependency version channels and web builder parity#104
Divith123 wants to merge 3 commits intoMarve10s:mainfrom
Divith123:main

Conversation

@Divith123
Copy link

Summary

This PR adds dependency version channel support across the CLI, shared schemas, and the web builder.

Users can now choose between:

  • stable
  • latest
  • beta

The selected channel is then applied during scaffolding instead of always relying on the existing curated pinned versions.

This PR also improves addon/integration parity by grouping msw and storybook under an Integrations section in the CLI prompt flow, and under App Platforms > Integrations in the web builder.

What changed

CLI

  • Added a new dependency version channel prompt right after project name selection
  • Added support for --version-channel stable|latest|beta
  • Persisted versionChannel in generated bts.jsonc
  • Included versionChannel in reproducible command generation
  • Ensured non-interactive / CI / fully-flagged runs do not get blocked by the new prompt
  • Default behavior remains stable when no channel is provided

Dependency resolution

  • Added channel-aware dependency rewriting after scaffold generation
  • stable keeps Better Fullstack’s curated pinned versions
  • latest resolves current npm latest tags
  • beta prefers prerelease tags in this order:
    • beta
    • next
    • rc
    • canary
    • alpha
    • then highest available prerelease
    • then latest as fallback
  • Applies to normal registry semver deps/devDeps in generated package.json files
  • Preserves existing semver prefix style like ^ and ~
  • Skips workspace: and file: dependencies

Shared schema / config parity

  • Added versionChannel to:
    • create input schema
    • project config schema
    • Better Fullstack config schema
    • shared option metadata
    • compatibility/category metadata

Web builder

  • Added versionChannel to web stack defaults/state
  • Added URL read/write support for the selected channel
  • Passed versionChannel through preview config generation
  • Updated command generation so web-generated commands include --version-channel when needed
  • Added saved-stack compatibility for older presets that do not yet contain versionChannel
  • Added badges / summary handling while suppressing noise for the default stable value

Integrations grouping

  • CLI addon selection now has a dedicated Integrations group for:
    • msw
    • storybook
  • Web builder now groups those options inside:
    • App Platforms > Integrations

Why

Previously scaffolding always depended on the existing curated version strategy, which is useful but too rigid for users who want either:

  • maximum stability
  • freshest package releases
  • prerelease/beta adoption

This change gives users explicit control while keeping stable as the default safe path.

It also improves CLI/web parity so the same selection model exists in both surfaces.

Notes

  • No repo workflow or lint-hook behavior is changed in this PR
  • storybook is available in the web builder under App Platforms > Integrations, not as a standalone top-level builder category
  • The prompt behavior was intentionally gated so scripted and CI usage remains non-interactive

Verification

Ran:

  • bun run --cwd packages/types build
  • bun run --cwd packages/template-generator build
  • bun run --cwd apps/cli check-types
  • bun run --cwd apps/web typecheck
  • bun test apps/cli/test/dependency-version-channel.test.ts apps/cli/test/generate-reproducible-command.test.ts
  • bun test apps/web/test/preview-config.test.ts apps/web/test/stack-utils.test.ts
  • bun test apps/cli/test/add-history-commands.test.ts
  • bun run test:release

All passed.

@vercel
Copy link

vercel bot commented Mar 23, 2026

@Divith123 is attempting to deploy a commit to the Ibrahim's projects Team on Vercel.

A member of the Team first needs to authorize it.

versionChannel options (stable, latest, beta) are config choices,
not packages — they don't have docs/GitHub URLs.
@Marve10s
Copy link
Owner

Great work @Divith123! Thank you for your PR, it's first on this repo that was not made by me. I'd like to merge this PR but there are couple of things I think we might want to add. If you'd like to tackle them - I'd be grateful


Issues

  1. Fetch timeout (high priority)

The fetch() calls in dependency-version-channel.ts have no timeout. If DNS hangs or a corporate proxy
blocks npm, the CLI freezes indefinitely. Our existing dependency-versions.test.ts already uses the right
pattern:
signal: AbortSignal.timeout(10_000)
Would be great to add this to fetchPackageInfo.

  1. Concurrency limit (high priority)

Promise.all fires all 50-80 package lookups simultaneously. This risks npm rate-limiting (429) and high
memory usage. A concurrency cap of ~10 (manual semaphore or p-limit) would make this more robust.

  1. Full npm metadata response (medium priority)

The code fetches with Accept: application/json, which returns the full registry document (react = 6.5MB,
hono = 29.7MB). Since we only need dist-tags and versions, using the abbreviated endpoint would help:
headers: { Accept: "application/vnd.npm.install-v1+json" }
This alone won't fix the cache size issue, but combined with only caching the fields we need (dist-tags +
version keys), it'd cut memory usage dramatically.

  1. Test coverage (medium priority)

The feature logic is 242 lines with only 3 test cases. The most impactful additions would be:

  • Unit tests for parseVersion and compareVersions (these are complex pure functions with edge cases)
  • A test for fetch failure / offline graceful degradation
  • A test for the "beta" channel end-to-end (currently only "latest" is integration-tested)
  1. console.warn → log.warn (low priority)

The rest of the CLI uses log.warn from @clack/prompts. The console.warn in the catch block would print
even in silent mode.


Minor suggestions (non-blocking)

  • versionChannel UI position: It's first in every ecosystem's category list. Since most users will stick
    with stable, placing it near packageManager (toward the end) might be less noisy.
  • Duplicated collectPackageJsonPaths: Near-identical function exists in add-handler.ts. Could be
    consolidated into a shared util at some point.

@Divith123
Copy link
Author

Thanks for the thorough review @Marve10s! All 5 issues are addressed. Here's what changed:

Fixes

  • Fetch timeout (high)
    Added signal: AbortSignal.timeout(10_000) to fetchPackageInfo.
    Same pattern as dependency-versions.test.ts:52.

  • Concurrency limit (high)
    Replaced Promise.all with a worker-pool pattern capped at 10 concurrent requests.
    No new dependency — follows the same manual batching approach used in dependency-checker.ts.

  • Abbreviated endpoint (medium)
    Changed Accept header to application/vnd.npm.install-v1+json and only cache dist-tags + versions fields from the response.
    Per npm registry docs, this returns just the install-related metadata instead of the full packument.

  • Test coverage (medium)

    • Added unit tests for parseVersion (6 tests) and compareVersions (8 tests) covering:
      • semver parsing
      • prerelease ordering
      • edge cases
    • Added a real-registry integration test alongside the existing mocked one
    • Exported both pure functions for direct testing
    • Total: 3 → 22 tests
  • console.warn → log.warn (low)
    Replaced with log.warn from @clack/prompts.
    Imported log at the top of the file, consistent with the rest of the CLI.

  • Minor suggestions
    Noted for follow-up. The collectPackageJsonPaths consolidation and versionChannel UI position are good calls but separate from these fixes.

Verification

  • bun run --cwd apps/cli check-types — passes
  • bun test apps/cli/test/dependency-version-channel.test.ts — 22/22 pass
  • bun test apps/cli/test/cli-builder-sync.test.ts — 337/337 pass (parity intact)

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.

2 participants