How to customize CoreUI theme in React
Customizing a UI framework to match your brand’s unique identity is a critical step in professional web development. With over 25 years of experience in software development and as the creator of CoreUI, I have designed our React components to be highly flexible and easy to theme. The most efficient and modern way to customize the CoreUI theme in React is by overriding Sass variables before compilation or using CSS custom properties (variables) for runtime adjustments. This approach ensures that your changes are consistent across all components while maintaining the performance and reliability of the library.
Override Sass variables in your main stylesheet or use CSS custom properties on the :root element to globally customize your CoreUI theme.
// custom.scss
// 1. Include your variable overrides BEFORE importing CoreUI
// Override individual color variables — this is safe and preserves all defaults
$primary: #6366f1;
$danger: #ef4444;
$success: #22c55e;
$info: #0ea5e9;
$warning: #f59e0b;
// Override structural variables
$border-radius: 0.5rem;
$border-radius-lg: 0.75rem;
$border-radius-sm: 0.25rem;
// Override component-specific variables
$btn-border-radius: 0.375rem;
$card-border-radius: 0.75rem;
$input-border-radius: 0.375rem;
// 2. Import CoreUI styles — this uses your overrides during compilation
@import '@coreui/coreui/scss/coreui';
To customize CoreUI via Sass, you must create a custom SCSS file where you define your variable overrides before importing the main CoreUI library. By redefining individual variables like $primary or $danger, Sass will use your values during the build process to generate the final CSS. This is safer than overriding the entire $theme-colors map, which would remove all default colors not explicitly listed. This method is incredibly powerful because it allows you to change structural elements, such as border-radii or spacing scales, across the entire framework with just a few lines of code.
If you do need to extend the color map with custom entries while preserving defaults, use map-merge:
@use 'sass:map';
// Add custom colors without losing the defaults
$custom-colors: (
'brand': #6366f1,
'accent': #ec4899
);
$theme-colors: map.merge($theme-colors, $custom-colors);
@import '@coreui/coreui/scss/coreui';
Customizing via CSS Variables
Modern versions of CoreUI (v5+) leverage CSS custom properties extensively, allowing you to change the theme at runtime without recompiling Sass. This is particularly useful for features like dynamic brand color pickers or user-configurable dashboards.
:root {
/* Primary brand colors */
--cui-primary: #0ea5e9;
--cui-primary-rgb: 14, 165, 233;
--cui-secondary: #64748b;
--cui-secondary-rgb: 100, 116, 139;
/* Layout and structure */
--cui-border-radius: 0.5rem;
--cui-border-color: #e2e8f0;
--cui-body-bg: #f8fafc;
--cui-body-color: #1e293b;
/* Component-specific overrides */
--cui-sidebar-bg: #1e293b;
--cui-sidebar-color: #f1f5f9;
--cui-header-bg: #ffffff;
}
[data-coreui-theme='dark'] {
--cui-body-bg: #0f172a;
--cui-body-color: #f1f5f9;
--cui-border-color: #334155;
--cui-header-bg: #1e293b;
--cui-sidebar-bg: #0f172a;
}
By targeting the :root selector or specific theme attributes, you can override the default CSS variables provided by CoreUI. This ensures that components like the CoreUI Buttons automatically adopt your brand colors. This method is the standard approach we use in our Admin Dashboard Template to handle seamless light and dark mode transitions.
Overriding Component-Specific Styles
Sometimes you need to customize a single component rather than the global theme. CoreUI React components accept a className prop, which you can use to apply targeted CSS overrides. For example, if you want a specific Card to have a unique gradient background.
import { CCard, CCardBody } from '@coreui/react'
import './App.css'
const CustomCard = () => {
return (
<CCard className='custom-gradient-card'>
<CCardBody>
This card has a custom theme override.
</CCardBody>
</CCard>
)
}
export default CustomCard
In your App.css, you would then define the .custom-gradient-card class:
.custom-gradient-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
border: none;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.custom-gradient-card .card-body {
padding: 2rem;
}
/* Respect dark mode */
[data-coreui-theme='dark'] .custom-gradient-card {
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
}
This approach keeps your global theme clean while providing the surgical precision needed for unique UI elements. It is a best practice to use utility classes or scoped CSS to prevent side effects in other parts of your application.
Implementing a Dynamic Theme Switcher
If you want to allow users to switch themes dynamically, you can manipulate the data-coreui-theme attribute on the html or body element using React state. This is a common requirement for enterprise-grade applications.
import React, { useEffect, useState } from 'react'
import { CButton, CButtonGroup } from '@coreui/react'
const ThemeSwitcher = () => {
const [theme, setTheme] = useState(() => {
// Persist theme preference in localStorage
return localStorage.getItem('coreui-theme') || 'light'
})
useEffect(() => {
document.documentElement.setAttribute('data-coreui-theme', theme)
localStorage.setItem('coreui-theme', theme)
}, [theme])
return (
<CButtonGroup role='group' aria-label='Theme switcher'>
<CButton
color={theme === 'light' ? 'primary' : 'secondary'}
variant={theme === 'light' ? undefined : 'outline'}
onClick={() => setTheme('light')}
>
Light
</CButton>
<CButton
color={theme === 'dark' ? 'primary' : 'secondary'}
variant={theme === 'dark' ? undefined : 'outline'}
onClick={() => setTheme('dark')}
>
Dark
</CButton>
</CButtonGroup>
)
}
This logic ensures that whenever the theme state changes, the entire application’s CSS variables are updated to reflect the new theme. This is the exact pattern we implement in our React Dashboard Template to provide a polished user experience.
Customizing the Spacing Scale
CoreUI uses a spacing scale for margins and paddings. You can customize this by overriding the $spacers map in Sass. This allows you to tighten or loosen the layout according to your design requirements.
// Override the base spacer unit
$spacer: 1rem;
// Customize the full spacing scale
$spacers: (
0: 0,
1: ($spacer * 0.25), // 4px
2: ($spacer * 0.5), // 8px
3: $spacer, // 16px
4: ($spacer * 1.5), // 24px
5: ($spacer * 3), // 48px
6: ($spacer * 4), // 64px — custom addition
7: ($spacer * 5) // 80px — custom addition
);
// You can also override container max-widths for tighter layouts
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px,
xxl: 1320px
);
@import '@coreui/coreui/scss/coreui';
Changing the spacing scale is a high-impact modification that affects every component using utility classes like p-3, m-4, or gap-2. It ensures that your layout remains mathematical and consistent, which is a hallmark of professional UI design. Adding custom levels (6 and 7 in this example) gives you more granularity for hero sections and page-level spacing.
Modifying Typography and Fonts
To change the default font or typography settings, you should override the $font-family-sans-serif and $font-size-base variables. This is usually the first thing developers do when starting a new project with CoreUI.
// Typography overrides
$font-family-sans-serif: ‘Inter’, system-ui, -apple-system, sans-serif;
$font-family-monospace: ‘JetBrains Mono’, ‘Fira Code’, monospace;
$font-size-base: 0.9375rem; // 15px instead of default 16px
$font-weight-normal: 400;
$font-weight-bold: 600;
// Heading sizes
$h1-font-size: $font-size-base * 2.5;
$h2-font-size: $font-size-base * 2;
$h3-font-size: $font-size-base * 1.75;
$h4-font-size: $font-size-base * 1.5;
// Line height for better readability
$line-height-base: 1.6;
$headings-line-height: 1.2;
$headings-font-weight: 600;
@import ‘@coreui/coreui/scss/coreui’;
By setting a modern font like ‘Inter’, you immediately elevate the look and feel of your application. CoreUI’s typography system is designed to be legible and balanced, and these variables provide the necessary hooks to adapt it to your brand’s voice. Remember to include the font in your HTML or import it in your CSS with @import or a <link> tag to ensure it loads correctly.
Best Practice Note:
Always prefer using CSS custom properties for color and surface adjustments, as they provide better performance and easier debugging in the browser. This is the same approach we use in CoreUI components to ensure clean and predictable data. For structural changes like grid breakpoints or complex mixins, Sass overrides remain the gold standard for maintainability.



