grugbraindev c2ac210002 Use Geist as the default sans font family name
Google Fonts, Bunny Fonts and Fontsource all publish the font as "Geist". "Geist Sans" is only on Fontsource, so the default token fell back to system fonts with the other providers. "Geist Sans" stays as a fallback for existing Fontsource setups. Matches shadcn/ui, which loads "Geist".
2026-10-23 09:28:43 +08:00
2026-06-28 09:54:05 +08:00
2026-07-06 15:21:53 +07:00
2026-07-06 15:21:53 +07:00
2026-07-06 15:21:53 +07:00
2026-06-28 09:54:05 +08:00
2026-01-04 21:22:53 +08:00

Basecoat

Basecoat is a Tailwind CSS, vanilla HTML/CSS/JavaScript implementation of the shadcn/ui design system. It provides shadcn-style components for any web stack without React, Radix, or framework runtime dependencies.

screenshot

Features

  • Semantic HTML-first components.
  • Tailwind CSS v4 source files and generated CSS bundles.
  • Small vanilla JavaScript for components that need behavior.
  • Standalone style packs: Vega, Nova, Maia, Lyra, Mira, Luma, Sera, and Rhea.
  • Compatible with shadcn/ui themes.
  • Dark mode.
  • CDN, npm, and template usage paths.
  • Nunjucks and Jinja templates.

Documentation

Install

npm install basecoat-css

Use the default bundle:

@import "tailwindcss";
@import "basecoat-css";

Use a specific style bundle:

@import "tailwindcss";
@import "basecoat-css/nova";

Use the styleless base plus a custom style file:

@import "tailwindcss";
@import "basecoat-css/base";
@import "./style-acme.css";

Repository Layout

.
├── dist/                 Generated package output
├── scripts/              Build and generation scripts
├── site/                 ReallySimpleDocs/Astro documentation app
│   ├── public/           Static site assets
│   └── src/
│       ├── components/   RSD component overrides
│       ├── docs/         Documentation pages and examples
│       ├── fragments/    Site-only rendered fragments
│       ├── pages/        Astro routes outside the docs tree
│       └── scripts/      Site scripts
├── src/                  Package source
│   ├── css/
│   ├── js/
│   └── templates/
└── templates/            Generated package template output

CSS Architecture

Basecoat separates structure from style:

  • src/css/base/base.css: shared tokens and semantic utilities.
  • src/css/components/*.css: component layout, structure, accessibility selectors, and behavior hooks.
  • src/css/styles/*.css: style-pack visuals such as color, radius, shadow, typography, spacing, variants, and state styles.

Generated source entrypoints are committed for transparency and package imports:

  • src/css/basecoat.css: default backward-compatible Vega bundle.
  • src/css/basecoat-base.css: base plus components, no style pack.
  • src/css/basecoat-components.css: component imports only.
  • src/css/basecoat-<style>.css: base plus one style pack.
  • src/css/basecoat-<style>.cdn.css: CDN-compatible wrapper.

These entrypoints are generated by scripts/generate-css-entrypoints.js and by the build scripts.

JavaScript Lifecycle

  • window.basecoat.init(name) initializes uninitialized components for one registered component.
  • window.basecoat.initAll() initializes all uninitialized registered components.
  • window.basecoat.init(name, { force: true }) and window.basecoat.initAll({ force: true }) destroy and reinitialize matching components. Use this when a framework or navigation library restores previously initialized DOM from a cache. Force mode resets transient component state such as open menus, focus state, and active interactions.
  • window.basecoat.refresh(element) asks an initialized component to rescan dynamic children when it supports refresh.
  • Components use internal destroy hooks to clean up listeners when initialized roots are removed from the DOM.

Development

# Install dependencies.
npm i
npm --prefix site i

# Run the ReallySimpleDocs/Astro site.
npm run docs:dev

# Build package assets.
npm run build

# Build the static docs site.
npm run docs:build

License

MIT

Languages
MDX 40.9%
CSS 35.1%
JavaScript 11.5%
Astro 4.8%
Jinja 3.9%
Other 3.7%