1.0.0 🎉
Basecoat 1.0.0 is the first stable release of Basecoat as a Tailwind CSS, vanilla HTML, CSS, and JavaScript implementation of shadcn/ui's visual language for non-React stacks.
This is a large release. It reshapes the package, public component APIs, style system, JavaScript lifecycle, docs, and template story around a stable 1.0 foundation.
What is Basecoat?
Basecoat brings the shadcn/ui look and component conventions to plain HTML, Tailwind CSS, and small vanilla JavaScript.
It is not a React, Radix, Base UI, cn-*, or data-slot DOM port. The goal is to map shadcn/ui concepts onto simpler semantic markup that works well in server-rendered apps, template engines, HTMX-style apps, and other non-React stacks.
Highlights
One package
Basecoat now ships as a single npm package:
npm install basecoat-cssThe old CLI workspace has been removed. Templates now ship directly inside basecoat-css, so package assets, CSS, JS, and template macros all share one version.
Template paths:
node_modules/basecoat-css/templates/nunjucksnode_modules/basecoat-css/templates/jinja
If you previously used basecoat-cli, install basecoat-css instead and copy the template files from the package.
Smaller public APIs
Basecoat 1.0 moves toward canonical root classes, semantic HTML, and documented data-* attributes.
Examples:
<button class="btn" data-variant="outline">Button</button>
<span class="badge" data-variant="secondary">Badge</span>
<div class="card" data-size="sm">...</div>
<div class="alert" data-variant="destructive">...</div>Several pre-1.0 composed class APIs were replaced by this smaller, more regular API.
If you need legacy aliases during migration, load the optional compatibility stylesheet after Basecoat:
@import "tailwindcss";
@import "basecoat-css";
@import "basecoat-css/compat";Standalone style packs
Style packs are now standalone bundles. Do not load the default/Vega bundle and then override it with another style.
Available style packs:
- Vega
- Nova
- Maia
- Lyra
- Mira
- Luma
- Sera
- Rhea
Examples:
@import "tailwindcss";
@import "basecoat-css";@import "tailwindcss";
@import "basecoat-css/maia";Base and component-only imports are also available for custom styling:
@import "basecoat-css/base";
@import "basecoat-css/components";CDN builds
Basecoat includes standalone CDN-ready CSS bundles:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@1.0.0/dist/basecoat.cdn.min.css" />Named style bundles are available too:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@1.0.0/dist/basecoat-maia.cdn.min.css" />Expanded component coverage
Basecoat 1.0 adds, stabilizes, or substantially reworks many components and docs pages, including:
- Accordion
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Card
- Chart beta
- Checkbox
- Combobox
- Command
- Dialog
- Drawer beta
- Dropdown Menu
- Empty
- Field
- Input
- Input Group
- Item
- Kbd
- Label
- Native Select
- Pagination
- Popover
- Progress
- Radio Group
- Scroll Area
- Select
- Sidebar
- Skeleton
- Slider
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Theme Switcher
- Toast
- Tooltip
Many components were realigned with current shadcn/ui visual styles across all style packs.
JavaScript lifecycle cleanup
Basecoat JavaScript now initializes only uninitialized components by default:
window.basecoat.initAll()
window.basecoat.init("select")Removed component roots clean up their listeners and runtime state through internal destroy hooks.
Several dynamic components now expose refresh() methods for rescanning child items:
- Command
- Select
- Combobox
- Dropdown Menu
- Tabs
Method-based APIs
Document-level command events for Toast, Sidebar, and Theme were removed.
Use explicit methods instead:
document.getElementById("toaster")?.toast(config)
document.getElementById("sidebar")?.toggle()
window.basecoat.theme.toggle()Templates included in the package
Basecoat now ships Nunjucks and Jinja templates inside basecoat-css.
Copy them from:
cp -R node_modules/basecoat-css/templates/nunjucks ./templates/basecoat
cp -R node_modules/basecoat-css/templates/jinja ./templates/basecoatNew docs site
The docs site was rebuilt on ReallySimpleDocs/Astro with:
- updated installation docs
- component-specific usage pages
- style switching
- template documentation
- sitemap and robots support
- custom 404 page
- Cloudflare Workers deployment support
Breaking changes
- Removed the
basecoat-cliworkspace. - Removed the old
.formconvenience selector. - Changed Button, Badge, Card, Avatar, and Alert visual APIs to root classes plus documented
data-*attributes. - Changed icon-only Button sizing to upstream-aligned
data-size="icon|icon-xs|icon-sm|icon-lg". - Changed Combobox markup and behavior to an input-first structure.
- Removed Combobox
data-multiple; usearia-multiselectable="true"on the listbox. - Changed Command markup to the migrated Basecoat structure.
- Removed Combobox-specific search-header behavior from Select.
- Removed built-in document command events for Toast, Sidebar, and Theme.
- Reworked style loading so non-default style packs are standalone bundles.
Migration notes
Forms
The old .form wrapper is gone. Compose forms from Field, Fieldset, Label, Input, Textarea, Select, Native Select, Checkbox, Radio Group, and Switch.
If you need the old convenience behavior temporarily, define it in your app:
.form label { @apply label; }
.form input { @apply input; }
.form textarea { @apply textarea; }
.form select { @apply select; }Legacy aliases
Use the compatibility stylesheet while migrating older markup:
@import "tailwindcss";
@import "basecoat-css";
@import "basecoat-css/compat";Removed document events
If you need to bridge old document events temporarily:
document.addEventListener("basecoat:toast", (event) => {
document.getElementById("toaster")?.toast(event.detail?.config || {})
})
document.addEventListener("basecoat:sidebar", (event) => {
const sidebar = document.getElementById(event.detail?.id || "sidebar")
const action = event.detail?.action || "toggle"
if (["open", "close", "toggle"].includes(action)) sidebar?.[action]()
})
document.addEventListener("basecoat:theme", (event) => {
const mode = event.detail?.mode
mode ? window.basecoat.theme.set(mode) : window.basecoat.theme.toggle()
})Fixes and polish
- Fixed destructive Alert descriptions/content using muted text instead of destructive text across all style packs.
- Fixed dark-mode unchecked Switch thumb colors across all style packs.
- Improved Combobox single selection reopening behavior.
- Improved Combobox multiple chips and remove buttons.
- Updated Table examples to avoid inline overlay menus inside scrollable table containers.
- Documented the Table overflow limitation.
- Updated Scroll Area examples to use Card surfaces.
- Narrowed dark-mode generated selectors to
html.dark. - Simplified Select component selectors.
- Fixed Input Group dropdown stacking.
- Fixed Sidebar nested item styling.
- Fixed command preview styling.
- Fixed Drawer side positioning and border radius handling.
Known beta components
Chart and Drawer remain marked beta. They are usable, but their APIs and generated behavior may still change before being considered fully stable.