Skip to content

Angular: Raise the supported floor to 21 - #36166

Merged
valentinpalkovic merged 20 commits into
nextfrom
feat/angular-21-floor
Sep 7, 2026
Merged

valentinpalkovic merged 20 commits into
nextfrom
feat/angular-21-floor

Conversation

@obvious-autobuild

@obvious-autobuild obvious-autobuild Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

Why

Angular 21 is the SB11 minimum, and @storybook/angular still advertises >=18.0.0 peers — two majors behind @storybook/angular-vite. A webpack-framework project on Angular 18–20 installs cleanly today and breaks only at runtime, because the upgrade-time blocker also stops at 18. The floor has to agree everywhere: package metadata, the upgrade blocker, and the last version-conditional code path.

What

  • Peers (code/frameworks/angular/package.json): all Angular-related peers rise to >=21.0.0 < 23.0.0 — @angular-devkit/architect gets the devkit form >=0.2100.0 < 0.2300.0. rxjs keeps Angular 21's own peer range ^6.5.3 || ^7.4.0 (every @angular/core@21.x release declares exactly that on the npm registry), so @storybook/angular is never stricter than the framework it integrates. One intentional asymmetry: @storybook/angular tracks Angular's own RxJS range, while @storybook/angular-vite remains RxJS-7-only (^7.4.0). Every Angular-related shared peer still uses the exact string @storybook/angular-vite publishes, so the two packages can't drift apart again. (The typescript peer intentionally differs — the webpack framework's ^4.9.0 || ^5.0.0 || ^6.0.0 predates this change and is untouched here.)
  • Upgrade blocker (code/lib/cli-storybook/src/autoblock/block-dependencies-versions.ts): @angular/core minimum goes 18.0.0 → 21.0.0. The message stays in the existing style ("Support for Angular < 21 has been removed.") and now links the new MIGRATION.md#angular-requires-angular-21-or-higher anchor instead of the generic angular.dev guide. --force bypass is untouched — it's the pre-existing !options.force gate in collectProjects, not blocker logic.
  • PropertyExtractor: the >= 19 runtime check for the standalone default collapses to the constant true (the floor guarantees it), and the now-unused VERSION import goes with it. The two matching VERSION.major >= 21 defaults for experimentalZoneless in the webpack builders (build-storybook / start-storybook) collapse to true the same way, so the package carries one semantics: under the 21 floor, zoneless is always supported as the default, and an explicit experimentalZoneless: false in a project's options still wins.
  • Automigration audit (D5): none of the three Angular fixes is removed. angular-to-angular-vite is forward-looking (it already requires Angular ≥ 21 and skips below it), angular-vite-remove-compodoc only runs for the @storybook/angular-vite framework, and angular-workspace.ts is a shared helper module, not a registered fix. No fix here exists solely for a pre-21 behavior.

How to Review

  • code/frameworks/angular/package.json and code/lib/cli-storybook/src/autoblock/block-dependencies-versions.ts are the behavioral core; the rest is docs and the dead branch cleanup.
  • New unit test block-dependencies-versions.test.ts covers 20 → blocked (with title, message, and the exact MIGRATION.md anchor), 21/22 → pass, and missing-package → pass.
  • The peer strings intentionally keep the spaced < 23.0.0 format to match angular-vite byte-for-byte.
  • Pre-existing lint noise: PropertyExtractor.ts carries 8 oxlint warnings that exist on the base commit too; this change adds none.

Test Evidence

  • Autoblock suite: 32 tests, 4 files, all green (including the new floor test).
  • @storybook/angular suite: 187 tests, all green.
  • Peer-range consistency check between @storybook/angular and angular-vite passes programmatically (Angular-related peers).
  • devDependencies at the supported minimum per review (@angular/* ^21.0.0, devkit ^0.2100.0, zone.js ^0.16.0), so the suite runs against a supported Angular; yarn.lock resynced and yarn install --immutable passes.
  • Visual evidence not applicable — no rendered UI, visual state, or interactive workflow changes.

Manual testing

This PR changes package metadata, the upgrade blocker, docs, and one dead code path — there is no rendered UI to exercise by hand. To verify manually:

  • Upgrade blocker: in an Angular workspace on @angular/core@20, run storybook upgrade — it stops with "Angular 21 support removed", linking the migration guide; rerunning with --force proceeds. On @angular/core@21 or 22, no blocker appears.
  • Peer range: in a scratch project, install @angular/core@20 and then @storybook/angular@canary — the package manager reports unresolvable peers; with @angular/core@21 it installs cleanly.
  • Docs: MIGRATION.md shows the new "Angular: Require v21 and up" entry under "From version 10.x to 11.0.0" (alongside the Vitest 4 and Vite 5/6 entries that landed on next independently), with a matching TOC link.

🔗 Obvious Project · 🧵 Obvious Thread

@obvious-autobuild
obvious-autobuild Bot marked this pull request as ready for review September 3, 2026 19:24
@obvious-autobuild obvious-autobuild Bot added maintenance User-facing maintenance tasks ci:normal Run our default set of CI jobs (choose this for most PRs). qa:skip Pull Requests that do not need any QA. (e.g. documentation) labels Sep 3, 2026
@obvious-autobuild
obvious-autobuild Bot force-pushed the feat/angular-21-floor branch from 41a873d to 083b5b6 Compare September 3, 2026 19:35
Comment thread code/lib/cli-storybook/src/autoblock/block-dependencies-versions.ts Outdated
Comment thread code/lib/cli-storybook/src/autoblock/block-dependencies-versions.ts Outdated
Comment thread MIGRATION.md Outdated
Comment thread code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.ts Outdated
Comment thread code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.ts Outdated
Comment thread yarn.lock Outdated
@valentinpalkovic
valentinpalkovic force-pushed the release/raise-framework-floors-drop-cra-support-deprecate-storybooknextjs-20260903-190632 branch from 1dbb4fe to 1eed720 Compare September 3, 2026 22:01
obvious-autobuild Bot pushed a commit that referenced this pull request Sep 3, 2026
…ad after backoff

Attempt 5 of the flaky benchmark-packages BigQuery upload (4 failures / 1 success over 2.5h today, repo-wide per PR #36166). Retrying after a ~25-minute backoff per the error's own guidance.
@obvious-autobuild
obvious-autobuild Bot force-pushed the feat/angular-21-floor branch from 2a7513a to d5b7e73 Compare September 4, 2026 12:34
@storybook-app-bot

storybook-app-bot Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Package Benchmarks

Commit: f7725f5, ran on 7 September 2026 at 07:56:24 UTC

No significant changes detected, all good. 👏

@obvious-autobuild
obvious-autobuild Bot changed the base branch from release/raise-framework-floors-drop-cra-support-deprecate-storybooknextjs-20260903-190632 to next September 4, 2026 14:52
@valentinpalkovic

Copy link
Copy Markdown
Contributor

@ObviousApp Resolve conflicts

@obvious-autobuild
obvious-autobuild Bot force-pushed the feat/angular-21-floor branch from d5b7e73 to 44ce3b3 Compare September 4, 2026 15:00
@obvious-autobuild

Copy link
Copy Markdown
Contributor Author

Replying to this comment

Done — the branch is rebuilt on next. feat/angular-21-floor now carries only the 13 PR commits (verified via git log --oneline origin/next..HEAD): no release-setup commit 1dbb4fe85b6, no sync-merges, and no #36162 Vite-floor content in the diff (git diff origin/next...HEAD --stat shows exactly the 6 deliverable files: code/frameworks/angular/package.json, the autoblock map + test, PropertyExtractor.ts, MIGRATION.md, yarn.lock).

Two MIGRATION.md conflicts resolved against nexts current state: the "From version 10.6.0 to 11.0.0" section is now "10.x" carrying the Vitest 4 / Vite 5/6 entries that landed independently, with the Angular entry appended under it. I also corrected the docs RxJS bullet to the restored peer range ^6.5.3 || ^7.4.0 (the reviewed text still claimed ^7.4.0, which no longer matched package.json after your RxJS decision), and kept your simplified standalone bullet.

Pushed with --force-with-lease; head is 44ce3b3e7cae08d2e130529897773b5860db5d6. Local verification green on the rebased branch: autoblock suite 4 passed, @storybook/angular suite 187 passed / 11 skipped, no type errors. Danger JS succeeds against the new base; full CI is re-running against next.

Replying to this comment

@obvious-autobuild obvious-autobuild Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obvious Code Review

Verdict: COMMENT (2 Medium findings — advisory, non-blocking)

Review of the canonical patch at head 44ce3b3 (includes the RxJS ^6.5.3 arm restore). All prior maintainer feedback from valentinpalkovic verified applied — none re-raised.

Medium

  • code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.ts:185 — the new 21 floor also makes two sibling VERSION.major >= 21 checks constant-true in the builders; the PR body's "last version-conditional code path" claim doesn't hold
  • code/frameworks/angular/package.json:100 — devDependencies still pin Angular ^19.1.1, below the floor this PR enforces; the reported green test suite ran against an unsupported Angular

Suggestions

  • code/frameworks/angular/package.json:105 — typescript peer (^4.9.0 || ^5.0.0 || ^6.0.0) drifts from angular-vite's >= 5.9.x, contrary to the PR body's byte-for-byte claim

Verified clean: upgrade-blocker flow (semver.lt boundaries at 20/21/22, missing package, --force untouched), MIGRATION.md anchor slug, RxJS range vs Angular 21's own peer, byte-for-byte shared-peer match vs angular-vite, VERSION import fully removed, new blocker test coverage, yarn.lock resync.


View full review in Obvious

Comment thread code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.ts Outdated
Comment thread code/frameworks/angular/package.json
@obvious-autobuild

Copy link
Copy Markdown
Contributor Author

Replying to this comment

Both Mediums addressed in 92a9c387578: devDependencies now match angular-vite's Angular 21 set (suite verified green against the floor), and the PR body no longer overclaims — the two builders' VERSION.major >= 21 checks are documented as deliberate below-floor force-install guards. On the typescript-peer suggestion: the drift is real but predates this PR and changing the webpack framework's TS floor is a support-policy decision outside this deliverable, so I scoped the body's byte-for-byte claim to Angular-related peers and left the peer untouched — flagging it for a maintainer call rather than expanding scope.

Replying to this comment

@obvious-autobuild obvious-autobuild Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obvious Code Review

Verdict: COMMENT (1 Medium finding — advisory)

Incremental pass at head a5a9dffbd3 (devDeps pinned to the supported minimum, builders' zoneless defaults collapsed).

Pass 1 findings — all resolved (verified)

  • Constant-true builder checks — both experimentalZoneless defaults collapsed to true, VERSION imports removed (no residual references), PR body now states one semantics with explicit-false still honored
  • devDependencies on Angular 19 — now ^21.0.0 (devkit ^0.2100.0, zone.js ^0.16.0) per maintainer request; Angular 19 subtree fully gone from yarn.lock
  • typescript peer drift — documented as intentional; byte-for-byte claim scoped to Angular-related peers

Medium

  • code/frameworks/angular/package.json:70 — @analogjs/vite-plugin-angular stays on the 1.x line: resolved 1.22.5, whose peer declarations stop at Angular 20 (optional peers, so yarn resolves silently). src/test-setup.ts runs all 187 tests through its setup-vitest against devkit 21.2.22 — a combination the plugin itself declares unsupported. The 2.x line is proven in-repo: angular-vite runs ^2.5.2 (2.6.1, peers ^17..^22 devkit, ^6..^8 vite) with the same setup-vitest import.

Verified clean: explicit experimentalZoneless: false preserved; no residual VERSION references; zone.js peers identical across both frameworks; workspace lock entry matches package.json; PR body accurate to the code.


View full review in Obvious

Comment thread code/frameworks/angular/package.json Outdated
@obvious-autobuild

Copy link
Copy Markdown
Contributor Author

Replying to this comment

The remaining Medium is fixed in b1d0af3230e (Analog bumped to the sibling-proven ^2.5.2, suite green on 2.6.1). One open question outside this review's scope: CircleCI's build--linux failed on a5a9dffbd3c — the logs aren't reachable with the credentials available here, so I'm reproducing the build locally while the fresh run on b1d0af3230e executes. If it reproduces, I'll fix it on this branch; if the fresh run passes, it was transient infrastructure.

Replying to this comment

@obvious-autobuild obvious-autobuild Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obvious Code Review

Verdict: COMMENT

Incremental pass at head b1d0af3230 (bump of @analogjs/vite-plugin-angular to ^2.5.2).

The Pass 2 Medium is resolved and verified: a single merged lock entry resolving 2.6.1 (the same resolution @storybook/angular-vite runs), zero 1.x residue, devkit 21.2.22 now inside the plugin's declared ^17..^22 peer envelope, and the full suite re-run green through the new setup-vitest harness. All findings from Passes 1–2 are now resolved and verified.

No findings — clean pass.


View full review in Obvious

@obvious-autobuild obvious-autobuild Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obvious Code Review

Verdict: COMMENT

Incremental pass at head e8857c1373 (yarn.lock dedupe to satisfy the build dedupe gate — the CircleCI fix from the prior head).

Verified: the dedupe is purely mechanical — within-range merges (the Angular descriptor families collapse onto the 21.2.22 resolutions both frameworks' ranges already allowed, which also removes the minor cross-framework version divergence noted earlier) plus pruning of stale orphaned exact-pin entries; the Angular workspace entry, analog 2.6.1, and zone.js 0.16.2 are untouched; no source changes. The queued CircleCI run on this head is the definitive gate check.

No findings — clean pass.


View full review in Obvious

Comment thread MIGRATION.md

@JReinhold JReinhold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved with minor feedback.

Comment thread code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.ts Outdated
Comment thread MIGRATION.md
@valentinpalkovic

Copy link
Copy Markdown
Contributor

@ObviousApp Resolve merge conflicts

ObviousApp and others added 20 commits September 7, 2026 07:43
…r 21 floor

Bump @angular/* devDependencies ^19.1.1 -> ^21.2.x (devkit ^0.2102.x,
build-angular ^21.2.12, zone.js ^0.16.2), matching @storybook/angular-vite,
so the package is developed and tested against a supported Angular. The
187-test suite now exercises the same major the peers advertise.
DevDependency ranges now express the floor the peers enforce:
@angular/* ^21.0.0, devkit architect ^0.2100.0, zone.js ^0.16.0.
The experimentalZoneless version checks in build-storybook and
start-storybook were constant-true under the 21 floor; both now default
to true, matching the PropertyExtractor collapse. Explicit
experimentalZoneless: false in project options is still honored.
The 1.x line's peer declarations stop at Angular 20 while both peers are
optional, so yarn silently pairs it with the Angular 21 toolchain this
package now develops against. ^2.5.2 (resolves 2.6.1) is the version
@storybook/angular-vite already runs and declares devkit peers ^17..^22.
The lockfile regeneration left 27 duplicate resolutions (Angular devkit,
compiler-cli, Babel core among them) that yarn install tolerates but
`yarn dedupe --check` rejects in the Build (linux) job.
The 11.0 breaking-change entries in MIGRATION.md double as the
changelog item titles but mixed title formats ("Dropped support for
...", "Require vN and up"). Consolidate them to the dominant
"Scope: <statement>" convention and update the table-of-contents
anchors to match. Body text is unchanged.

Replayed on top of the reverted next: the Next.js 15 section was
removed by the revert of #36167, so its title hunks are dropped.
The MIGRATION.md section title is now "Angular: requires Angular 21
or higher", so the anchor changed. Update the autoblock blocker link
and its test assertion so the link resolves instead of dangling.
Fold the separate `if (isStandalone === undefined)` fallback into the
declaration as `?? true` per review feedback. The `??` operand is
parenthesized because nullish coalescing cannot be mixed with `&&`
without parentheses; semantics are unchanged (false is not nullish).

Also link the Angular update guide (https://angular.dev/update-guide)
from the MIGRATION.md section, mirroring the Next.js section.
@obvious-autobuild
obvious-autobuild Bot force-pushed the feat/angular-21-floor branch from 74262eb to f7725f5 Compare September 7, 2026 07:47
@obvious-autobuild

Copy link
Copy Markdown
Contributor Author

Replying to this comment

Resolved — rebased feat/angular-21-floor onto the current next (reland of #36167 included) and force-pushed as f7725f5. Both conflicts stayed within the Angular deliverable: the autoblock test file is now the union of the reland's Next.js tests and my three Angular tests (7 passed locally, no type errors), and MIGRATION.md keeps the restored Next.js section verbatim alongside the Angular section and its TOC entry. Anchor #angular-requires-angular-21-or-higher is consistent across the autoblock implementation, test, and MIGRATION.md. CI is re-running on the new head.

@obvious-autobuild

Copy link
Copy Markdown
Contributor Author

Replying to this comment

Thanks! Both minor items are addressed at f7725f5: the standalone fallback is folded into the declaration ((…?.standalone ?? true), parenthesized since ?? cannot be mixed with && unparenthesized), and the Angular migration section now links the angular.dev update guide, mirroring the Next.js phrasing. The branch was also rebased onto the current next with the relanded Next.js 15 content preserved.

@valentinpalkovic
valentinpalkovic merged commit e2d68de into next Sep 7, 2026
152 checks passed
@valentinpalkovic
valentinpalkovic deleted the feat/angular-21-floor branch September 7, 2026 08:02
@github-actions github-actions Bot mentioned this pull request Sep 7, 2026
2 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal Run our default set of CI jobs (choose this for most PRs). maintenance User-facing maintenance tasks qa:skip Pull Requests that do not need any QA. (e.g. documentation)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants