Build a CSS framework from one config file.

EmilyCSS takes the colours, spacing, type, and breakpoints in emily.config.json and generates a plain stylesheet for your site.

CSSplain stylesheet output
0KBclient JavaScript runtime
MITfree framework licence

Works with

HTMLHTML
DrupalDrupal
WordPressWordPress
PHP / TwigPHP / Twig
AstroAstro
Vue / NuxtVue / Nuxt
ReactReact
Next.jsNext.js
SvelteSvelte
AngularAngular

The problem

Most frontend tooling assumesyou control the stack.

You are in a WordPress theme. A Drupal template. A PHP project where Node does not run in production. The build pipeline is not yours to touch. You still need the whole thing to look consistent and work accessibly.

EmilyCSS is a static CSS file. Drop it in with a link tag.

01

You are inside a CMS

Drupal, WordPress, or any system where the server is not yours to configure. No Node in production. Just link the stylesheet.

02

One system, multiple projects

One config file. One CSS output. Drop the same stylesheet into every project that needs your brand. No duplicated tokens, no drift.

03

Your team is mixed-skill

Backend developers, content editors, and designers can all copy consistent HTML patterns without learning a frontend runtime.

How it works

Config in. CSS out. Ship anywhere.

1

Define your tokens

Put your colours, fonts, spacing, breakpoints, and output path in emily.config.json.

Terminal
npx emily-css init
2

Generate your CSS

Run the build command to create the stylesheet your templates will load.

Terminal
npx emily-css build
3

Link and ship

Link the generated CSS from WordPress, Drupal, PHP, static HTML, or a JavaScript framework.

One config file

Define tokens once.
Use them everywhere.

Set your colours, typography, spacing, and breakpoints in emily.config.json. EmilyCSS turns that into CSS variables, utility classes, responsive variants, and reusable component classes.

Change one token, rebuild, and every utility and component stays in sync.

emily.config.json
{
  "name": "My Brand",
  "colours": {
    "brand":   "#DB2777",
    "accent":  "#D4AF37",
    "success": "#017F65"
  },
  "fontFamily": {
    "heading": "inter",
    "body":    "inter"
  },
  "output": {
    "css": "public/emily.min.css"
  }
}

Why teams choose it

What every build includes.

Config-driven classes

The class names are generated from your own colours, spacing, type, and breakpoint settings.

Plain CSS output

The browser receives a stylesheet. There is no client-side styling runtime.

Accessible defaults

Focus styles, reduced-motion handling, and contrast-aware utility options are included in the generated CSS.

Tooling data

Optional JSON output gives the VS Code extension and doctor command the class list they need.

Components

Accessible patterns, ready to paste.

Two examples from the component reference. Copy the HTML, then adjust the classes to match your config.

Action row
actions.html
<div class="flex gap-3">
  <button class="btn btn-primary">Save settings</button>
  <button class="btn btn-secondary">Preview</button>
  <button class="btn btn-secondary" disabled>Disabled</button>
</div>
Accessible form field

Used for build notifications only.

field.html
<label for="email" class="text-sm font-medium">Email address</label>
<input
  id="email"
  type="email"
  aria-describedby="email-hint"
  class="mt-2 w-full rounded border border-neutral-30 px-4 py-2.5 text-sm"
>
<p id="email-hint" class="mt-2 text-xs text-neutral-60">
  Used for build notifications only.
</p>

Production output

Full utility set in development. Purged output in production.

Build generates the full utility catalogue for speed while designing. Purge removes unused classes for production so users download far less CSS.

Development output

Full CSS

~4 MB

emily.css

Includes all generated utilities, responsive variants, and state variants so teams can move quickly while building.

Production output

Purged CSS

much smaller

emily.purged.css

Keeps only the classes your templates use. Run emily-css purge to see the exact output size for your project.

Visual size comparison

Before
~4 MB
After
after purge
Build
npx emily-css build
Purge
npx emily-css purge

EmilyUI ecosystem

Add interactivity without a framework.

EmilyCSS handles your styles. EmilyJS handles interactive behaviour — dropdowns, tabs, modals, form validation — using plain HTML attributes. No build step. No framework. Works in the same legacy environments as the CSS.

  • Toggle visibility, classes, and text with emily-show, emily-text, and emily-class
  • ARIA attributes (aria-expanded, aria-controls, aria-live) managed automatically
  • Focus trapping for modals and dialogs with emily-trap
  • Works in Drupal, WordPress, server-rendered HTML — anything
  • CSP-safe: no eval, no new Function, no inline script generation
toggle.html
<!-- No build step. Drop in a script tag. -->
<script src="/emily.js"></script>

<!-- Toggle a menu open and closed -->
<div emily-state="{ open: false }">
  <button emily-click="open = !open"
          class="btn btn-secondary">
    Toggle menu
  </button>

  <nav emily-show="open"
       class="mt-4 flex flex-col gap-2">
    <a href="/docs">Docs</a>
    <a href="/components">Components</a>
    <a href="/pricing">Pricing</a>
  </nav>
</div>

<!-- aria-expanded is set automatically -->

One design system.
Any project that can load CSS.

Free, MIT licensed, no sign-up required. Start with the CSS framework and add the editor tooling when you need it.