Introduction
CDS v8 is our most feature packed release ever! Including but not limited to:
- 🔮 Expanded styling and customization options
- 🔥 Faster renders and smaller flamegraphs
- 🦾 Improved accessibility of components and theming
- 🧩 Simplified and more predictable internal architecture
To enable global theming and style customization for all CDS components, some APIs were deprecated or outright deleted. We appreciate the impact this will have on teams adopting CDS v8 and are committed to supporting developers through this upgrade 🏎️
If you experience any trouble migrating we're ready to help! Just reach out via Slack.
New Packages
@coinbase/cds-common@8.1.0@coinbase/cds-mobile@8.1.0@coinbase/cds-mobile-visualization@3.0.0@coinbase/cds-web@8.1.0@coinbase/cds-web-visualization@3.0.0@coinbase/cds-icons@5.0.0@coinbase/cds-lottie-files@3.0.0
Migration Script
Before diving into the breaking changes, we highly recommend starting with our automated migration script. The @coinbase/cds-migrator package handles many of the repetitive transformations automatically, saving you significant time and effort.
What the Migration Script Automates
The migration script handles these transformations automatically:
- Icon migrations: Active/inactive suffix removal, renamed icons, and active prop additions
- Color token updates: Converts old color names to new semantic tokens
- Border radius/width tokens: Updates string tokens to numeric values and CSS variables
- Import path updates: Fixes outdated import paths throughout your codebase
- Component prop changes: Updates
responsiveConfigto direct responsive props - Hook migrations: Updates
useSpectrum,useAccessibleForeground, and other deprecated hooks
Look for the
Running the Migration Script (Internal to Coinbase)
For detailed instructions on running the migration script, refer to the Migrator Guide, reach out via Slack if you need help finding the guide.
What Requires Manual Migration
While the script handles most changes, some breaking changes require manual intervention:
- ThemeProvider setup: Converting from legacy providers to the new ThemeProvider
- Scale/density system removal: Creating custom dense themes
- Custom styling: Updating CSS-in-JS and styled components
- Type definitions: Updating polymorphic component prop types
- Complex component patterns: Advanced usage that can't be automatically detected
Dependency Updates
Linaria Dependency Requirements
Important: If you are using @linaria/core in your application code, you must properly declare it in your package.json dependencies. In CDS v8, we moved @linaria/core from dependencies to devDependencies, which means it will no longer be automatically available to consuming applications.
This is required if your application directly imports from @linaria/core:
Alternative for cx function: If you're only using the cx function from @linaria/core, you can import it directly from @coinbase/cds-web instead of adding the dependency:
💥 Breaking Change Overview
Here's a high-level overview of the major breaking changes in v8:
🎨 Theming System Changes
- New ThemeProvider: Requires
themeandactiveColorSchemeprops (no defaults) - Provider consolidation:
SpectrumProvider,DarkModeProvider,LightModeProvider, and scale providers replaced by singleThemeProvider - Spectrum vs Color: Distinction between spectrum (
"r,g,b") and color (CSS values) - prefer color tokens - CSS variables: Preferred way to access theme values on web for performance
- No inheritance: ThemeProvider no longer auto-inherits from parent providers
- Color scheme classes: ThemeProvider adds
.dark/.lightclasses to container - Scale/density removed: No scale system - create custom themes for dense styles
- Theme inversion:
invertSpectrum→invertColorScheme, newInvertedThemeProvider
🎭 Style System Changes
- Safari support: Requires Safari 15.4+ for web (CSS layers,
:focus-visible,:has()) - CSS layers: All CDS styles scoped to
@layer cdsfor better specificity control - CSS reset: New global styles override browser defaults for polymorphic components
- Improved polymorphism: Better type safety for polymorphic components with
asprop - Elevation simplified: Streamlined system without
ElevationProvider/useElevationStyles - CSS-in-JS: Static CSS variables and Linaria-compiled styles instead of runtime calculations
🪙 Token Changes
- Color tokens: Complete redesign with semantic naming:
- Foreground:
foreground→fg,primary→fgPrimary - Background:
background→bg,primary→bgPrimary - Border:
line→bgLine,primary→bgLinePrimary
- Foreground:
- Border radius: String tokens → numeric (
rounded→200,roundedFull→1000) - Border width: String tokens → numeric (
button→100,focusRing→200) - Import paths: Many token imports moved to new package locations
⭐ Icon Changes
- Active states: Controlled by
activeprop instead of icon name suffixes (starFilled→<Icon name="star" active />) - Renamed icons: Several icons renamed for clarity
- Removed props:
borderedprop removed from Icon component - Removed components:
NavigationIconandNavigationIconButtonremoved
🧩 Component Changes
- Responsive props:
responsiveConfigprop removed, use direct responsive props - Media queries:
deviceBreakpoints/deviceMqs→breakpoints/media - Removed providers:
DevicePreferencesProvider,BreakpointsProvider,FeatureFlagProvider - Removed components: Several utility components removed or renamed (
InteractableContent→Interactable) - Import paths: Component import paths updated to new package structure
🔧 Hook & Utility Changes
- useTheme: Replaces
useSpectrum,useScale, and other theming hooks - Accessibility:
useAccessibleForeground→getAccessibleColorwith new API - Spacing:
useSpacingScale/useSpacingValue→ direct theme token access - Typography:
useTypographyStyles→ direct theme property access - Scale hooks:
useScale,useScaleConditionalremoved (no scale system) - Palette utilities:
paletteValueToRgbaString,usePalette→ theme-based approach
📝 Type Changes
- Polymorphic types: Now require type arguments (
TextProps<'h1'>,BoxProps<'div'>) - Default elements:
TextDefaultElement,BoxDefaultElementexported for defaults - Removed types:
HTMLNonHeadingTextTags,NoopFn,SetState,Overflow,IconPixelSize - Updated types:
GapSpacing→ThemeVars.Space
Theming Updates
The New ThemeProvider
In CDS v8, the theming system has been completely redesigned. The new ThemeProvider is the single source of truth for all styling and requires both theme and activeColorScheme props.
Basic Setup:
Custom Theme:
The useTheme Hook
The useTheme() hook provides access to the current theme and active color scheme:
Performance Note: Whenever possible, use CSS variables on web instead of the useTheme() hook to ensure best performance.
Note about Spectrum vs Color
The difference between theme.spectrum and theme.color is that spectrum values are just "r,g,b" strings while color values are valid CSS values. The theme.color values have semantic names and you should always prefer to use these values instead of spectrum values when styling UI.
CSS Variables (Web)
On web, ThemeProvider creates CSS variables for all theme values:
| JS variable | CSS variable |
|---|---|
theme.color.bgPrimary | --color-bgPrimary |
theme.space[2] | --space-2 |
theme.borderRadius[200] | --borderRadius-200 |
Color Scheme Classes (Web)
On web, the ThemeProvider adds a .dark or .light class to its container element depending on the activeColorScheme. You can use this class for writing styles specific to the color schemes.
ThemeProvider Requirements
The ThemeProvider no longer includes default values for the theme or activeColorScheme props. These props are now required on every ThemeProvider. Any component calling the useTheme() hook without a parent ThemeProvider will throw an error, and component styles will be broken.
ThemeProvider Inheritance
The ThemeProvider no longer automatically inherits and merges themes from parent ThemeProviders. However you can manually inherit the theme if you want:
Scale/Density System Removed
In CDS v8, the concept of scale/density no longer exists. To achieve dense/xSmall scale styles, you can create a new theme that updates the values of space, fontSize, lineHeight, controlSize, iconSize, etc.
We have an example coinbaseDenseTheme you can use to emulate the old dense/xSmall scale styles - web link and mobile link. However you need to copy this theme into your application, it will be deleted from CDS in the next major release.
Inverting the Theme
Some component props like invertSpectrum allow inverting a component tree to use the opposite of the current activeColorScheme. These props have been renamed to invertColorScheme.
We have a new InvertedThemeProvider that will do this inversion automatically if the opposite color palette is defined in the theme. If the opposite colors are not defined then the InvertedThemeProvider does nothing.
Removed Theming APIs
The following theming-related APIs have been removed:
Providers:
SpectrumProvider/RootSpectrumProvider- see migration instructionsDarkModeProvider/LightModeProvider- see migration instructionsScaleProvider/RootScaleProvider/DenseScaleProvider/NormalScaleProvider- see dense theme migration
Hooks:
useSpectrum- Replaced byuseThemehookuseScale/useScaleConditional- see migration instructionsuseSpectrumConditional- see migration instructions
Style Updates
Safari Web Support
CDS v8 for web supports Safari 15.4 and later, released March 14, 2022. We make use of features like CSS layers and selectors like :focus-visible and :has().
CSS Layers
All CDS web CSS is now scoped to a CSS layer for better specificity control:
This causes CDS CSS to have lower style specificity than styles that are not on a CSS layer - which makes it easy to ensure your custom styles always overwrite CDS. This solves problems with non-deterministic styles based on stylesheet load order.
New Web Global Styles
CDS web global styles now include a CSS reset which override the browser default styles for some elements. This ensures that polymorphic components render correctly, regardless of their HTML element. See the full style reset here.
Improved Polymorphism
Many web components are now fully polymorphic with strong type checking:
Elevation Changes
CDS v8 introduces a simplified elevation system that replaces the complex context-based approach with streamlined implementations for both web and mobile platforms. The elevation prop continues to support the same levels (0, 1, 2), but the underlying implementation has been significantly simplified for better performance and developer experience.
In CDS web, the new elevation system uses static CSS variables and Linaria-compiled styles instead of runtime calculations. v8 removes the ElevationProvider context and useElevationStyles hook in favor of direct component props. This change eliminates the need for context providers and custom hooks while providing more consistent visual results across light and dark themes.
In CDS mobile, the complex ElevationConfigsProvider and createElevationConfigForSpectrum system has been replaced with direct theme-based styling through the getElevationStyles function, removing the need for context providers and wrapper components.
Removed Style APIs
The following style-related APIs have been removed:
Providers:
ElevationConfigsProvider- see migration instructions
Hooks:
useTypographyStyles- see migration instructionsuseThemeProviderStyles- see migration instructionsuseSpacingStyles- see migration instructionsuseSpacingScale/useSpacingValue- see migration instructions
New Style Tokens
CDS v8 introduces many new themeable style tokens. The value of these tokens is configured in the ThemeProvider.
Example: Using New Color Tokens
CSS Variables in Styled Components
Mobile StyleSheet Updates
Token Updates
Foreground Color Token Mapping
| v7 Token | v8 Token |
|---|---|
foreground | fg |
foregroundMuted | fgMuted |
primary | fgPrimary |
primaryForeground | fgInverse |
secondary | bgSecondary |
secondaryForeground | fg |
positive | fgPositive |
positiveForeground | fgInverse |
negative | fgNegative |
negativeForeground | fgInverse |
warning | bgWarning |
warningForeground | fgWarning |
Background Color Token Mapping
| v7 Token | v8 Token |
|---|---|
background | bg |
backgroundAlternate | bgAlternate |
backgroundOverlay | bgOverlay |
backgroundInverse | bgInverse |
primary | bgPrimary |
secondary | bgSecondary |
positive | bgPositive |
negative | bgNegative |
warning | bgWarning |
primaryWash | bgPrimaryWash |
negativeWash | bgNegativeWash |
transparent | transparent |
Border Color Token Mapping
| v7 Token | v8 Token |
|---|---|
primary | bgLinePrimary |
primaryWash | bgLinePrimarySubtle |
secondary | bgLine |
positive | bgPositive |
negative | bgNegative |
line | bgLine |
lineHeavy | bgLineHeavy |
transparent | transparent |
warning | bgWarning |
warningForeground | fgWarning |
Border Radius Token Mapping
| v7 Token | v8 Token |
|---|---|
roundedNone | 0 |
roundedSmall | 100 |
rounded | 200 |
roundedMedium | 300 |
roundedLarge | 400 |
roundedXLarge | 500 |
roundedFull | 1000 |
Border Width Token Mapping
| v7 Token | v8 Token |
|---|---|
none | 0 |
button | 100 |
card | 100 |
checkbox | 200 |
radio | 200 |
sparkline | 200 |
focusRing | 200 |
input | 100 |
Removed Token APIs
The following token-related APIs have been removed:
Functions:
paletteValueToRgbaString- see migration instructionspaletteAliasToRgbaString- see migration instructions
Hooks:
usePalette- see migration instructionsusePaletteConfig- see migration instructions
Constants:
defaultPalette- see migration instructions
Icon Updates
Renamed Icons
The following icons have been renamed:
visibleInactive→invisiblefollowInactive→followAddvisibleFilled→visiblerocketInactive→noRocketfollowActive→following
Active State Changes
For certain UI icons whose names end with Active or Inactive suffixes, their active state is now controlled by a boolean active prop -- see the complete migration instructions.
Affected icons: See the complete UI Icon Exceptions list in the migration instructions.
Affected components: Icon, CellMedia, IconButton, Button, Banner.
Removed Icon APIs
The following icon-related APIs have been removed:
Props:
borderedprop fromIconcomponent - see migration instructions
Components:
NavigationIcon&NavigationIconButton- Use standardIconandIconButtoninstead - see migration instructions
Component Updates
Responsive Props
The responsiveConfig prop has been removed. Pass responsive values directly to each prop:
Breakpoints & Media Queries
Import paths and values have been updated:
Removed Component APIs
The following component-related APIs have been removed:
Providers:
DevicePreferencesProvider- see migration instructionsBreakpointsProvider- see migration instructionsFeatureFlagProvider- see migration instructions
Components:
InteractableContent- Renamed toInteractable- see migration instructions
Hooks:
useMergedRef- see migration instructionsuseToggler- see migration instructionsuseMediaQuery/useDeviceColorScheme- Use theme-based approach insteaduseIconSize/useAvatarSize- see migration instructionsuseInteractableHeight- see migration instructions
Utilities:
overflowClassName- Replace with inline CSS:{ overflow: auto; text-overflow: unset; white-space: normal; }- see migration instructions
Type Updates
Polymorphic Component Props
All polymorphic component prop types now require a type argument:
Removed Type APIs
The following type-related APIs have been removed:
Types:
HTMLNonHeadingTextTags- Define locally if needed - see migration instructionsLinkTypography- Replace withLinkProps<LinkDefaultElement>['font']BoxElement- UseBoxDefaultElementor define askeyof JSX.IntrinsicElementsOverflow- Define locally as{ overflow?: 'visible' | 'hidden' | 'scroll' | 'auto' | 'clip' }- see migration instructions
Constants:
paletteForegrounds,paletteBackgrounds,paletteBorders
FAQ
Why upgrade to v8?
CDS v8 brings faster performance, full theming and customization, powerful new APIs, and improved accessibility. It also includes React 19 support, a rebuilt docs site, and an MCP server to streamline development.
What new features are included?
This release includes:
- Theming and customization
- Drastically improved performance
- CDS MCP Server
- Powerful new APIs
- All new docs site
- React 19 support
- 5 new components
Are migration scripts available?
Yes! We provide the @coinbase/cds-migrator package to assist with automated migration. For detailed instructions, refer to the Migrator Guide.
Appendix: Detailed Migration Instructions
This section provides step-by-step instructions for migrating specific APIs and components that have been removed or updated. Each section corresponds to the breaking changes outlined above.
Note: Code examples may show platform-specific import paths (e.g., @coinbase/cds-web or @coinbase/cds-mobile). Adjust the import paths based on your target platform.
Theming Migration Instructions
See Theming Updates for overview
Migrating DevicePreferencesProvider
On Web:
On Mobile:
Migrating BreakpointsProvider
Steps:
- Remove the
BreakpointsProviderimport - Add
import { MediaQueryProvider } from '@coinbase/cds-web/system/MediaQueryProvider' - Replace
BreakpointsProviderwithMediaQueryProvider - Add the
defaultValuesprop if needed
Migrating RootSpectrumProvider
Steps:
- Replace
RootSpectrumProviderwithThemeProvider - Add your own device color scheme detection logic using
useDeviceColorScheme()hook - Implement user preference state management
Migrating DarkModeProvider / LightModeProvider
Steps:
- Remove
DarkModeProviderandLightModeProviderimports - Replace with
ThemeProviderthat hasactiveColorSchemeset to"dark"or"light"
Migrating FeatureFlagProvider
Steps:
- Simply remove
FeatureFlagProviderfrom your component tree - The benefits it provided are now automatic in v8
What was automated:
- CSS gap support
- Fabric support
- Other modern behaviors that required opt-in
Migrating ElevationConfigsProvider
Steps:
- Remove
ElevationConfigsProviderfrom your component tree - The elevation system has been simplified and no longer needs this provider
Creating Dense Themes
Related to the scale system removal mentioned in Theming Updates
Steps:
- Copy the example
coinbaseDenseThemefrom CDS - Create theme switching logic
Example:
Style Migration Instructions
See Style Updates for overview
Migrating useThemeProviderStyles
Steps:
- Update the import path:
import { useThemeProviderStyles } from '@coinbase/cds-web/system/ThemeProvider'; - Remove
classNamereferences (no longer returned) - Update hook usage
Migrating useTypographyStyles
Related to new style tokens mentioned in Style Updates
On Web:
On Mobile:
Migrating useSpacingStyles
Steps:
- Remove the import of
useSpacingStyles - Replace with native padding/margin style properties
Token Migration Instructions
See Token Updates for overview and mapping tables
Migrating useSpacingScale / useSpacingValue
On Web:
On Mobile:
Migrating borderRadius Tokens
Refer to Border Radius Token Mapping table
Steps:
- Remove the import of
borderRadius - Replace usage with CSS variables or theme tokens
Migrating borderWidth Tokens
Refer to Border Width Token Mapping table
Steps:
- Remove the import of
borderWidth - Import
useThemeif needed - Replace with theme tokens
Migrating Color Palette Functions
Refer to Color Token Mapping table
paletteValueToRgbaString:
paletteValueToHex:
paletteAliasToRgbaString:
usePalette:
Palette Constants (paletteForegrounds, paletteBackgrounds, paletteBorders):
Steps:
- Identify the palette color name from the v7 array
- Find the corresponding new color token from the color mapping tables
- Replace array access with direct token name
defaultPalette / usePaletteConfig:
Icon Migration Instructions
See Icon Updates for overview
Icon Components with Active States
Related to Active State Changes mentioned above
Component-to-Prop Mapping:
- Icon:
['name', 'active'] - CellMedia:
['name', 'active'] - DotSymbol:
['iconName', 'active'] - IconButton:
['name', 'active'] - InputIcon:
['name', 'active'] - InputIconButton:
['name', 'active'] - Banner:
['startIcon', 'startIconActive'] - Button:
[['startIcon', 'startIconActive'], ['endIcon', 'endIconActive']]
UI Icon Exceptions List:
Only apply active prop logic if the icon name is in this list: add, affiliates, airdrop, artwork, avatar, bell, book, briefcase, calculator, camera, chartBar, chartPie, chartPieCircle, chatBubble, circleCheckmark, circleCross, clock, coinbaseOne, crypto, cryptobasics, currencies, defi, dot, email, error, ethereum, flame, games, gavel, gear, giftCard, group, heart, home, info, institute, keyboard, lightbulb, lightningBolt, lock, marketCap, megaphone, microphone, music, newsFeed, newsletter, nft, orderHistory, paperAirplane, passport, pencil, play, profile, questionMark, regulated, safe, save, shield, sortDoubleArrow, sortDown, sortDownCenter, sortUp, sortUpCenter, soundOff, soundOn, sparkle, speaker, stake, taxesReceipt, telephone, thumbsDown, thumbsUp, trashCan, trophy, unlock, verifiedBadge, visibleFilled, wallet, warning, wrapToken.
Steps:
If the icon name ends with Active or Inactive:
- Remove the suffix from the icon name
- Add the active prop for icons with Active suffix
Example:
Migrating bordered Icon Prop
Related to Removed bordered Prop mentioned above
Steps:
- Find all instances using regex:
<Icon\s+[^>]*\bbordered\b[^>]*> - Remove the
borderedprop - Wrap the Icon in a bordered Box
Example:
Component Migration Instructions
See Component Updates for overview
Migrating NavigationIcon/NavigationIconButton
Related to Removed Components mentioned above
Steps:
- Remove imports:
- Replace with:
- Update component usage:
Migrating InteractableContent
Related to Removed Components mentioned above
Steps:
- Remove import:
import { InteractableContent } from '@coinbase/cds-web/system'; - Import Interactable:
import { Interactable } from '@coinbase/cds-web/system'; - Replace all usage:
<InteractableContent>→<Interactable>
Migrating Responsive Props
Related to Responsive Props mentioned above
The responsiveConfig prop migration is automated by the migration script, but here's the pattern:
Migrating Breakpoints & Media Queries
Related to Breakpoints & Media Queries mentioned above
Steps:
- Update import paths
- Update breakpoint values (note the changes)
Note: Breakpoint values have changed. For example, phone now starts at 0 and media.phone is a max-width query.
Migrating overflowClassName
Related to Removed Utilities mentioned above
Steps:
- Remove the import of
overflowClassName - Replace with equivalent CSS styles
Type Migration Instructions
See Type Updates for overview
Migrating Polymorphic Component Types
Related to Polymorphic Component Props mentioned above
BoxElement:
TextProps:
LinkTypography:
Migrating Removed Types
Related to Removed Types mentioned above
HTMLNonHeadingTextTags:
NoopFn:
SetState:
Overflow:
IconPixelSize:
GapSpacing:
Hook Migration Instructions
Cross-references to various sections above
Migrating useAccessibleForeground
Related to color token changes in Token Updates
Migrating useMergedRef
Migrating useToggler
Migrating useSpectrumConditional
Related to theming changes in Theming Updates
Migrating useInteractableHeight
Migrating useIconSize
Migrating useAvatarSize
Migrating Scale-Related Hooks (No Direct Replacement)
Related to scale system removal in Theming Updates
useScale:
useScaleConditional: