chore(ui): drop the antd dependency and its leftovers - #37574
Conversation
Nothing in the dashboard renders antd any more, so the package and the
scaffolding around it can go. This removes `antd` and
`@ant-design/cssinjs` from package.json, deletes the global StyleProvider
the root layout wrapped every page in, drops the `antd` cascade layer and
the z-index override that lifted Base UI popups over an antd Modal, and
retires the lint rules that policed antd imports and antd class selectors
in tests.
Fifteen test files still carried `vi.mock("antd", ...)` factories for
components that stopped importing antd during the migration. They were
inert, and they resolve the real module, so they would have broken the
moment the package left node_modules.
The compatibility shims keep their behaviour and lose the antd name:
`antdRules`/`antdRequired` become `validatorRules`/`requiredRule`,
`isAntdUrl` becomes `isValidUrl`, and `ABOVE_ANTD_MODAL` becomes
`NESTED_DIALOG_LAYER`. Comments that explain why a contract looks the way
it does still name antd, because that history is the reason.
Greptile SummaryThis PR removes the dashboard’s unused Ant Design runtime, global style provider, compatibility CSS, lint rule, and obsolete test mocks. It also renames surviving form and URL-validation helpers without changing their behavior
Confidence Score: 4/5The PR appears safe to merge, with only the non-blocking test-classification cleanup remaining The removed packages and provider have no active dashboard importers, helper behavior is preserved, and deleted mocks do not remove behavioral assertions Files Needing Attention: ui/litellm-dashboard/src/**/*.test.tsx and ui/litellm-dashboard/src/lib/forms/urlValidation.test.ts
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/package.json | Removes the two unused Ant Design dependencies; no active dashboard importer remains |
| ui/litellm-dashboard/src/app/layout.tsx | Removes the inert global Ant Design style wrapper while preserving the existing provider hierarchy |
| ui/litellm-dashboard/src/app/globals.css | Removes the Ant Design cascade layer and modal popup override while retaining Base UI nested-dialog styling |
| ui/litellm-dashboard/src/components/common_components/formRules.ts | Renames the legacy form-rule shim while preserving required and asynchronous validator behavior |
| ui/litellm-dashboard/src/lib/forms/urlValidation.ts | Renames the URL-validation shim and constants without changing the compatibility regex or length limit |
| ui/litellm-dashboard/src/app/(dashboard)/policies/_components/impact_popover.test.tsx | Removes an inert Ant Design mock, but leaves a touched legacy test unclassified under the dashboard test naming convention |
Comments Outside Diff (1)
-
ui/litellm-dashboard/src/app/(dashboard)/policies/_components/impact_popover.test.tsx, line 1 (link)Touched tests remain unclassified
This PR modifies fourteen legacy tests without classifying them as unit or integration tests, leaving their ownership and execution scope ambiguous
Context Used: CLAUDE.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (1): Last reviewed commit: "chore(ui): drop the antd dependency and ..." | Re-trigger Greptile
tin-berri
left a comment
There was a problem hiding this comment.
Reviewed the antd removal — this is a large diff (105 additions / 1,410 deletions across 50 files) so I verified it against the full post-removal tree, not just the hunks. Completeness: grep across ui/litellm-dashboard/src/ for any remaining from "antd"/from '@ant-design returns zero hits; the ~40 remaining string matches for "antd" are comments/test-description strings documenting legacy contracts, matching the PR's own caveat. package.json/package-lock.json drop antd and @ant-design/cssinjs from real dependencies (not just dev), and the lockfile prunes the full transitive tree (~993 lines) — a real npm install, not a hand-edit. No behavior loss from the StyleProvider/z-index deletion: the deleted CSS was scoped to .ant-modal-wrap, a class that never renders once antd is gone, so it was already inert — and critically, the underlying nested-dialog stacking mechanism itself (NESTED_DIALOG_LAYER, renamed from ABOVE_ANTD_MODAL) is preserved and still used by KeywordModal/PatternModal/CustomPatternModal, unrelated to antd. The 15 deleted vi.mock("antd") factories were confirmed dead — no file in src/ imports antd, so nothing depended on those mocks. Scope is clean (all 50 files under ui/litellm-dashboard/**, no backend/auth/billing/security touched). CI green — build-ui, ui-unit-tests, frontend-lint and the full backend suite all pass; only non-blocking image-scan and the external PR-review bot remain pending.
mateo-berri
left a comment
There was a problem hiding this comment.
LGTM. Thanks Ryan, this rocks!!
Upstream finished migrating the dashboard off antd (BerriAI#37569, BerriAI#37574), so AntdGlobalProvider.tsx no longer exists and antd is gone from package.json. The ConfigProvider patch was dead, and its missing file failed the build. Deleted it: the brand colour already goes through shadcn's --primary. They also extracted the login SSO notice into a <SsoEnabledNotice /> component, so the legal-links patch now matches one short line instead of a multi-line antd Alert. Less to churn against. Separately, branding/layout.tsx had gone stale without anyone noticing. It was an unguarded whole-file copy taken before e368eea, so every build silently dropped upstream's NoRedisWarningBanner from both app shells, and it had also stripped their comments. Rebuilt it as upstream's current file plus only our four additions, so the delta is now just the two Legal imports and the column shell that makes the footer a real row. To stop that recurring, layout.tsx joins the guarded manifest. The guard was never Authentik-specific, so manifest.txt, baseline.sha256 and rebaseline.sh move up to aihpi/ and the manifest names copies relative to that. Both copies now fail the build when upstream moves them and get 3-way merged by the nightly re-sync step before the push. Verified: apply.sh applies clean, is idempotent, and exits 1 naming layout.tsx when its upstream version is altered. npm ci and npm run build on Node 24 compile. In the built bundle --primary:#dd6108 is present, the legal links reach both the login page and the dashboard shell, "AI Model Hub", "KI-Servicezentrum" and "Login with Authentik" are all there, and AUTO_REDIRECT_UI_LOGIN_TO_SSO and "Access your LiteLLM Admin UI" are gone. The patched layout keeps NoRedisWarningBanner in all three places.
TLDR
Problem this solves:
How it solves it:
antdand@ant-design/cssinjsfrom package.jsonvi.mock("antd")factoriesUser Flow
Before: an admin loading the dashboard downloads and parses a UI library that no longer draws a single control
After: the same page ships only the kit it actually renders
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Shared setup: one worktree per side,
cd ui/litellm-dashboard && npm ci && npm run build, the build copied intolitellm/proxy/_experimental/out, and a live proxy per side (python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --port <port> --use_v2_migration_resolver, fresh Postgres DB each) so the browser loads the UI exactly as an admin would at http://localhost:PORT/ui/. Browser steps executed in a real Chromium driven by Playwright against those live proxies, logged in as adminBefore (0b37454)
antd presence in node_modules and the served bundle
npm ls antd @ant-design/cssinjsnpm run buildcompletes, thenfind out/_next/static -name '*.js' | xargs cat | wc -cgives 10522409 bytes andgrep -rl cssinjs out/_next/statichits one served chunk,_next/static/chunks/0i9exd9dj3-75.js: the style engine still ships to every visitorDashboard pages and the create-key dialog still render
GET http://localhost:53817/ui/returns 200; after logging in,?page=api-keys,?page=teams,?page=new_model,?page=mcp-servers, and?page=guardrailsall render the full dashboard with zero browser console errors and zero page errors?page=api-keys, Create New Key opens, and clicking the Models field pops a 10-option dropdown;document.elementFromPointat the first option's center hits that option (hitInsideOption: true,hitInsideDialogOverlay: false), so the dropdown paints above the dialog, and clicking it selects the modelAfter (552884d)
antd presence in node_modules and the served bundle
npm ls antd @ant-design/cssinjsnpm run buildcompletes, then the same byte count gives 10510152 bytes andgrep -rl cssinjs out/_next/static(plusant-design,data-ant, and bareantd) hits zero files: nothing antd-flavored ships anymoreDashboard pages and the create-key dialog still render
GET http://localhost:54293/ui/returns 200; the same five pages render identically with zero browser console errors and zero page errorshitInsideOption: true,hitInsideDialogOverlay: false) and the same successful selection, with the z-index override goneQA observations:
Type
🧹 Refactoring
Caveats (if any)
tests/proxy_admin_ui_tests/ui_unit_testsstill declares antdFinal Attestation
The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR
552884d passes /live-pr-risk