Skip to content

Dependencies Analysis

Decisions (2026-03-19): All recommendations accepted.

Keep (production dependency): radix-ui — replaces @radix-ui/react-tooltip

Keep (devDependency): @reduxjs/toolkit, react-redux, redux-persist, sonner

Conditionally keep: @storybook/addon-links (verify no linkTo usage first)

Drop: next-themes, react-icons, shadcn, pako, qr-scanner, react-dropzone


The following packages appear in the worktree’s package.json but not in the main clone. Minor version bumps to existing packages (tailwind-merge, @tailwindcss/postcss, tailwindcss, Storybook packages, agentation, lucide-react) are not evaluated here — they are routine updates with no consolidation impact.


1. radix-ui (production dependency, ^1.4.3)

Section titled “1. radix-ui (production dependency, ^1.4.3)”

What it is. The unified Radix UI meta-package that re-exports all @radix-ui/react-* primitives under a single import. It is the recommended migration path from individual @radix-ui/react-* packages going forward.

Where it is used. 14 files in src/components/ui/ and src/components/canary/:

  • button.tsx, badge.tsx, sidebar.tsx — import { Slot }
  • dropdown-menu.tsx — imports { DropdownMenu as DropdownMenuPrimitive }
  • collapsible.tsx, toggle.tsx, separator.tsx, tabs.tsx, sheet.tsx, tooltip.tsx, avatar.tsx, label.tsx, dialog.tsx — import their respective primitives
  • src/components/canary/atoms/button/button.tsx — imports { Slot }

The main clone already depends on @radix-ui/react-tooltip individually. The worktree switches all ui components to the consolidated radix-ui package.

Needed after consolidation? Yes. All the src/components/ui/ components that consolidation brings in require it. The individual @radix-ui/react-tooltip dependency in production can be replaced by radix-ui at the same time.

Recommendation: Keep. Promote to production dependency; remove the now-redundant @radix-ui/react-tooltip entry.


2. @reduxjs/toolkit (devDependency, ^2.11.2)

Section titled “2. @reduxjs/toolkit (devDependency, ^2.11.2)”

What it is. The official Redux tooling library (configureStore, slices, createAsyncThunk, etc.).

Where it is used. One file: src/decorators/with-full-app-providers.tsx. The decorator uses configureStore to create a per-story Redux store with the same rootReducer as the vendored arda-frontend-app. This is required to render “Dev Witness” and “Canary Refactor” stories that embed live frontend pages.

Needed after consolidation? Yes, as long as the Dev Witness / Canary Refactor story categories exist. The decorator wraps stories with the full frontend provider stack; without it those stories cannot render. It is a devDependency because it is only used in Storybook.

Recommendation: Keep as a devDependency.


What it is. React bindings for Redux (<Provider>, useSelector, useDispatch).

Where it is used. src/decorators/with-full-app-providers.tsx — imports { Provider as ReduxProvider } to wrap stories with the store created by @reduxjs/toolkit.

Needed after consolidation? Yes — same reasoning as @reduxjs/toolkit. The two packages are used together in the same decorator file.

Recommendation: Keep as a devDependency.


What it is. Persistence and rehydration layer for Redux stores. The vendored arda-frontend-app rootReducer uses redux-persist/lib/storage.

Where it is used.

  • src/decorators/with-full-app-providers.tsx — imports { FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } to configure serializableCheck middleware ignores.
  • .storybook/main.ts — a Vite plugin transforms require('redux-persist/lib/storage') in the vendored rootReducer.ts from CJS to ESM at build time.

Needed after consolidation? Yes — the vendored frontend code pulls in redux-persist transitively, and the Storybook Vite config has an explicit transform for it. It is a devDependency.

Recommendation: Keep as a devDependency.


What it is. A toast notification library. The worktree uses it in two ways: a thin wrapper component (src/components/ui/sonner.tsx) that re-exports a styled <Toaster>, and direct toast / Toaster imports in live story files.

Where it is used. 8 files:

  • src/components/ui/sonner.tsx — the ui-layer wrapper (imports Toaster + useTheme from next-themes; see note below)
  • src/use-cases/reference/business-affiliates/create-supplier/creatable-suppliers-page.tsx
  • src/use-cases/reference/business-affiliates/edit-supplier/editable-suppliers-page.tsx
  • src/use-cases/reference/business-affiliates/delete-supplier/deletable-suppliers-page.tsx
  • src/use-cases/reference/business-affiliates/delete-supplier/panel-deletable-suppliers-page.tsx
  • src/canary-refactor/components/columnPresets.tsx
  • src/canary-refactor/components/ItemsPage.tsx
  • src/canary-refactor/components/ItemTableAGGrid.tsx

Interaction with next-themes. src/components/ui/sonner.tsx calls useTheme() from next-themes to propagate the active theme to <Sonner>. Because next-themes is being dropped, this wrapper component must be rewritten to remove that dependency. The four business-affiliates use-case pages and the canary-refactor files import toast and Toaster from sonner directly (not through the wrapper), so they are unaffected by the next-themes removal. The wrapper file itself (sonner.tsx) is the only code change needed.

Needed after consolidation? Yes. Toast feedback is actively used across supplier use-case stories and the canary-refactor Items components. It is a devDependency because ux-prototype is a Storybook library, not an installed package.

Recommendation: Keep as a devDependency. Rewrite src/components/ui/sonner.tsx to remove the useTheme call (use a hardcoded "system" or accept theme as a prop instead).


What it is. A theme (dark/light mode) provider for Next.js. The worktree adds it.

Where it is used. One file: src/components/ui/sonner.tsxuseTheme() call to drive <Sonner>’s theme prop.

Needed after consolidation? No. next-themes is already decided to be dropped (per the task context). The sole usage is in sonner.tsx, which must be rewritten to remove the dependency.

Recommendation: Drop. Fix sonner.tsx as noted above.


What it is. A large icon collection aggregator (react-icons/lu, react-icons/fa, etc.) providing thousands of icons from various icon sets as React components.

Where it is used. One file: src/canary-refactor/components/columnPresets.tsx — imports { LuCaptions } from react-icons/lu.

Needed after consolidation? No. The project design system uses lucide-react as its canonical icon library (configured in components.json and established in the main clone). LuCaptions is a Lucide icon available directly from lucide-react as CaptionsIcon. The canary-refactor/ directory is transitional prototype code, not a consolidation target. Using react-icons alongside lucide-react creates a redundant icon dependency.

Recommendation: Drop. Replace LuCaptions with the equivalent lucide-react import before or during consolidation.


What it is. The shadcn CLI tool (npx shadcn add <component>). It scaffolds component files from the shadcn/ui registry.

Where it is used. Not imported anywhere in source code. Referenced only in package.json and components.json (the CLI configuration file).

Needed after consolidation? No. The CLI is a scaffolding aid, not a runtime or build-time dependency. It should not be pinned in package.json; maintainers can run npx shadcn@latest on demand. Including it adds a versioned entry that drifts without providing value.

Recommendation: Drop. Remove from package.json; run via npx shadcn@latest add <component> when needed.


Section titled “9. @storybook/addon-links (devDependency, ^10.2.17)”

What it is. A Storybook addon that adds story-to-story linking utilities (linkTo, <LinkTo> component).

Where it is used. It is listed in package.json but not registered in .storybook/main.ts (addons array only contains @storybook/addon-docs and msw-storybook-addon). No source file imports from it. The CHANGELOG notes it as “added” in v4.0.0 alongside radix-ui and shadcn, suggesting it was added in bulk.

Needed after consolidation? Conditionally. If no stories use linkTo / <LinkTo>, it has no functional value and adds to install weight. However, it is a lightweight, zero-configuration addon that Storybook itself often registers automatically as part of its essential addons bundle. Keeping it costs little.

Recommendation: Conditionally keep. Verify whether any MDX or story files in the worktree use linkTo; if none do, drop it. If the Storybook essential-addons bundle already includes it, the explicit package.json entry is redundant regardless.


What it is. A JavaScript implementation of zlib compression/decompression (inflate/deflate).

Where it is used. No file in the worktree imports from pako. Zero usages found across src/, .storybook/, and configuration files.

Needed after consolidation? No.

Recommendation: Drop. Unused dependency.


What it is. A QR code scanning library that uses the browser’s camera or image input.

Where it is used. No file in the worktree imports from qr-scanner. Zero usages found.

Needed after consolidation? No.

Recommendation: Drop. Unused dependency.


12. react-dropzone (devDependency, ^15.0.0)

Section titled “12. react-dropzone (devDependency, ^15.0.0)”

What it is. A React hook and component for drag-and-drop file uploads.

Where it is used. No file in the worktree imports from react-dropzone. Zero usages found.

Needed after consolidation? No.

Recommendation: Drop. Unused dependency.


PackageSectionRecommendationRationale
radix-uiproductionKeepReplaces individual @radix-ui/* packages; used in 14 ui component files
@reduxjs/toolkitdevDependencyKeepRequired by Dev Witness / Canary Refactor Storybook decorator
react-reduxdevDependencyKeepRequired by same Storybook decorator alongside @reduxjs/toolkit
redux-persistdevDependencyKeepVendored frontend code depends on it; Vite build shim requires it
sonnerdevDependencyKeepLive toast feedback in supplier use-cases and canary-refactor stories; fix sonner.tsx to remove next-themes dependency
next-themesdevDependencyDropDecided upstream; sole usage in sonner.tsx which must be rewritten
react-iconsdevDependencyDropOne icon in transitional code; lucide-react is the canonical library
shadcndevDependencyDropCLI scaffolding tool; use npx shadcn@latest on demand instead
@storybook/addon-linksdevDependencyConditionally keepNot registered or imported; drop if no linkTo usage found
pakodevDependencyDropUnused
qr-scannerdevDependencyDropUnused
react-dropzonedevDependencyDropUnused

The package publishes as @arda-cards/design-system via GitHub Packages. The publish workflow (npm run build:lib) invokes LIB_BUILD=true vite build.

The Vite library build config (vite.config.ts) externalizes only:

react, react-dom, react/jsx-runtime, ag-grid-community, ag-grid-react, lucide-react

Everything else imported by the entry points (index.ts, canary.ts, extras.ts, types/*.ts) is bundled into the dist. This means production dependencies in package.json are included in the bundle — consumers don’t install them separately.

EntryExport pathContent
index.ts@arda-cards/design-systemStable (nominal) components
canary.ts@arda-cards/design-system/canaryIn-development canary components
extras.ts@arda-cards/design-system/extrasSupplementary extras components
types/*.ts@arda-cards/design-system/types/*Shared type definitions
styles/*@arda-cards/design-system/styles/*CSS files (copied, not bundled as JS)
PackageCurrent tierReaches published entry point?Correct tier
class-variance-authoritydependencyYes — canary atoms, extras atomsdependency (correct, bundled)
clsxdependencyYes — cn() utilitydependency (correct, bundled)
tailwind-mergedependencyYes — cn() utilitydependency (correct, bundled)
@radix-ui/react-tooltipdependencyYes — stable componentsRemove — superseded by radix-ui
radix-uidependency (new)Yes — canary primitives → canary organisms → canary.tsdependency (correct, bundled)
sonnerdevDependencyNo — only in use-cases/ stories and canary-refactor/ (not exported)devDependency (correct)
@reduxjs/toolkitdevDependencyNo — only in Storybook decoratordevDependency (correct)
react-reduxdevDependencyNo — same decoratordevDependency (correct)
redux-persistdevDependencyNo — same decorator + Vite transformdevDependency (correct)
tw-animate-cssdevDependencyCSS only — inlined by PostCSS/Tailwind at build timedevDependency (correct)

radix-ui: bundled dependency vs peer dependency

Section titled “radix-ui: bundled dependency vs peer dependency”

Should radix-ui be a peer dependency (consumer installs it) or a bundled dependency (included in dist)?

The project pattern is clear: class-variance-authority, clsx, and tailwind-merge are all bundled dependencies, not peers. Only framework-level packages (react, react-dom) and heavy domain packages (ag-grid-*) are peers. radix-ui follows the same pattern as CVA — it’s a UI utility library that should be bundled for consumer simplicity.

Decision: radix-ui stays as a production dependency (bundled). @radix-ui/react-tooltip is removed.

No devDependencies need promotion to runtime or peer dependencies. All new devDependencies are correctly classified — they’re consumed only by Storybook decorators, stories, or build tooling, none of which reach the published entry points. The only production dependency change is adding radix-ui and removing @radix-ui/react-tooltip.