shadcn/ui Bulk Installation - Risk Analysis
Risk Level: 🟢 LOW to 🟡 MODERATE
Installing all shadcn/ui components is SAFE for your monorepo with proper precautions. Here’s why:
Key Safety Factors
Section titled “Key Safety Factors”✅ React versions are locked via resolutions (18.3.1)
✅ shadcn/ui only adds to packages/ui-web (isolated package)
✅ Your apps import from workspace packages (won’t be affected directly)
✅ Radix UI is web-only (no React Native conflicts)
✅ All dependencies use caret ranges (compatible with your existing versions)
Risk Assessment by Category
Section titled “Risk Assessment by Category”1. Dependency Conflicts 🟡 MODERATE RISK
Section titled “1. Dependency Conflicts 🟡 MODERATE RISK”Potential Issues:
Section titled “Potential Issues:”A. React Version Conflicts
// Your current setup (GOOD):"resolutions": { "react": "18.3.1", // ✅ Locked "react-dom": "18.3.1" // ✅ Locked}
// shadcn/ui components require:"peerDependencies": { "react": "^18.0.0", // ✅ Compatible (18.3.1 satisfies ^18.0.0) "react-dom": "^18.0.0" // ✅ Compatible}Status: ✅ NO CONFLICT - Your locked versions satisfy all requirements
B. Radix UI Version Conflicts
// You currently have:"@radix-ui/react-navigation-menu": "^1.2.14" // From NavigationMenu
// Bulk install will add ~40 more Radix packages:"@radix-ui/react-dialog": "^1.1.4""@radix-ui/react-dropdown-menu": "^2.1.4"// ... etcPotential Issue: Some Radix packages may have peer dependency on different @radix-ui/react-* versions
Mitigation: Yarn 4 handles this automatically with hoisting
Status: 🟡 MINOR RISK - Yarn will resolve, but watch for warnings
C. Tailwind CSS Conflicts
// Your current setup:"tailwindcss": "3.4.10" // At root
// shadcn/ui requires:"tailwindcss": ">=3.0.0" // ✅ CompatibleStatus: ✅ NO CONFLICT
D. Class Utility Conflicts
// You currently have:"clsx": "^2.1.1", // ✅ At root AND packages/ui-web"tailwind-merge": "^3.3.1" // ✅ At root AND packages/ui-web
// shadcn/ui will want to add these to ui-web:"clsx": "^2.1.1", // ✅ Same version"tailwind-merge": "^3.3.1" // ✅ Same versionStatus: ✅ NO CONFLICT - Already installed with correct versions
2. React Native Compatibility 🟢 LOW RISK
Section titled “2. React Native Compatibility 🟢 LOW RISK”Analysis:
Section titled “Analysis:”Your monorepo has React Native apps (mobile folders) and web packages (ui-web, ui-web).
Good News:
- shadcn/ui components live in
packages/ui-web/(web-only package) - React Native apps don’t import from
@cloudalt-frontend/ui-web - React Native apps have their own UI packages:
ui-[brand-name]
packages/ui-web/ ← shadcn/ui goes here (WEB ONLY) └── NavigationMenu └── Button └── Card └── etc
packages/ui-homestay/ ← React Native componentspackages/ui-stay-match/ ← React Native componentspackages/ui-bonjour-services/ ← React Native componentsPotential Issue: If someone accidentally tries to import shadcn component into React Native app
Mitigation:
- Keep clear naming:
@cloudalt-frontend/ui-webvs@cloudalt-frontend/ui-homestay - Add comment in ui-web package.json:
{"name": "@cloudalt-frontend/ui-web","description": "⚠️ WEB ONLY - Do not import into React Native apps",}
- TypeScript will catch incompatible imports (Radix uses DOM APIs)
Status: 🟢 LOW RISK - Clear package boundaries prevent issues
3. Bundle Size Impact 🟡 MODERATE RISK
Section titled “3. Bundle Size Impact 🟡 MODERATE RISK”Before Installation:
Section titled “Before Installation:”packages/ui-web/ └── dependencies: 4 packages (~50KB) - @radix-ui/react-navigation-menu - class-variance-authority - clsx - tailwind-mergeAfter Installation (All 50+ Components):
Section titled “After Installation (All 50+ Components):”packages/ui-web/ └── dependencies: ~35 packages (~500KB gzipped) - All 40+ @radix-ui/react-* packages - date-fns (for Calendar) - react-day-picker (for Calendar) - embla-carousel-react (for Carousel) - recharts (for Chart components) - sonner (for Toast) - vaul (for Drawer) - react-hook-form (for Form)Potential Issues:
- Larger
node_modules(disk space) - Longer
yarn installtime - Heavier package if all exported
Mitigation:
- ✅ Tree-shaking enabled (Vite + ES modules)
- ✅ Only imported components get bundled
- ✅ Apps won’t bloat unless they import
- ✅ You can remove unused components later
Example Bundle Impact:
// App imports ONLY Button and Card:import { Button, Card } from '@cloudalt-frontend/ui-web';
// Bundle includes:// - Button (~5KB)// - Card (~3KB)// - Shared utils (~10KB)// Total: ~18KB (NOT 500KB!)Status: 🟡 MODERATE RISK - Manageable with tree-shaking
4. TypeScript Compilation 🟢 LOW RISK
Section titled “4. TypeScript Compilation 🟢 LOW RISK”Potential Issues:
Section titled “Potential Issues:”A. Type Definition Conflicts
// Multiple @radix-ui packages exporting similar typesimport type { ComponentPropsWithoutRef } from 'react';Mitigation:
- Radix UI packages are well-typed
- No known conflicts between packages
- Your
typescript: "~5.7.2"is up-to-date
Status: 🟢 LOW RISK
B. Build Time Impact
Before: ~10 seconds to build packages/ui-webAfter: ~15-20 seconds (50+ components)Status: 🟢 LOW RISK - Acceptable increase
5. Storybook Performance 🟡 MODERATE RISK
Section titled “5. Storybook Performance 🟡 MODERATE RISK”Current State:
Section titled “Current State:”Stories: ~20-30 componentsLoad Time: ~3-5 secondsAfter Adding 50+ Components:
Section titled “After Adding 50+ Components:”Stories: ~80-100 components (existing + shadcn)Load Time: ~8-12 seconds (estimated)Potential Issues:
- Slower Storybook startup
- More memory usage during development
- Larger Storybook build
Mitigation:
- Use Storybook’s lazy loading (already enabled)
- Split stories by category
- Use
--no-manager-cacheflag if needed - Consider separate Storybook instances per category
Status: 🟡 MODERATE RISK - May need optimization
6. Workspace Dependency Graph 🟢 LOW RISK
Section titled “6. Workspace Dependency Graph 🟢 LOW RISK”Current Dependencies:
Section titled “Current Dependencies:”packages/ui-web → react, react-dom (peers)apps/[app]/web → @cloudalt-frontend/ui-webAfter Installation:
Section titled “After Installation:”packages/ui-web → react, react-dom, 35+ radix packagesapps/[app]/web → @cloudalt-frontend/ui-web (unchanged)Key Point: Apps don’t care about ui-web’s internal dependencies!
Status: 🟢 LOW RISK - Encapsulation works correctly
7. Breaking Changes Risk 🟢 LOW RISK
Section titled “7. Breaking Changes Risk 🟢 LOW RISK”What Could Break:
Section titled “What Could Break:”A. Existing NavigationMenu
- ❌ Won’t break - CLI won’t overwrite without
--overwriteflag - ✅ Your current NavigationMenu stays intact
B. Existing Button (if you have custom one)
// Your existing Button in packages/ui-web/src/components/Button// Solution: Different paths = no conflict!C. CSS Variable Conflicts
/* You already have these (from NavigationMenu): */:root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; /* etc */}
/* CLI won't override these if they exist */Status: 🟢 LOW RISK - CLI respects existing files
Breaking Change Scenarios & Prevention
Section titled “Breaking Change Scenarios & Prevention”Scenario 1: Dependency Version Bump Forces Breaking Change
Section titled “Scenario 1: Dependency Version Bump Forces Breaking Change”Example:
// Radix releases breaking change:"@radix-ui/react-dialog": "^2.0.0" // Major version bump
// Your NavigationMenu uses:"@radix-ui/react-navigation-menu": "^1.2.14" // Depends on Radix corePrevention:
- ✅ Pin exact versions instead of caret ranges:
"@radix-ui/react-dialog": "1.1.4" // Exact, not ^1.1.4
- ✅ Use
resolutionsto force versions:"resolutions": {"@radix-ui/react-*": "~1.x.x"} - ✅ Test before upgrading
Likelihood: 🟡 MODERATE (Radix is stable but evolves)
Scenario 2: Tailwind Class Name Collision
Section titled “Scenario 2: Tailwind Class Name Collision”Example:
// Your existing component:<button className="btn btn-primary">Custom</button>
// shadcn Button component:<Button className="inline-flex items-center ...">shadcn</Button>
// Collision? NO - different classes!Prevention:
- ✅ shadcn uses utility-first Tailwind (no custom classes)
- ✅
cn()utility merges classes safely - ✅ Your custom classes won’t conflict
Likelihood: 🟢 LOW (different styling approaches)
Scenario 3: Import Path Conflicts
Section titled “Scenario 3: Import Path Conflicts”Example:
// You might have:import { Button } from '@cloudalt-frontend/ui-web';
// After bulk install:import { Button } from '@cloudalt-frontend/ui-web'; // Which Button?!Prevention:
- ✅ Organize by category:
// Old custom button:export * from './components/custom/Button';// New shadcn button:export * from './components/forms/button';export { Button as ShadcnButton } from './components/forms/button';
- ✅ Use explicit exports:
packages/ui-web/src/index.ts export { Button as CustomButton } from './custom/Button';export { Button as ShadcnButton } from './components/ui/button';
Likelihood: 🟡 MODERATE (if you have existing components with same names)
Scenario 4: Yarn Install Failures
Section titled “Scenario 4: Yarn Install Failures”Example:
yarn install# Error: Could not resolve peer dependency @radix-ui/react-compose-refsPrevention:
- ✅ Use
--ignore-scriptsif needed:Terminal window yarn install --ignore-scripts - ✅ Clear cache if stuck:
Terminal window yarn cache cleanrm -rf node_modulesyarn install - ✅ Use Yarn 4’s
nodeLinker: node-modules(you already have this)
Likelihood: 🟢 LOW (Yarn 4 is robust)
Recommended Safe Installation Strategy
Section titled “Recommended Safe Installation Strategy”Phase 1: Test in Isolation (30 min)
Section titled “Phase 1: Test in Isolation (30 min)”# 1. Create safety checkpointcd /Users/work-station/company/cloudalt-frontendgit checkout -b test/shadcn-bulk-installgit add .git commit -m "checkpoint: before shadcn bulk install"
# 2. Install to ui-web packagecd packages/ui-webnpx shadcn@latest add button card input alert # Start with 4 components
# 3. Check for issuescd ../..yarn installyarn build # Build all packagesSuccess Criteria:
- ✅ No yarn install errors
- ✅ No TypeScript errors
- ✅ Storybook still loads
- ✅ Existing components still work
Phase 2: Gradual Rollout (2-3 hours)
Section titled “Phase 2: Gradual Rollout (2-3 hours)”# Install by category (safer than --all at once)
# Round 1: Core UI (10 components)cd packages/ui-webnpx shadcn@latest add button input textarea select checkbox radio-group switch label badge avatar
# Testcd ../..yarn storybook # Verify in Storybook
# Round 2: Layout (10 components)cd packages/ui-webnpx shadcn@latest add card separator sheet drawer tabs accordion collapsible dialog alert-dialog
# Round 3: Feedback (10 components)npx shadcn@latest add toast tooltip popover hover-card progress skeleton alert
# Round 4: Navigation (5 components)npx shadcn@latest add breadcrumb menubar dropdown-menu context-menu pagination
# Round 5: Data & Advanced (15+ components)npx shadcn@latest add table calendar chart carousel date-picker sliderBenefit: Catch issues early, easier to rollback
Phase 3: Validation (1 hour)
Section titled “Phase 3: Validation (1 hour)”# 1. Run all checksyarn nx run-many --target=build --allyarn nx run-many --target=lint --allyarn nx run-many --target=test --all
# 2. Build Storybookyarn build-storybook
# 3. Test in one appcd apps/bonjour_services/bonjour_it_com/web# Import and test shadcn componentsRollback Plan
Section titled “Rollback Plan”If Something Breaks:
Section titled “If Something Breaks:”Option 1: Git Revert (Safest)
# If you committed checkpoint:git reset --hard HEAD~1
# If you want to keep other changes:git checkout HEAD~1 -- packages/ui-web/Option 2: Selective Removal
# Remove problematic componentcd packages/ui-webrm -rf src/components/ui/[component-name]
# Remove from package.json# Edit manually or:yarn remove @radix-ui/react-[component-name]Option 3: Fresh Start
# Delete ui-web and recreatecd packagesrm -rf ui-webmkdir ui-web# Recreate from scratchMonitoring After Installation
Section titled “Monitoring After Installation”1. Check Bundle Sizes
Section titled “1. Check Bundle Sizes”# Build and analyzeyarn nx build ui-webyarn analyze-bundle
# Expected increases:# - node_modules: +50-100MB# - Bundle (if all components used): +500KB gzipped# - Bundle (typical app): +50-100KB gzipped2. Monitor Build Times
Section titled “2. Monitor Build Times”# Before:time yarn nx build ui-web# Expected: ~10-15 seconds
# After:time yarn nx build ui-web# Expected: ~15-25 seconds3. Check for Peer Dependency Warnings
Section titled “3. Check for Peer Dependency Warnings”yarn install 2>&1 | grep "warning"# Look for:# - Unmet peer dependencies# - Conflicting versions# - Deprecated packagesRisk Mitigation Checklist
Section titled “Risk Mitigation Checklist”Before bulk install:
- Create git branch
test/shadcn-bulk-install - Commit current state as checkpoint
- Document current bundle sizes
- Take note of current build times
- List all existing components in ui-web
During install:
- Install in phases (not all at once)
- Test after each phase
- Monitor yarn install output
- Check for TypeScript errors
- Verify Storybook loads
After install:
- Run full build:
yarn nx run-many --target=build --all - Run all tests:
yarn nx run-many --target=test --all - Verify Storybook:
yarn storybook - Test in one app (bonjour_it_com/web)
- Compare bundle sizes
- Update documentation
Final Recommendation
Section titled “Final Recommendation”✅ PROCEED with these precautions:
Section titled “✅ PROCEED with these precautions:”- Use gradual rollout (not
--allat once) - Test in isolated branch first
- Install by category (10-15 components per round)
- Validate after each round
- Monitor for warnings
🛡️ Safety Nets in Place:
Section titled “🛡️ Safety Nets in Place:”- ✅ React versions locked via resolutions
- ✅ Package isolation (ui-web is separate)
- ✅ Tree-shaking prevents bloat
- ✅ Git allows easy rollback
- ✅ Yarn 4 handles conflicts well
📊 Risk Summary:
Section titled “📊 Risk Summary:”| Risk Category | Level | Mitigation |
|---|---|---|
| Dependency Conflicts | 🟡 Moderate | Locked React versions, gradual install |
| React Native Compat | 🟢 Low | Clear package boundaries |
| Bundle Size | 🟡 Moderate | Tree-shaking, selective imports |
| TypeScript | 🟢 Low | Well-typed packages |
| Storybook Perf | 🟡 Moderate | Lazy loading, category split |
| Breaking Changes | 🟢 Low | Git rollback, pinned versions |
Overall Risk: 🟡 LOW-MODERATE - Safe to proceed with proper testing
Questions Before Proceeding?
Section titled “Questions Before Proceeding?”- Do you want me to create the test branch and do Phase 1 (test install)?
- Should we start with just 10 core components to validate?
- Do you have any existing components in ui-web that might conflict?
- What’s your preferred rollback strategy if issues arise?