# Cirrus is an SCSS framework whose utilities are generated from a config

> Cirrus is an MIT licensed SCSS framework published to npm as cirrus-ui, a component and utility centric framework for rapid prototyping where the utility classes are generated at build time from a configuration map, so you can extend, exclude or disable them. It is Sass first, with no JavaScript required for component behaviour.

**Spiderpig86/Cirrus** — :cloud: The SCSS framework for the modern web.

- Repository: https://github.com/Spiderpig86/Cirrus
- Website: https://www.cirrus-ui.com/
- Stars: 1,432 · Forks: 76
- Language: SCSS
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/spiderpig86-cirrus

## The utilities are generated, which is the design decision

Cirrus describes itself as a component-and-utility-centric SCSS framework designed for rapid prototyping, with the instruction to use beautiful pre-built components to bootstrap your next project and utility classes to polish your final design.

The distinguishing feature is stated in the third bullet. Configuration at its Core, where you can add additional components, remove utility classes and disable features, and Cirrus takes a generative approach to building your stylesheets.

That last phrase is the whole architecture. The utility classes in Cirrus are not a fixed list of class names in a stylesheet. They are generated from a configuration map, so the set of utilities that exist, and in some cases the values they carry, is a function of your config.

The SCSS usage example shows it.

```scss
@use "node_modules/cirrus-ui/src/cirrus-ext" as * with (
    $config: (
        excludes: (
            ABSOLUTES,
        ),
        opacity: null, // Disable default opacity classes
        extend: (
            // Add your own
            opacity: (
                25: .25,
                50: .5,
                75: .75,
            )
        )
    ),
);
```

So you exclude a whole group of classes with ABSOLUTES, you set a feature to null to disable it, and you extend a group with your own values. The opacity group in the example ends up with your own 25, 50 and 75 classes rather than the defaults, and the default opacity classes are gone because opacity was set to null.

The practical consequence is that the utility layer adapts to the project. A design system with a 4 point spacing scale does not need to fight a framework that generates 10 point spacing, and a project that has decided it does not want absolute positioning classes does not ship them. This is a meaningful difference from a framework that hands you a fixed utility sheet, and it is also the thing that makes the framework's class names project-specific, which is worth keeping in mind.

The other four features are more conventional. Beautiful components that come out of the box for rapid prototyping. Sass First, where the instruction is to forget bundling tons of JavaScript with each component, and all styles require no JS for interactions and functionality, with modals and dropdowns named as the examples. Lightweight, a large amount of features with a minimal footprint. And Responsive, fully responsive by design.

## No JavaScript, and a browser support matrix that still includes IE11

The Sass First claim is the one that has the largest practical consequences, and it is easy to get wrong.

The stated benefit is that you forget bundling tons of JavaScript with each component, and all styles require no JS for interactions and functionality, with modals and dropdowns given as the examples. So a modal in Cirrus is opened by a class on the element, and a dropdown is opened by a class, and there is no JavaScript component to include, no framework to mount it, no state to manage.

That is a real constraint and it is also the framework's most distinctive position. Almost every modern component library ships a JavaScript component, and the interaction model is part of the package. Cirrus moves the entire component catalogue into CSS, which is why the CSS distribution is a single file.

The browser support table is the other thing worth reading, because it dates the project. Cirrus relies on What CSS to prefix? to determine which selectors need prefixes, so the prefixing is generated rather than hand maintained. The support row reads IE11 and Edge for Internet Explorer, last 3 versions and ESR for Firefox, last 3 versions for Chrome, last 3 versions for Safari, last 3 versions for Opera, and last 3 versions for Electron.

So IE11 and Edge are still in the support matrix alongside the last three versions of everything else. That is an unusual thing to see in 2026, and it is consistent with a framework whose newest release is from February 2025 and whose last commit is from October 2026, and it tells you that the codebase has a prefixing layer that is still earning its keep.

The README also points to a Visual Studio Code extension for intellisense, so the class names are available to an editor, and a playground on the project site where you can try out whatever experiment you want with Cirrus.

The docs are at cirrus-ui.netlify.app for the examples and at cirrus-ui.com for the site, and the package is on npm as cirrus-ui with the main entry point at ./dist/cirrus.min.css.

## Distribution by npm, by CDN, and a warning about the dist folder

The install section is short, and one line of it is a warning worth taking seriously.

Npm installs the package with npm install cirrus-ui, and Yarn with yarn add cirrus-ui. For CDNs, it is recommended to attach a specific version to the URLs to avoid unexpected updates to maintain consistency in your project, and the Unpkg and JsDelivr examples are given.

Then the warning. Please do not reference the dist folder artifacts directly as these are subject to change at any time.

That is a bit of a puzzle until you look at the package.json, and the answer is in the autoupdate field. The files array lists cirrus.min.css and cirrus.css, and the basePath is dist, and the target is the git repository. So the published npm package contains a dist directory, and the autoupdate configuration describes how a tool like greenkeeper or dependabot would push a new version when the upstream repository changes.

Combined with the warning, the reading is that the dist directory inside the npm package is not the supported entry point. The supported way to consume the framework is the package's main field, ./dist/cirrus.min.css, resolved through the package, and if you want the source to compile yourself, the SCSS entry point is src/, which is what the @use example in the usage section points at, node_modules/cirrus-ui/src/cirrus-ext.

So there are three ways in. The compiled CSS through npm or a CDN for a quick start, the SCSS source through the @use with configuration for the generative approach, and the package's own main field for a bundler.

The framework examples cover the four common setups. A basic HTML page with the stylesheet link, a React example, a Vue example and a Svelte example, each of which is the same import of the stylesheet next to the framework's own import. The React example uses ReactDOM.render with StrictMode, and the Vue example sets Vue.config.productionTip to false, which is Vue 2 syntax, and the Svelte example uses the older component constructor with a target of document.body.

## The build is gulp, and the versions are named after Greek letters

The package.json is small and the build is a gulp pipeline.

```json
"scripts": {
  "test": "jest",
  "build": "gulp minify",
  "watch": "gulp watch",
  "prepare": "npm run snyk-protect",
  "snyk-protect": "snyk-protect"
}
```

The build script is gulp minify, and the watch script is gulp watch. The gulpfile.js is at the root of the repository, and the dev dependencies are the gulp plugins for the pipeline, gulp-build, gulp-clean-css, gulp-concat, gulp-gzip, gulp-header and gulp-size.

The size plugin is worth noting, since it reports the size of the generated CSS, and the gzip plugin means the published artifact includes a compressed variant. The prepare script runs snyk-protect, and the @snyk/protect package is a runtime dependency, which is an unusual arrangement, and the reason is that the snyk-protect command patches package.json on install to pin vulnerable transitive dependencies. The README carries a Snyk badge for known vulnerabilities, and the package.json has a snyk field set to true, which is the Snyk protection metadata.

The testing setup is jest with jest-environment-node-single-context, and sass-true in the dependencies, which is the interesting one. sass-true is a testing library for Sass, so the framework tests its own Sass output, asserting on the generated CSS rather than on a rendered page. There is a jest.config.js at the root and a tests/ directory.

The release naming is unusual and quite good. The tags are 0.7.2, Gamma 8, on 2023-12-29, then 0.7.2-patch.1, Gamma 8 Patch 1, on 2023-12-30, and then 0.8.0, Delta I, on 2025-02-05. So the semantic version is paired with a name from the Greek alphabet and a Roman numeral, and a patch is a patch of the name as well as of the number.

The build inputs are a src/ directory for the Sass sources, a config/ directory for the configuration, a dist/ directory for the built output, a main.example.scss showing how a consumer would configure it, a .browserslistrc driving the prefixing, and a .hound.yml for the style linter, since Hound is a review bot that checks code style.

## Where Cirrus is the wrong choice

The first wrong case is a team already on Tailwind. A utility framework and another utility framework is duplication, and the two will disagree about spacing scale, about colour naming and about how a component is composed. If your organisation has standardised on Tailwind, the value Cirrus offers is a nicer component set, and a component set is a much smaller thing to swap than a utility layer.

The second wrong case is a project that needs JavaScript components with real behaviour. A dropdown that traps focus, a menu that closes on escape, a modal that manages the focus ring and restores it on close, a combobox with typeahead, those need JavaScript, and a CSS-only approach either accepts a reduced behaviour or requires the developer to write the JavaScript themselves. The Sass First claim is a genuine constraint, and a project whose components must meet an accessibility bar may find that the accessible behaviour is the part you end up writing yourself.

The third wrong case is a team that wants a stable, versioned artefact. The release history has a two month gap, a two year gap and then nothing since February 2025, and the README's own advice to pin a specific version on a CDN is a warning about a framework whose dist artefacts change without notice. For a design system dependency, that is uncomfortable.

The fourth wrong case is a design system with its own tokens. The configuration system is good at adjusting the framework's scales, but it is not a token pipeline. A team with a single source of truth for colour, spacing and typography, exported from Figma or from a token file, is better served by a framework that consumes those tokens than by one whose tokens are Sass variables in a config map.

## How it differs from Tailwind

The comparison worth making is with Tailwind, since they occupy the same slot in a project's dependency list, and the difference in approach is in what is generated.

Tailwind generates utility classes from a configuration of scales and variants, and it ships the runtime of that generation to the browser, a just-in-time compiler or a build step that scans your files for the class names you used. The utilities are the primary product, and the components are things you assemble.

Cirrus inverts the emphasis. The components are the primary product and the utility layer is the polish, and the utilities are generated at build time from a Sass configuration map that you pass into the framework. The difference is visible in the config: Tailwind's configuration is a JavaScript or CSS file describing scales, while Cirrus's is a Sass map passed through @use with, and the options are structural, exclude a group, disable a feature, extend a group with your own values.

The second difference is the component approach. Tailwind ships a small set of first-party components and expects composition. Cirrus ships a catalogue of styled components that come ready to use, and the Sass First principle means they work without JavaScript, which is a different philosophy from Tailwind's headless component model.

The third difference is the distribution. Tailwind is a build-time tool, and what ships to production is the CSS that the scanner found. Cirrus is a stylesheet, a single minified CSS file on npm or a CDN, and the config only matters if you compile the Sass yourself.

The fourth difference is the age. Tailwind is actively developed with a large ecosystem of plugins and a community. Cirrus is a smaller project with a recent release from February 2025 and a slower cadence, which is not a disqualification but is a factor in any decision to depend on it.

## Conclusion

Cirrus fits a team that wants a component library and a utility layer in one Sass file, with the utilities generated rather than hand written, so a project can add its own spacing scale or drop the utilities entirely. It does not fit a team that has standardised on Tailwind or on a design system with its own tokens, and it does not fit a project that needs JavaScript-driven components without writing them. Before adopting it, read the configuration guide, because the generative approach means the class names you get depend on the config, and note that the current release is 0.8.0, named Delta I, from 2025-02-05 with the last push on 2026-10-12.

## FAQ

### What is Cirrus and what makes it different from other CSS frameworks?

It is an MIT licensed SCSS framework for rapid prototyping that is component and utility centric, and its distinguishing feature is a generative approach to building stylesheets. Utility classes are generated at build time from a configuration map, so you can add components, remove utility classes and disable features, and the set of classes depends on your configuration.

### How do I install Cirrus?

With npm install cirrus-ui or yarn add cirrus-ui, or from a CDN with a version pinned to the URL, using Unpkg or JsDelivr. The README warns not to reference the dist folder artifacts directly because they are subject to change at any time, so consume the package main entry instead.

### Does Cirrus need JavaScript for its components?

No, and that is the Sass First principle. The README says to forget bundling tons of JavaScript with each component, since all styles require no JS for interactions and functionality, with modals and dropdowns given as the examples. A project that needs focus trapping or keyboard handling has to write that JavaScript itself.

### How do I configure Cirrus in a Sass project?

You @use the cirrus-ext entry point from node_modules/cirrus-ui/src and pass a $config map. The example excludes the ABSOLUTES group, sets opacity to null to disable the default opacity classes, and extends opacity with your own 25, 50 and 75 values. The Setup guide in the documentation covers the rest.

### How is Cirrus built and tested?

With gulp, where the build script is gulp minify and the watch script is gulp watch, using plugins for concatenation, minification, gzip, headers and size reporting. Tests run under jest with sass-true, which asserts on the generated Sass output, and the repository also has a .browserslistrc driving the CSS prefixing through shouldiprefix.com.

## Sources

- [License: MIT](https://github.com/Spiderpig86/Cirrus/blob/master/LICENSE)
- [Project website](https://www.cirrus-ui.com/)
- [README](https://github.com/Spiderpig86/Cirrus/blob/master/README.md)
- [Releases](https://github.com/Spiderpig86/Cirrus/releases)
- [Spiderpig86/Cirrus on GitHub](https://github.com/Spiderpig86/Cirrus)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/spiderpig86-cirrus
