CoreUI ONE — 250+ PRO components and 25+ admin templates for React, Angular, Vue, Bootstrap and Next.js, plus Data Grid, Scheduler, 4,300+ PRO icons and the Next.js boilerplate. One license. → See what you get

CoreUI v6 Alpha: What Changes and Why

CoreUI v6 Alpha: What Changes and Why

The first alpha of CoreUI v6 is on npm. It covers three packages: CoreUI PRO for Bootstrap (@coreui/coreui-pro), for React (@coreui/react-pro) and for Vue (@coreui/vue-pro), each published as 6.0.0-alpha.0 under the next tag. The free editions and Angular follow in later alphas.

Two weeks earlier the Bootstrap team published the first Bootstrap 6 alpha. CoreUI has always been built on Bootstrap, and v6 follows the same architecture: cascade layers, a token map per component, theme classes and colours computed in the browser. Where a class, token, option or event exists in both libraries, it almost always has the same name. What we took from Bootstrap 6, what we did not take and why is the subject of a separate post. This one is about what v6 gives you.

It is an alpha. The API can still change before the release candidate, so pin the exact version and keep it out of production for now.

Table of Contents

Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


Try it

# Bootstrap (vanilla JavaScript)
npm install @coreui/[email protected]

# React
npm install @coreui/[email protected] @coreui/[email protected]

# Vue
npm install @coreui/[email protected] @coreui/[email protected]

A plain npm install @coreui/coreui-pro still installs v5. The v6 documentation is published next to the v5 docs, and each edition has its own migration guide:

A browser floor tied to features

v6 supports Chrome and Edge 123, Firefox 130, Safari 18 and iOS 18. We did not pick these numbers by age. Each one is the first version that ships a feature v6 relies on without a fallback:

  • Chrome 123 brings light-dark(). The light and dark colours in the stylesheet resolve through it.
  • Firefox 130 brings <details name>. Exclusive accordions are grouped by that attribute, and below this version several panels can stay open at once.
  • Safari 18 fixes color-mix() in oklch when one side is grey, white, black or transparent. Safari 17 shifts the hue, so tinted colours come out wrong.

The floor holds for the whole 6.x line, because we cannot raise it in a minor release. In return, the build no longer adds prefixes and fallbacks for older browsers, and the JavaScript ships modern syntax without transpiling it down. If your users are on older browsers, stay on v5.

CSS you can change in the browser

Most of what v6 changes in CSS comes down to one idea: a value you customise should stay customisable after the build. Nearly every value is now a CSS custom property, and anything derived from it is computed by the browser, not by Sass.

Cascade layers

All library CSS lives in cascade layers, declared once at the top of the stylesheet:

@layer colors, config, root, reboot, layout, content, forms, components, custom, helpers, utilities;

Two consequences matter in daily work. Your own unlayered CSS wins over the library’s declarations whatever their specificity, so overriding a component no longer means matching our selectors. And utilities sit in the top layer, so they beat component styles without !important, which is gone from every utility class. Two layers are empty and reserved for you: config for a configuration sheet the library should read, and custom between components and helpers, for overrides that utilities should still be able to beat.

A token map per component

Each component declares its own custom properties on its own selector and reads its values from them. You can override them for the whole app, for one section of the page, or for a single element:

.alert {
  --cui-alert-padding-x: 1.5rem;
}

The same tokens are documented in the “CSS variables” section of every component page, and in Sass they come from one $<component>-tokens map per component, which replaces several hundred separate Sass variables.

Theme classes

Colour is no longer part of the component class. Instead of .alert-success or .btn-danger, you add a theme class, and it works on any component:

<div class="alert theme-success" role="alert">Changes saved.</div>
<button type="button" class="btn-solid theme-danger">Delete</button>

There are seven themes: primary, secondary, success, info, warning, danger and inverse. Each one is a family of slots (--cui-theme-bg, --cui-theme-bg-subtle, --cui-theme-fg, --cui-theme-border, --cui-theme-focus-ring and a few more), and components read the slot first, with their own token as the fallback. A theme class on a container themes everything inside it, and .theme-reset lets one part opt out. The theme page covers the details.

Colours computed in the browser

The palette is defined in oklch. Each colour has one base stop, 500, and every other stop from 025 to 975 is a color-mix() of that base, so the whole ramp follows a single custom property at runtime:

:root {
  --cui-primary-500: oklch(55% 0.2 150);
}

Light and dark colours resolve through light-dark(), and data-coreui-theme still switches a page or a single element between them. Each theme colour is tuned together with the text colour that sits on it (white on most, black on warning) to meet WCAG AA contrast on a solid button.

One stylesheet for both directions

The separate *.rtl.css builds are gone. The layout uses logical properties, the few rules that cannot be logical are mirrored with :dir(rtl), and dir="rtl" on <html> is all a right-to-left page needs. Serving both directions from one file costs a few hundred bytes gzip.

Load only the CSS you use

dist/css still has coreui.css with everything in it. Next to it, v6 ships base.css (tokens, palette and Reboot) and one stylesheet per component, plus a manifest.json that lists each file’s dependencies and load order.

The React and Vue editions use this out of the box. You import base.css once, and each component imports its own stylesheet, so an app ships only the CSS it renders:

import '@coreui/coreui-pro/css/base.css'
import { CButton } from '@coreui/react-pro'

Utility classes are not split per component. If you use them, import @coreui/coreui-pro/css/coreui-utilities.css as well. If you would rather load coreui.css whole, import the components from @coreui/react-pro/unstyled or @coreui/vue-pro/unstyled instead.

Old class names in a separate file

The v5 colour modifiers (.btn-primary, .btn-outline-*, .alert-success and the rest) and the old form check markup moved out of coreui.css into coreui-legacy.css. Load it after the main stylesheet while you migrate markup. That keeps about 3.8 kB gzip out of the main file for everyone who does not need it, and the legacy file goes away in v7.

Native HTML where the platform has caught up

A lot of the JavaScript a UI library used to carry now exists in the browser. v6 uses it:

  • Modal and Offcanvas run on <dialog> with showModal(). Focus containment, the inert background, Escape and stacking come from the browser. The new Dialog and Drawer components share the same base.
  • Accordion uses <details> and <summary>, so collapsed content stays in the page and exclusive accordions group by name.
  • Collapse can use hidden="until-found", so the browser’s find-in-page opens the section that contains the match.
  • Carousel runs on CSS scroll snap, with native swipe and momentum.
  • Form validation uses :user-invalid. Add data-coreui-validate to a form, and errors appear after the user has interacted with a field, not as soon as the page loads.
  • Enter and exit transitions use @starting-style, and the navbar, card group, horizontal list group and stacks respond to the width of their container through container queries.

JavaScript

  • TypeScript. The source is TypeScript and the package ships its own type declarations. Each component exports the type of its options, so a typo in an option name is a compile error.
  • Floating UI instead of Popper. Every positioned component (tooltips, popovers, dropdowns, menus, picker popups) uses @floating-ui/dom. The popperConfig option is now floatingConfig.
  • Promises. On the components that animate in and out (Collapse, Accordion, Dialog and Modal, Drawer and Offcanvas, Menu and Dropdown, Tooltip and Popover, Toast, Tab and Sidebar), show() and hide() return a promise, so await collapse.show() waits for the transition to finish.
  • Setters for live changes. Options are fixed when a component starts. To change state on a running instance, call its setter: setValue(), setOptions(), setDate(), disable() and enable(). By default, setters do not fire change events, because change events describe what the user did.
  • The same delivery as before. v6 still ships UMD bundles, an ESM bundle and per-file modules, and the jQuery integration keeps working.

New components

The Bootstrap edition adds Dialog, Drawer, Menu, Context Menu, Combobox, List Box, Transfer, Toaster, Date Input, Date Range Input, Time Input, Number Input and Password Strength. Accordion, Range and form validation are now JavaScript plugins, and two helpers are new: Backdrop and Hover Lift.

The React and Vue editions get the same components, plus hooks and composables for the ones with state worth sharing: useCombobox, useListBox, useMenu, useTransfer, useToaster, useSmartTable, useDatePicker, useDateRangePicker and useTimePicker.

React and Vue

Both editions are built on the v6 stylesheet, so everything above applies to them. On top of that:

  • Supported versions. React 18 and 19 (prop-types is gone) and Vue 3.5 or newer.
  • One model for controlled state. In React, components that open and close take show, defaultShow and onShowChange in place of visible, which is deprecated. Set a value prop to control it, or use its default* prop to only seed it. In Vue, v-model:show and v-model on value props make them controlled, and a one-way prop only seeds the state.
  • validationState takes over from the valid and invalid booleans, which stay as deprecated aliases. An invalid field blocks form submission and shows its feedback text as the browser’s message.
  • A theme prop on the components that support theme classes, with variant picking the shape of a button, mirroring the classes in CSS.
  • Smart Table is split into composable parts with a useSmartTable hook, and Toaster is a store created with createToaster(), with add, update, close and promise.

Accessibility

Each v6 documentation site has a new Accessibility section that targets WCAG 2.2 AA, with pages on keyboard support, screen readers, colour contrast and reduced motion. The Bootstrap edition also has a compliance page that lists the WCAG criteria each tested component meets.

  • One live announcer for the page. The announce() utility gives Toaster, Transfer, Chip Set, List Box, Multi Select, Loading Button and Calendar the same way to speak to screen readers. Its options mirror the upcoming ariaNotify() API. Today it uses live regions, and it moves into an open modal dialog so a message is not lost behind the inert page.
  • Keyboard models from the ARIA Authoring Practices. The calendar grid, chip sets and time selection are each one tab stop. Pickers open with Alt+ArrowDown, Context Menu opens with Shift+F10 or the Menu key, and forms move focus to the first invalid field.
  • Smaller fixes that add up. At the default font size, the close button is a 24 px target, the size WCAG 2.2 asks for. Carousel autoplay stops after the user interacts with it. Transitions run only under prefers-reduced-motion: no-preference.

What we measured and what we did not: the messages from announce(), the Toaster and the loading button were measured by hand with VoiceOver on macOS, in Safari and Chrome, and the wait after a dialog closes in Firefox too. NVDA, JAWS, Narrator, VoiceOver on iOS and TalkBack have not been measured for this alpha yet. The screen readers page in the docs keeps that table up to date.

Ready for AI agents

Coding agents read documentation differently from people, so v6 meets them where they read. The packages ship Agent Skills in their skills/ folders. Each one has skills for installing v6 and migrating from v5 or v4, and @coreui/coreui-pro, which the React and Vue editions install with them, adds skills for writing components, theming, the utility API and moving a project from Bootstrap to CoreUI. The docs publish an llms.txt and a Markdown version of every page. The AI tools page shows how to point an agent at them.

What is not in this alpha

  • The free editions and Angular. @coreui/coreui, @coreui/react, @coreui/vue and the Angular libraries get their v6 in later alphas.
  • A frozen API. Option names, props and events can still change before the release candidate. If something in the migration guide makes your upgrade harder than it should be, now is when we can still change it.

Tell us what breaks

Install the alpha in a branch, run your app, and go through the migration guide for your framework. If something does not work the way the docs say, or the guide is missing a step, open an issue in the CoreUI PRO repository or write to us through support. Every report before the beta saves someone else a broken upgrade.

About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.