npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chakrabortyrajarshi2005/chai-tailwind-css

v1.0.1

Published

A lightweight utility-class CSS engine. Write chai- classes, get real CSS.

Readme

☕ chai-css

A lightweight, zero-dependency, custom Tailwind-like CSS engine you build yourself. Write chai- classes in your HTML — get real CSS applied at runtime.

<div class="chai-bg-slate-950 chai-px-24 chai-py-16 chai-rounded-12 chai-text-indigo-400">
  Hello from chai ☕
</div>

What is chai-css?

chai-css is a DIY utility-class CSS engine inspired by Tailwind CSS. Instead of a build step or a CDN stylesheet, chai works by:

  1. Scanning the DOM for any element with a chai- class
  2. Parsing the class name into a { property, value } pair
  3. Applying the CSS directly to the element as an inline style

No compiler. No config file. No stylesheet to ship. Just your JavaScript engine + your HTML.


Project Structure

your-project/
├── index.html
├── src/
│   └── main.js              ← entry point (run chai here)
└── config/
    └── propertyMap.js       ← all shorthand keys + color palette

The engine itself lives in four files:

src/
├── main.js        ← entry point: connects everything
├── scanner.js     ← finds all chai- elements in the DOM
├── parser.js      ← breaks "chai-bg-red-500" into { property, value }
└── apply.js       ← sets the actual CSS on the element

How It Works

1. scanner.js — Find

Walks every element in the DOM and collects any class starting with chai-.

// Returns: [{ element: <div>, className: "chai-bg-red-500" }, ...]
scan()

2. parser.js — Parse

Splits the class name into a property key and a value.

"chai-bg-red-500"    →  { property: "bg",       value: "red-500" }
"chai-px-16"         →  { property: "px",        value: "16"      }
"chai-rounded-8"     →  { property: "rounded",   value: "8"       }
"chai-gridCols-3"    →  { property: "gridCols",  value: "3"       }

The parser tries each possible split point left-to-right and picks the first one where the property key exists in propertyMap. This correctly handles color names like red-500 that contain a dash.

3. apply.js — Apply

Looks up the CSS property in propertyMap, resolves the value, and sets it.

"bg"   → "backgroundColor"           → element.style.backgroundColor = "#ef4444"
"px"   → ["paddingLeft","paddingRight"] → sets both at once
"text" → "color"                      → element.style.color = "#3b82f6"

Value resolution order:

  1. Color name? (red-500) → look up hex in categoryGroups.colors
  2. Already has a unit? (2rem, 50%) → use as-is
  3. Keyword? (auto, flex, none) → use as-is
  4. Plain number? (16, 8) → append px automatically
  5. Anything else → use as-is (hex codes, CSS vars, etc.)

4. main.js — Run

import { scan }       from "./scanner.js";
import { parse }      from "./parser.js";
import { applyStyle } from "./apply.js";

function run() {
  scan().forEach(item => applyStyle(item.element, parse(item.className)));
}

document.readyState === "loading"
  ? document.addEventListener("DOMContentLoaded", run)
  : run();

Class Syntax

chai-{property}-{value}

| Part | Example | What it is | |---|---|---| | chai- | always | required prefix | | {property} | bg, px, rounded | key from propertyMap | | {value} | red-500, 16, auto | color name, number, or keyword |


Property Reference

Spacing

| Class | CSS Property | |---|---| | chai-p-{n} | padding | | chai-px-{n} | paddingLeft + paddingRight | | chai-py-{n} | paddingTop + paddingBottom | | chai-pt-{n} | paddingTop | | chai-pb-{n} | paddingBottom | | chai-pl-{n} | paddingLeft | | chai-pr-{n} | paddingRight | | chai-m-{n} | margin | | chai-mx-{n} | marginLeft + marginRight | | chai-my-{n} | marginTop + marginBottom | | chai-mt-{n} | marginTop | | chai-mb-{n} | marginBottom | | chai-ml-{n} | marginLeft | | chai-mr-{n} | marginRight | | chai-gap-{n} | gap | | chai-gapX-{n} | columnGap | | chai-gapY-{n} | rowGap |

Sizing

| Class | CSS Property | |---|---| | chai-w-{n} | width | | chai-h-{n} | height | | chai-size-{n} | width + height | | chai-minW-{n} | minWidth | | chai-maxW-{n} | maxWidth | | chai-minH-{n} | minHeight | | chai-maxH-{n} | maxHeight |

Colors

| Class | CSS Property | |---|---| | chai-bg-{color} | backgroundColor | | chai-text-{color} | color | | chai-fill-{color} | fill | | chai-stroke-{color} | stroke | | chai-borderColor-{color} | borderColor | | chai-outlineColor-{color} | outlineColor | | chai-accentColor-{color} | accentColor | | chai-caretColor-{color} | caretColor |

Typography

| Class | CSS Property | |---|---| | chai-fontSize-{n} | fontSize | | chai-fontWeight-{n} | fontWeight | | chai-fontStyle-{v} | fontStyle | | chai-lineHeight-{n} | lineHeight | | chai-letterSpacing-{n} | letterSpacing | | chai-textAlign-{v} | textAlign | | chai-textTransform-{v} | textTransform | | chai-textDecor-{v} | textDecoration | | chai-textOverflow-{v} | textOverflow | | chai-whiteSpace-{v} | whiteSpace | | chai-lineClamp-{n} | -webkit-line-clamp | | chai-wordBreak-{v} | wordBreak |

Borders & Radius

| Class | CSS Property | |---|---| | chai-border-{v} | border | | chai-borderW-{n} | borderWidth | | chai-borderStyle-{v} | borderStyle | | chai-borderColor-{color} | borderColor | | chai-rounded-{n} | borderRadius | | chai-roundedT-{n} | top-left + top-right radius | | chai-roundedB-{n} | bottom-left + bottom-right radius | | chai-roundedTL-{n} | borderTopLeftRadius | | chai-roundedTR-{n} | borderTopRightRadius | | chai-roundedBL-{n} | borderBottomLeftRadius | | chai-roundedBR-{n} | borderBottomRightRadius |

Layout & Display

| Class | CSS Property | |---|---| | chai-d-{v} | display | | chai-pos-{v} | position | | chai-overflow-{v} | overflow | | chai-overflowX-{v} | overflowX | | chai-overflowY-{v} | overflowY | | chai-z-{n} | zIndex | | chai-opacity-{n} | opacity | | chai-visibility-{v} | visibility | | chai-cursor-{v} | cursor | | chai-objectFit-{v} | objectFit |

Flexbox

| Class | CSS Property | |---|---| | chai-flex-{v} | flex | | chai-flexDir-{v} | flexDirection | | chai-flexWrap-{v} | flexWrap | | chai-flexGrow-{n} | flexGrow | | chai-flexShrink-{n} | flexShrink | | chai-flexBasis-{n} | flexBasis | | chai-alignItems-{v} | alignItems | | chai-alignSelf-{v} | alignSelf | | chai-alignContent-{v} | alignContent | | chai-justifyContent-{v} | justifyContent | | chai-justifyItems-{v} | justifyItems | | chai-justifySelf-{v} | justifySelf | | chai-placeItems-{v} | placeItems | | chai-order-{n} | order |

Grid

| Class | CSS Property | |---|---| | chai-gridCols-{v} | gridTemplateColumns | | chai-gridRows-{v} | gridTemplateRows | | chai-gridArea-{v} | gridArea | | chai-gridAutoFlow-{v} | gridAutoFlow | | chai-colStart-{n} | gridColumnStart | | chai-colEnd-{n} | gridColumnEnd | | chai-rowStart-{n} | gridRowStart | | chai-rowEnd-{n} | gridRowEnd |

Position

| Class | CSS Property | |---|---| | chai-top-{n} | top | | chai-bottom-{n} | bottom | | chai-left-{n} | left | | chai-right-{n} | right | | chai-inset-{n} | inset | | chai-insetX-{n} | left + right | | chai-insetY-{n} | top + bottom | | chai-z-{n} | zIndex |

Transforms & Transitions

| Class | CSS Property | |---|---| | chai-transform-{v} | transform | | chai-rotate-{v} | rotate | | chai-scale-{v} | scale | | chai-translate-{v} | translate | | chai-transition-{v} | transition | | chai-duration-{n} | transitionDuration | | chai-delay-{n} | transitionDelay | | chai-ease-{v} | transitionTimingFunction |

Shadow & Filter

| Class | CSS Property | |---|---| | chai-shadow-{v} | boxShadow | | chai-filter-{v} | filter | | chai-backdropFilter-{v} | backdropFilter | | chai-blur-{v} | filter | | chai-opacity-{n} | opacity |


Color Palette

chai includes the full Tailwind color palette with shades from 50 to 950.

Available color families: slate · gray · zinc · neutral · stone · red · orange · amber · yellow · lime · green · emerald · teal · cyan · sky · blue · indigo · violet · purple · fuchsia · pink · rose

Usage:

chai-bg-{color}-{shade}
chai-text-{color}-{shade}
chai-borderColor-{color}-{shade}

Examples:

<div class="chai-bg-blue-500">   <!-- backgroundColor: #3b82f6 -->
<p  class="chai-text-rose-400">  <!-- color: #fb7185 -->
<hr class="chai-bg-slate-200">   <!-- backgroundColor: #e2e8f0 -->

Special values: black, white, transparent, current


Value Rules

| Value type | Example | What chai does | |---|---|---| | Plain number | 16, 8, 24 | Appends px16px | | Number with unit | 1.5rem, 50%, 100vh | Used as-is | | Color name | red-500, indigo-400 | Resolved to hex → #ef4444 | | Keyword | auto, flex, none, center | Used as-is | | Raw hex | #ff0000 | Used as-is |


Examples

Card component

<div class="
  chai-bg-slate-800
  chai-px-24 chai-py-20
  chai-rounded-16
  chai-shadow-lg
">
  <h2 class="chai-text-white chai-fontSize-20 chai-fontWeight-700 chai-mb-8">
    Title
  </h2>
  <p class="chai-text-slate-400 chai-fontSize-14 chai-lineHeight-1.6">
    Some description text here.
  </p>
</div>

Flex row

<div class="chai-d-flex chai-alignItems-center chai-justifyContent-between chai-gap-16">
  <span class="chai-text-slate-300 chai-fontSize-14">Label</span>
  <button class="chai-bg-indigo-600 chai-text-white chai-px-16 chai-py-8 chai-rounded-8">
    Action
  </button>
</div>

Responsive-ish sizing

<img
  class="chai-w-100 chai-h-200 chai-objectFit-cover chai-rounded-12"
  src="photo.jpg"
  alt="Photo"
/>

Dark badge

<span class="
  chai-bg-indigo-950
  chai-text-indigo-300
  chai-fontSize-11
  chai-px-10 chai-py-4
  chai-rounded-100
  chai-letterSpacing-0.08em
  chai-textTransform-uppercase
">
  New
</span>

Setup with Vite

<!-- index.html -->
<body>
  <div class="chai-bg-slate-950 chai-px-32 chai-py-24">
    <h1 class="chai-text-white chai-fontSize-32 chai-fontWeight-800">
      Hello chai ☕
    </h1>
  </div>
  <script type="module" src="./src/main.js"></script>
</body>
// src/main.js
import { scan }       from "./scanner.js";
import { parse }      from "./parser.js";
import { applyStyle } from "./apply.js";

function run() {
  scan().forEach(item => applyStyle(item.element, parse(item.className)));
}

document.readyState === "loading"
  ? document.addEventListener("DOMContentLoaded", run)
  : run();

Then run:

npm create vite@latest my-app -- --template vanilla
cd my-app
npm install
npm run dev

Extending chai

Add a new property shorthand

Open config/propertyMap.js and add your key:

export const propertyMap = {
  // ...existing properties...

  // your new ones:
  trackColor: "scrollbarColor",
  txtSize:    "fontSize",
  bd:         ["borderLeft", "borderRight", "borderTop", "borderBottom"],
};

Now chai-trackColor-slate-500 and chai-txtSize-18 work immediately.

Add a custom color

Open config/propertyMap.js and add to categoryGroups.colors:

export const categoryGroups = {
  // ...
  colors: {
    // ...existing colors...
    "brand":      "#your-hex",
    "brand-light":"#your-light-hex",
    "brand-dark": "#your-dark-hex",
  }
};

Now chai-bg-brand and chai-text-brand-light work.


Limitations

Since chai applies inline styles, it cannot handle:

  • Pseudo-classes like :hover, :focus, :nth-child — use a <style> block for these
  • Media queries — add responsive logic manually in JS if needed
  • CSS variables — you can pass them as values (chai-color-var(--my-color)) but they must already be defined
  • Complex values with spaces — e.g. chai-shadow-0 2px 8px black won't parse — define these in a <style> block

File Overview

| File | Purpose | |---|---| | config/propertyMap.js | All shorthand keys → CSS properties + color palette | | src/scanner.js | Finds all chai- elements in the DOM | | src/parser.js | Parses "chai-bg-red-500" into { property, value } | | src/apply.js | Resolves values and sets element.style | | src/main.js | Runs the engine on page load | | index.html | Your HTML — use chai- classes here |


License

MIT — build whatever you want with it. ☕