Installing Yeti

Yeti is one stylesheet. Everything else here is optional and most pages need none of it.

The examples on these pages are live: each is a demo, a box you can drag from its bottom corner to watch the component change shape, with the code beneath it. The label in the corner names the width stop the box is at.

Getting the files

From npm:

npm install yeti-css

The package ships dist/: the bundled yeti.css, the same source tree unbundled under css/, the six modules under js/ and all of them in one yeti.js, the two example themes under themes/, and the machine-readable files described below. A release also carries a zip of the same dist/ folder on its GitHub release page, for a site with no build step at all. There is no CDN path yet; when there is one it will be listed here.

The stylesheet

One link, before your own styles:

<link rel="stylesheet" href="node_modules/yeti-css/dist/yeti.css">

Yeti's rules live in cascade layers, so anything you write outside a layer wins over them without a specificity fight. A theme is a second stylesheet of token values that loads after the first:

<link rel="stylesheet" href="node_modules/yeti-css/dist/yeti.css">
<link rel="stylesheet" href="node_modules/yeti-css/dist/themes/soft.css">

A module

Every component works with no script. Six of them do more with one: the alert's close button, the tabs' roving focus, the dialog's opening, a dropdown that opens on hover, the carousel's dots, and a demo's frame built from the code beneath it. Each is a module you load once, anywhere in the page, with nothing to call:

<script type="module" src="node_modules/yeti-css/dist/js/dialog.js"></script>

A module finds its own elements and is safe on a page that has none of them. Leave it out and the component is still there, minus what the module adds; the components guide says what that is for each. A page that would rather not pick loads all six at once, about a kilobyte and a half compressed:

<script type="module" src="node_modules/yeti-css/dist/yeti.js"></script>

Editor completion

Yeti configures components through data-* attributes with fixed value lists, and the package ships those lists in the two formats editors read, generated from the same manifest the validator uses.

VS Code, Cursor and Windsurf read a custom-data file. One setting, in .vscode/settings.json:

{ "html.customData": ["./node_modules/yeti-css/dist/yeti.html-data.json"] }

PhpStorm and WebStorm read web-types and find the file through package.json on their own. Install the package and the completions are there.

One limit is worth knowing. Neither format can tie a completion to a class, and a Yeti component's identity is its class, so every attribute is offered on every element: typing inside a p will offer data-ranks. Each description opens with the components that accept the attribute, so the list explains itself, and a wrong value is still a validator error rather than a silent nothing.

For a TypeScript project the package ships types for the two JSON files and the vocabularies they are built from:

import manifest from 'yeti-css/manifest';
import type { YetiGap, YetiManifest } from 'yeti-css';

Both resolve with no configuration beyond the default in a modern project. They exist for tools built on those files; a page needs nothing from them.

For a language model

llms.txt and llms-full.txt sit at the root of the docs site and in the package. The first lists every component with its class, attributes, legal values and defaults in a few hundred lines; the second adds each component's guidance, accessibility notes and the token catalogue. They are generated from the manifest, so they describe exactly the surface the validator enforces, and nothing else. Point an assistant at the first and it can write valid Yeti; give it the second and it can explain why.