Skip to content

chore: upgrade vite v7 -> v8#14359

Merged
sfc-gh-bnisco merged 3 commits intodevelopfrom
03-12-chore_upgrade_vite_v7_-_v8
Mar 16, 2026
Merged

chore: upgrade vite v7 -> v8#14359
sfc-gh-bnisco merged 3 commits intodevelopfrom
03-12-chore_upgrade_vite_v7_-_v8

Conversation

@sfc-gh-bnisco
Copy link
Copy Markdown
Collaborator

@sfc-gh-bnisco sfc-gh-bnisco commented Mar 13, 2026

Describe your changes

This PR upgrades the frontend workspace from Vite 7 to Vite 8 (and Vitest 4.0.x to 4.1.x), and applies the migration fixes needed for Streamlit’s build/dev/test flows.

One of the biggest benefits for this is perf.

  1. make frontend-fast is now 72% faster (50s -> 14s)
  2. Rolldown changes the way bundles are built and split, so now our entry file is 85% smaller
  3. Wheel size is 1.5% smaller
  • Upgraded Vite across frontend workspaces:
    • vite: ^7.3.1 -> ^8.0.0
    • @vitejs/plugin-react-swc: ^4.2.3 -> ^4.3.0
  • Upgraded Vitest-related deps:
    • vitest: ^4.0.18 -> ^4.1.0
    • @vitest/coverage-v8: ^4.0.18 -> ^4.1.0
  • Migrated Vite config keys from Rollup naming to Rolldown naming:
    • build.rollupOptions -> build.rolldownOptions in app, lib, connection, and component-lib
  • Updated app asset handling to match Vite 8/Rolldown output behavior:
    • CSS/media routing now uses assetInfo.names-based checks
    • Added renderBuiltUrl handling for CSS font URLs so emitted font paths stay stable (../media/...)
  • Added Vite 8 interop compatibility shims for mixed/CJS packages:
    • react-uid alias to local compat module
    • New compat wrappers for react-json-view and react-plotly.js to normalize nested default exports
    • Updated call sites (JSON, DataFrame JSON viewer, Plotly, related test imports) to consume compat modules
  • Added runtime guard for DeckGL/Luma canvas resize edge case:
    • Patch for CanvasContext.getMaxDrawingBufferSize() to avoid crashes when device.limits is temporarily unavailable
  • Adjusted BaseUI import pathing in theme creation to avoid interop/runtime issues under Vite 8
  • Updated knip ignore config for newly introduced compat file
  • Refreshed lockfile and updated theming E2E snapshots to reflect new build/render outputs

Per the Vite migration guidance, Vite 8 introduces Rolldown-based internals and changes CommonJS interop behavior. This branch applies the required config renames and adds targeted compatibility fixes for dependencies that surfaced runtime/import shape issues after the upgrade.

Reference: Vite Migration from v7

  • The compatibility wrappers/patches are intentionally scoped and documented as temporary safeguards for Vite 8 migration stability.

Screenshot or video (only for visual changes)

GitHub Issue Link (if applicable)

Testing Plan

  • E2E tests will catch a majority of this
  • Manually tested dev mode, building in prod mode, running in prod mode, etc.

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Mar 13, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@sfc-gh-bnisco sfc-gh-bnisco added the change:chore PR contains maintenance or housekeeping change label Mar 13, 2026 — with Graphite App
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 13, 2026

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-14359/streamlit-1.55.0-py3-none-any.whl
📦 @streamlit/component-v2-lib Download from artifacts
🕹️ Preview app pr-14359.streamlit.app (☁️ Deploy here if not accessible)

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@sfc-gh-bnisco sfc-gh-bnisco added the impact:internal PR changes only affect internal code label Mar 13, 2026 — with Graphite App
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 13, 2026

📉 Significant bundle size change detected

Metric This Branch develop Change (%)
Total (gzip) 7.85 MiB 8.14 MiB -3.55%
Entry (gzip) 97.24 KiB 670 KiB -85.49%

Please verify that this change is expected.

📊 View detailed bundle comparison

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 13, 2026

📉 Significant wheel size change detected

The wheel file size has decreased by 1.55% (threshold: 0.25%)

  • Current PR: 8752.78 KB
  • Latest develop: 8890.78 KB

Please verify that this change is expected.

@sfc-gh-bnisco sfc-gh-bnisco force-pushed the 03-12-chore_upgrade_vite_v7_-_v8 branch 2 times, most recently from c7f00f8 to 0ffa2f7 Compare March 13, 2026 17:57
@sfc-gh-bnisco sfc-gh-bnisco requested a review from Copilot March 13, 2026 18:42
@sfc-gh-bnisco sfc-gh-bnisco added the ai-review If applied to PR or issue will run AI review workflow label Mar 13, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Upgrades the frontend toolchain from Vite 7 → Vite 8 (and Vitest 4.0.x → 4.1.x) across the monorepo, applying required migration changes (Rolldown config renames, CJS interop shims) and updating build output handling and snapshots to keep Streamlit’s build/dev/test flows working.

Changes:

  • Bump Vite/Vitest (and related deps) across frontend workspaces and refresh yarn.lock.
  • Migrate Vite configs from build.rollupOptionsbuild.rolldownOptions, and adjust app asset URL handling for Rolldown output.
  • Add targeted runtime/interop shims: BaseUI theme import workaround, react-json-view / react-plotly.js compat modules, react-uid alias shim, and a DeckGL/Luma canvas resize guard.

Reviewed changes

Copilot reviewed 24 out of 46 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/yarn.lock Lockfile refresh for Vite 8 / Vitest 4.1 dependency graph (Rolldown, lightningcss, etc.).
frontend/package.json Bump root dev deps for Vitest + coverage.
frontend/utils/package.json Bump workspace dev deps (vite/vitest).
frontend/app/package.json Bump app dev deps (vite, vitest, plugin-react-swc).
frontend/app/vite.config.ts Switch to rolldownOptions, add react-uid alias, adjust asset routing and renderBuiltUrl for fonts.
frontend/app/src/util/reactUidCompat.ts New Vite-8 interop shim for react-uid (used via Vite alias).
frontend/lib/package.json Bump lib dev deps (vite/vitest/plugin-react-swc).
frontend/lib/vite.config.ts Switch to build.rolldownOptions for lib build.
frontend/lib/src/theme/createBaseUiTheme.ts BaseUI import pathing adjusted for Vite 8 interop behavior.
frontend/lib/src/util/reactJsonViewCompat.ts New compat wrapper to normalize CJS default export shape for react-json-view.
frontend/lib/src/util/reactPlotlyCompat.ts New compat wrapper to normalize CJS default export shape for react-plotly.js.
frontend/lib/src/components/elements/Json/Json.tsx Consume reactJsonViewCompat for runtime-stable JSON rendering.
frontend/lib/src/components/elements/Json/useJsonTooltip.ts Import OnSelectProps via compat module.
frontend/lib/src/components/widgets/DataFrame/columns/cells/JsonViewer.tsx Use reactJsonViewCompat in DataFrame JSON viewer.
frontend/lib/src/components/elements/PlotlyChart/PlotlyChart.tsx Use reactPlotlyCompat for Plotly component + types.
frontend/lib/src/components/elements/PlotlyChart/PlotlyChart.test.tsx Import Plotly types from compat module.
frontend/lib/src/components/elements/DeckGlJsonChart/patchLumaCanvasContext.ts New prototype patch to guard Luma resize crash when device.limits is temporarily unavailable.
frontend/lib/src/components/elements/DeckGlJsonChart/DeckGlJsonChart.tsx Apply the Luma canvas context patch via side-effect import.
frontend/connection/package.json Bump connection workspace dev deps (vite/vitest).
frontend/connection/vite.config.ts Switch to build.rolldownOptions.
frontend/component-lib/package.json Bump component-lib dev deps (vite/vitest).
frontend/component-lib/vite.config.ts Switch to build.rolldownOptions.
frontend/component-v2-lib/package.json Bump component-v2-lib dev deps (vite/vitest).
frontend/eslint-plugin-streamlit-custom/package.json Bump vitest deps for eslint plugin workspace.
frontend/knip.json Ignore knip “files” issue for the Vite-alias-only compat file.
e2e_playwright/snapshots/linux/custom_light_sidebar_theme_test/custom_dark_sidebar_theme_no_dark_configs[chromium].png Updated snapshot reflecting new render/build output.
Comments suppressed due to low confidence (1)

frontend/app/vite.config.ts:221

  • assetInfo.names and assetInfo.originalFileNames are treated as optional (you already fall back to [] in assetNames), but this block calls .includes(...) on assetInfo.names / assetInfo.originalFileNames directly. If either is undefined under Rolldown, the build will throw at config-eval time. Use the already-created fallback arrays (or optional chaining) for these .includes checks.
          const assetNames = assetInfo.names || []
          const hasAssetExtension = (extensions: string[]): boolean =>
            assetNames.some(name =>
              extensions.some(extension => name.endsWith(extension))
            )

          // For CSS files, place them in the /static/css/ directory
          if (hasAssetExtension([".css"])) {
            // If OMIT_HASH_FROM_MAIN_FILES is set, we don't want to include the
            // hash in the filename of the entry file at the minimum. There could
            // be other files with the same name that cause a conflict, which would
            // increment the entry file to index2.css, etc. This ensures the entry
            // file is named index.css in this case.
            if (
              assetInfo.names.includes("index.css") &&
              assetInfo.originalFileNames.includes("index.html")
            ) {

You can also share your feedback on Copilot code review. Take the survey.

@github-actions github-actions bot removed the ai-review If applied to PR or issue will run AI review workflow label Mar 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR upgrades the frontend build tooling from Vite 7 (Rollup-based) to Vite 8 (Rolldown-based) along with a Vitest 4.0.x → 4.1.x bump. Key changes include:

  • Dependency upgrades: vite ^7.3.1^8.0.0, vitest ^4.0.18^4.1.0, @vitejs/plugin-react-swc ^4.2.3^4.3.0 across all workspace packages.
  • Config migration: build.rollupOptionsbuild.rolldownOptions in 4 vite configs (app, lib, connection, component-lib).
  • CJS interop compatibility shims: New wrapper modules for react-uid, react-json-view, react-plotly.js, and baseui to handle Vite 8's changed CommonJS interop behavior.
  • DeckGL/Luma patch: Monkey-patch for CanvasContext.getMaxDrawingBufferSize() to guard against intermittent crashes when device.limits is temporarily unavailable.
  • Asset path handling: Updated assetFileNames to use Rolldown's assetInfo.names (array) instead of Rollup's assetInfo.name (string), and added renderBuiltUrl logic for stable CSS font URLs.
  • E2E snapshot updates: 21 theme-related screenshots updated to reflect Rolldown's slightly different CSS output.

The cited performance benefits are significant: 72% faster make frontend-fast and 85% smaller entry file.

Code Quality

All three reviewers agreed the code quality is high and the changes are well-scoped for a migration PR.

Consensus strengths:

  • All compatibility shims have excellent JSDoc documentation with clear intent, reasoning, and removal criteria — best practice for temporary workarounds (unanimous agreement).
  • The __streamlitMaxTexturePatchApplied guard in patchLumaCanvasContext.ts prevents double-patching (noted by all reviewers).
  • Defensive fallback in assetFileNames with assetInfo.names || [].
  • The knip.json update correctly suppresses false-positives for the compat file referenced only through a Vite alias.

Consensus observations (non-blocking):

  • Duplicated resolveDefaultExport function (reactJsonViewCompat.ts:43–56 and reactPlotlyCompat.ts:42–55): All three reviewers identified this duplication. For temporary shims this is acceptable, but extracting to a shared utility would reduce drift risk.
  • frontend/AGENTS.md line 8 still references "vite v7" in the tech stack header (identified by opus-4.6-thinking, verified). This should be updated to "vite v8".
  • PlotlyChart/utils.ts:17 still imports Figure directly from "react-plotly.js" rather than the compat module. Since it's a type-only import (erased at compile time), this has no runtime impact, but updating it for consistency would be cleaner (identified by opus-4.6-thinking).
  • createBaseUiTheme.ts:24–30 uses as unknown as Pick<...> to work around CJS interop — the double type assertion is inherently fragile but acceptable for a temporary fix (identified by opus-4.6-thinking).

Test Coverage

Reviewers largely agreed that test coverage is adequate for a migration PR but noted a gap in dedicated unit tests for the new compat helpers:

  • E2E tests: 21 snapshot images updated for theme-related visual changes. The E2E test suite provides the primary safety net for this migration (unanimous agreement).
  • Unit tests: The PlotlyChart.test.tsx correctly mocks react-plotly.js at the package level, which Vitest hoists before the compat module's import.
  • Gap identified (gpt-5.3-codex-high, opus-4.6-thinking): No new unit tests specifically exercise the resolveDefaultExport logic or the interop shim behavior. While existing component-level tests cover the happy path, edge cases (deeply nested defaults, non-object modules) are not explicitly tested. gpt-5.3-codex-high recommended adding targeted regression tests; gemini-3.1-pro and opus-4.6-thinking considered the gap acceptable given the temporary nature of the shims. Consolidated assessment: The absence of dedicated compat shim tests is a minor gap — not blocking, but worth adding as a follow-up.
  • renderBuiltUrl font path logic is only covered implicitly through E2E snapshot tests (noted by opus-4.6-thinking).

Backwards Compatibility

Unanimous agreement: No breaking API changes. This is an internal build tooling upgrade with no changes to Streamlit's public Python or TypeScript API. The 21 updated E2E theme snapshots indicate pixel-level CSS rendering differences that are cosmetic and unlikely to affect users. The component-lib package retains the same output format (es) and external dependencies, so existing custom components should continue to work. Wheel size is 1.5% smaller.

Security & Risk

Unanimous agreement: Low risk. No changes to security-sensitive areas (auth, sessions, WebSocket handling, CORS, CSP, file upload/download, XSRF). No new eval/Function() patterns. All new dependencies (lightningcss, rolldown, @oxc-project/*) are build-time tools replacing the previous Rollup/esbuild stack.

Residual risk areas (consensus):

  • Asset URL rewriting and output path behavior in frontend/app/vite.config.ts (renderBuiltUrl font path rewriting).
  • Runtime interop normalization wrappers that depend on module shape assumptions.
  • The patchLumaCanvasContext.ts monkey-patch modifies CanvasContext.prototype globally, which could interact unexpectedly with future Luma.gl updates (mitigated by guard flag and removal criteria).

External test recommendation

Unanimous recommendation: Yes — external testing is warranted.

  • Triggered categories: 5 (Static and component asset serving), 8 (Cross-origin theming and resource discovery)
  • Evidence:
    • frontend/app/vite.config.ts: assetFileNames rewritten to use Rolldown's assetInfo.names array; renderBuiltUrl adds CSS font URL rewriting that changes how font assets are referenced from CSS files.
    • frontend/component-lib/vite.config.ts: Build tooling changed from Rollup to Rolldown, could affect custom component asset serving.
    • 21 theme-related E2E snapshots changed, indicating CSS output differences that could manifest differently in embedded contexts.
  • Suggested focus areas:
    • Verify custom font loading works correctly in embedded Streamlit (SiS/iframe) where assets are served through a proxy or different base path.
    • Verify custom themes render correctly when Streamlit is embedded behind a reverse proxy with a custom baseUrlPath.
    • Verify custom components (v1 via component-lib) continue to load and render correctly.
  • Confidence: Medium
  • Assumptions and gaps: Cannot verify actual production build output or CDN behavior from code review alone. The font URL rewriting logic appears correct for standard deployment topology, but edge cases with non-standard base paths or CDN configurations cannot be fully assessed statically.

Accessibility

Unanimous agreement: No accessibility impact. Changes are limited to build tooling and module interop — no UI components, ARIA attributes, focus management, or semantic HTML were modified.

Recommendations

These are non-blocking improvements, consolidated and prioritized from all three reviews:

  1. Update frontend/AGENTS.md line 8: Change "Build tool: vite v7" to "Build tool: vite v8" to reflect the upgrade. (Low effort, should be done in this PR.)

  2. Consider extracting resolveDefaultExport: The identical function in reactJsonViewCompat.ts and reactPlotlyCompat.ts could be a shared utility to reduce duplication and drift risk. (All three reviewers noted this.)

  3. Track shim removal: Consider creating tracking issues for each compatibility shim removal (react-uid, react-json-view, react-plotly.js, baseui, patchLumaCanvasContext) so they don't become permanent fixtures. Each file's JSDoc already has clear removal criteria. (Two reviewers recommended this.)

  4. Add targeted regression tests for compat helpers (follow-up): At least one unit test validating resolveDefaultExport behavior would harden the migration. (Recommended by gpt-5.3-codex-high and opus-4.6-thinking.)

  5. Consider updating PlotlyChart/utils.ts:17: For consistency, update the type-only import of Figure to use the compat module path. (Low priority, no runtime impact.)

Verdict

APPROVED: The Vite 7 → 8 migration is well-executed with thorough compatibility shims, excellent documentation, defensive coding practices, and significant build performance improvements. All three reviewers approved. The recommendations above are non-blocking improvements that can be addressed in this PR or as follow-ups.


This is a consolidated AI review by opus-4.6-thinking, synthesizing reviews from gemini-3.1-pro, gpt-5.3-codex-high, and opus-4.6-thinking.


📋 Review by `gemini-3.1-pro`

Summary

This PR upgrades the frontend workspace dependencies from Vite 7 to Vite 8 and Vitest 4.0.x to 4.1.x, applying necessary migration fixes to accommodate Vite 8's new Rolldown bundler.

Code Quality

  • Code quality is high and adheres to Streamlit's TypeScript principles.
  • The transition from rollupOptions to rolldownOptions in all vite.config.ts files is the correct approach for Vite 8.
  • Compatibility shims (reactUidCompat.ts, reactJsonViewCompat.ts, reactPlotlyCompat.ts) are well-commented. Including explicit "Removal criteria" in the JSDoc is an excellent practice that will help prevent these workarounds from becoming permanent tech debt.
  • The resolveDefaultExport helper is a pragmatic and defensive workaround for the nested .default issues arising from CJS/ESM interop changes in Vite 8.
  • The Luma canvas resize patch in patchLumaCanvasContext.ts is targeted, safe, and properly checks __streamlitMaxTexturePatchApplied to avoid double-patching.

Test Coverage

  • Snapshot tests have been refreshed appropriately to reflect the build output differences from the new bundler.
  • No new features were added, so no new unit or E2E tests are required. Vitest dependencies have been upgraded cleanly.

Backwards Compatibility

  • This is a build tooling upgrade. Backwards compatibility for the runtime application is effectively maintained through the added interop shims.
  • CSS font URLs have been properly handled via renderBuiltUrl in frontend/app/vite.config.ts to ensure paths remain stable (../media/...), matching the previous Vite 7 behavior.

Security & Risk

  • Low risk. The compatibility wrappers and the Luma canvas patch are narrowly scoped and defensive.
  • There are no changes to security-sensitive areas like auth, sessions, or execution.

External test recommendation

  • Recommend external_test: Yes
  • Triggered categories: 5. Static and component asset serving, 8. Cross-origin theming and resource discovery
  • Evidence:
    • frontend/app/vite.config.ts: Modifies renderBuiltUrl to rewrite CSS font asset URLs to ../media/... for Rolldown compatibility.
  • Suggested external_test focus areas:
    • Verify that custom fonts load correctly (without 404 errors) when the Streamlit app is embedded or served via an external proxy/host.
  • Confidence: Medium
  • Assumptions and gaps: The PR states the renderBuiltUrl change keeps emitted font paths stable to match Vite 7 behavior. If the compiled output paths match exactly, there should be no regression. However, any build-path changes justify an external check just to be safe.

Accessibility

  • No changes to user-facing DOM structures, semantics, or interactive elements. No impact on accessibility.

Recommendations

  • The implementation is thorough and very well-documented. No further changes are required.

Verdict

APPROVED: The Vite 8 upgrade is implemented cleanly with excellent defensive coding and documentation around the temporary compatibility shims.


This is an automated AI review by gemini-3.1-pro. Please verify the feedback and use your judgment.

📋 Review by `gpt-5.3-codex-high`

Summary

This PR upgrades the frontend toolchain from Vite 7 to Vite 8 (plus Vitest 4.1), migrates Vite config keys to Rolldown equivalents, and introduces targeted interop guards for CommonJS-heavy dependencies (react-uid, react-json-view, react-plotly.js) plus a DeckGL/Luma runtime safety patch. It also refreshes theme-related E2E snapshots to match the new build output.

Code Quality

The changes are cohesive and well-scoped for a migration PR, with strong inline documentation and clear removal criteria in temporary compatibility shims. I did not find blocking correctness defects in the reviewed code paths.

Notable maintainability observations:

  • frontend/lib/src/util/reactJsonViewCompat.ts and frontend/lib/src/util/reactPlotlyCompat.ts duplicate the same resolveDefaultExport logic (43-56 and 42-55 respectively), which is acceptable short term but should be kept aligned if either shim is modified.
  • frontend/lib/src/components/elements/DeckGlJsonChart/patchLumaCanvasContext.ts (56-69) is a global prototype monkey-patch; it is guarded and documented, but should remain temporary.

Test Coverage

Coverage is partially adequate for migration confidence, but there is a gap in targeted regression tests for the new compat helpers:

  • Existing coverage signal: updated theme E2E snapshots in e2e_playwright/__snapshots__/linux/... suggest UI output was validated after the migration.
  • Limited direct test additions: only an import-type adjustment in frontend/lib/src/components/elements/PlotlyChart/PlotlyChart.test.tsx; no new unit tests specifically exercise the interop shim behavior in frontend/lib/src/util/reactJsonViewCompat.ts, frontend/lib/src/util/reactPlotlyCompat.ts, or frontend/app/src/util/reactUidCompat.ts.

Backwards Compatibility

No public Streamlit Python API changes are introduced, so end-user app code should remain compatible. The main compatibility risk is frontend runtime/build behavior under varied hosting conditions due to asset URL and module interop changes (not API surface changes).

Security & Risk

No direct high-risk security patterns were introduced (no new auth/session logic, no new endpoint handling, no unsafe eval/exec patterns, no new external service calls).
Main regression risk areas are:

  • Asset URL rewriting and output path behavior in frontend/app/vite.config.ts (204-257).
  • Runtime interop normalization wrappers (frontend/lib/src/util/reactJsonViewCompat.ts, frontend/lib/src/util/reactPlotlyCompat.ts) that depend on module shape assumptions.

External test recommendation

  • Recommend external_test: Yes
  • Triggered categories: 5. Static and component asset serving; 8. Cross-origin theming and resource discovery
  • Evidence:
    • frontend/app/vite.config.ts: Migrates to rolldownOptions, changes asset file classification to assetInfo.names, and adds CSS font URL rewrite logic in renderBuiltUrl (204-257), which can behave differently behind proxies/base paths/iframes.
    • e2e_playwright/__snapshots__/linux/custom_theme_fonts_test/custom_fonts_app[chromium].png (and related theme snapshots): visual output changed in theme/font/resource-related scenarios after build behavior changes.
  • Suggested external_test focus areas:
    • Validate custom theme font loading for externally hosted apps with non-root base paths and proxy prefixes.
    • Validate embedded iframe-hosted Streamlit app rendering (including sidebar/theme snapshots) to ensure CSS/media paths resolve identically to local runs.
  • Confidence: Medium
  • Assumptions and gaps: Assessment is diff-based only; I did not execute tests/build locally in this review step, so runtime behavior in all external hosting topologies is inferred rather than directly validated.

Accessibility

No direct accessibility-impacting UI interaction changes were introduced (no new controls, roles, focus management, or ARIA behavior changes). Snapshot churn appears visual/build-output related rather than semantic DOM/a11y behavior changes.

Recommendations

  1. Add at least one targeted regression test (unit or integration) that validates default-export normalization behavior for react-json-view and react-plotly.js compat modules.
  2. Add an external/embedded-path focused E2E scenario for themed font/media URL resolution to reduce risk from renderBuiltUrl and Rolldown asset behavior changes.
  3. Track cleanup follow-up for temporary shims/patches (reactUidCompat, reactJsonViewCompat, reactPlotlyCompat, patchLumaCanvasContext) so they do not become permanent technical debt.

Verdict

APPROVED: The migration is well-structured and merge-ready, with no blocking defects found; the main residual risk is hosting-topology-dependent asset/interop behavior, which should be further hardened with targeted follow-up tests.


This is an automated AI review by gpt-5.3-codex-high. Please verify the feedback and use your judgment.

📋 Review by `opus-4.6-thinking`

Summary

This PR upgrades the frontend build tooling from Vite 7 (Rollup-based) to Vite 8 (Rolldown-based), along with a Vitest 4.0.x → 4.1.x bump. The key changes are:

  • Dependency upgrades: vite ^7.3.1^8.0.0, vitest ^4.0.18^4.1.0, @vitejs/plugin-react-swc ^4.2.3^4.3.0 across all workspace packages.
  • Config migration: build.rollupOptionsbuild.rolldownOptions in 4 vite configs (app, lib, connection, component-lib).
  • CJS interop compatibility shims: New wrapper modules for react-uid, react-json-view, react-plotly.js, and baseui to handle Vite 8's changed CommonJS interop behavior.
  • DeckGL/Luma patch: Monkey-patch for CanvasContext.getMaxDrawingBufferSize() to guard against intermittent crashes when device.limits is temporarily unavailable.
  • Asset path handling: Updated assetFileNames to use Rolldown's assetInfo.names (array) instead of Rollup's assetInfo.name (string), and added renderBuiltUrl logic for stable CSS font URLs.
  • E2E snapshot updates: 21 theme-related screenshots updated to reflect Rolldown's slightly different CSS output.

The performance benefits cited are significant: 72% faster make frontend-fast and 85% smaller entry file.

Code Quality

Strengths:

  • All compatibility shims have excellent JSDoc documentation with clear intent, reasoning, and removal criteria. This is best-practice for temporary workarounds.
  • The __streamlitMaxTexturePatchApplied guard in patchLumaCanvasContext.ts prevents double-patching.
  • Defensive fallback in assetFileNames with assetInfo.names || [].
  • The knip.json is correctly updated to suppress the false-positive for the reactUidCompat.ts compat file (referenced only through Vite alias).

Minor observations:

  1. Duplicated resolveDefaultExport function (reactJsonViewCompat.ts:43–56 and reactPlotlyCompat.ts:42–55): The identical function appears in both compat files. For temporary shims this is acceptable, but extracting to a shared utility (e.g., frontend/lib/src/util/resolveDefaultExport.ts) would be cleaner and reduce drift risk.

  2. PlotlyChart/utils.ts:17 still imports Figure directly from "react-plotly.js" rather than from the compat module. Since this is a type-only import (erased at compile time), it has no runtime impact. However, for consistency with the compat pattern established in this PR, it could import type { Figure } from "~lib/util/reactPlotlyCompat" instead.

  3. createBaseUiTheme.ts:24–30 uses as unknown as Pick<...> to work around CJS interop. The double type assertion (as unknown as) is necessary but inherently fragile — it will silently succeed even if baseui's exports change. The import path "baseui/index.js" is also coupled to baseui's internal file structure. These are acceptable tradeoffs for a temporary fix, but worth noting for future maintenance.

  4. frontend/AGENTS.md line 8 still references "vite v7" in the tech stack header. This should be updated to "vite v8" to reflect the new version.

Test Coverage

  • E2E tests: 21 snapshot images updated for theme-related visual changes. These are expected consequences of the build tool change (different CSS optimization producing pixel-level differences). The E2E test suite provides the primary safety net for this migration.
  • Unit tests: The PlotlyChart.test.tsx correctly mocks react-plotly.js at the original package level, which Vitest hoists before the compat module's internal import runs — so the mock flows through properly.
  • No new unit tests for compat shims: The compat modules (reactJsonViewCompat.ts, reactPlotlyCompat.ts, reactUidCompat.ts, patchLumaCanvasContext.ts) lack dedicated unit tests. While existing component-level tests cover the happy path, edge cases in resolveDefaultExport (e.g., deeply nested defaults, non-object modules) are not explicitly tested. Given the temporary nature of these shims, this is acceptable but not ideal.
  • No new tests for renderBuiltUrl font path logic: The font URL rewriting in vite.config.ts is only covered implicitly through E2E snapshot tests.

Backwards Compatibility

  • No breaking API changes: This is an internal build tooling upgrade with no changes to Streamlit's public Python or TypeScript API.
  • Visual changes: The 21 updated E2E theme snapshots indicate pixel-level rendering differences due to Rolldown's different CSS optimization. These are cosmetic and unlikely to affect users.
  • component-lib build changes: The component-lib package (used by custom component authors) now builds with Rolldown instead of Rollup. The output format (es) and external dependencies remain the same, so existing custom components should continue to work.
  • Wheel size: 1.5% smaller, which is a positive change.

Security & Risk

  • No security-sensitive areas touched: No changes to WebSocket handling, authentication, CORS, CSP, file upload/download, cookies, XSRF, or session management.
  • No new runtime JS execution: No eval, Function(), or unsafe-eval patterns introduced.
  • No new dependencies from external services: All new dependencies (lightningcss, rolldown, @oxc-project/*) are build-time tools that replace the previous Rollup/esbuild stack. lightningcss is now a hard dependency of Vite 8 (was previously optional) — this has native binary components but is a well-maintained Mozilla project.
  • Monkey-patching risk: The patchLumaCanvasContext.ts modifies CanvasContext.prototype globally, which could interact unexpectedly with future Luma.gl updates. The guard flag and clear removal criteria mitigate this risk.
  • renderBuiltUrl font path rewriting: The new logic rewrites CSS font URLs to use ../media/ relative paths. If Rolldown changes its asset emission behavior in future releases, this could produce broken font paths. The explicit conditions (file extension regex, path checks) limit the blast radius.

External test recommendation

  • Recommend external_test: Yes
  • Triggered categories: 5 (Static and component asset serving), 8 (Cross-origin theming and resource discovery)
  • Evidence:
    • frontend/app/vite.config.ts: assetFileNames rewritten to use Rolldown's assetInfo.names array; renderBuiltUrl adds CSS font URL rewriting that changes how font assets are referenced from CSS files.
    • frontend/component-lib/vite.config.ts: Build tooling changed from Rollup to Rolldown, could affect custom component asset serving.
    • 21 theme-related E2E snapshots changed, indicating CSS output differences that could manifest differently in embedded contexts.
  • Suggested external_test focus areas:
    • Verify custom font loading works correctly in embedded Streamlit (SiS/iframe) where assets are served through a proxy or different base path.
    • Verify custom themes render correctly when Streamlit is embedded in Snowflake or behind a reverse proxy with a custom baseUrlPath.
    • Verify custom components (v1 via component-lib) continue to load and render correctly.
  • Confidence: Medium
  • Assumptions and gaps: Cannot verify actual production build output or CDN behavior from code review alone. The font URL rewriting logic appears correct for the standard deployment topology, but edge cases with non-standard base paths or CDN configurations cannot be fully assessed statically.

Accessibility

No accessibility impact. The changes are limited to build tooling and module interop — no UI components, ARIA attributes, focus management, or semantic HTML were modified. The theme snapshot changes are pixel-level CSS differences that do not affect accessible names, roles, or keyboard behavior.

Recommendations

  1. Update frontend/AGENTS.md line 8: Change "Build tool: vite v7" to "Build tool: vite v8" to reflect the upgrade.

  2. Consider extracting resolveDefaultExport: The identical function in reactJsonViewCompat.ts and reactPlotlyCompat.ts could be a shared utility in frontend/lib/src/util/resolveDefaultExport.ts. This reduces duplication and makes maintenance easier when the shims are eventually removed.

  3. Consider updating PlotlyChart/utils.ts:17: For consistency, update import { Figure as PlotlyFigureType } from "react-plotly.js" to import type { Figure as PlotlyFigureType } from "~lib/util/reactPlotlyCompat". This is low priority since it's type-only and has no runtime impact.

  4. Track shim removal: Consider creating tracking issues for each compatibility shim removal (react-uid, react-json-view, react-plotly.js, baseui, patchLumaCanvasContext) so they don't become permanent fixtures. Each file's JSDoc already has clear removal criteria, which is excellent.

Verdict

APPROVED: Well-executed Vite 7 → 8 migration with thorough compatibility shims, clear documentation, good defensive coding practices, and significant build performance improvements. The recommendations above are non-blocking improvements.


This is an automated AI review by opus-4.6-thinking.

@sfc-gh-bnisco
Copy link
Copy Markdown
Collaborator Author

@github-actions Follow-up on your review suggestions: I updated frontend/AGENTS.md to reflect Vite 8 and switched PlotlyChart/utils.ts to import the Figure type from ~lib/util/reactPlotlyCompat for consistency.

@sfc-gh-bnisco sfc-gh-bnisco marked this pull request as ready for review March 13, 2026 23:13
@sfc-gh-bnisco sfc-gh-bnisco force-pushed the 03-12-chore_upgrade_vite_v7_-_v8 branch from 73186ec to 41237a5 Compare March 16, 2026 16:10
@sfc-gh-bnisco sfc-gh-bnisco merged commit 1e0eab8 into develop Mar 16, 2026
45 of 46 checks passed
@sfc-gh-bnisco sfc-gh-bnisco deleted the 03-12-chore_upgrade_vite_v7_-_v8 branch March 16, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:chore PR contains maintenance or housekeeping change impact:internal PR changes only affect internal code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants