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

strata-css

v1.1.0

Published

A modern CSS framework combining Bootstrap components with Tailwind JIT processing

Readme

Strata CSS

A modern CSS framework combining Bootstrap's component architecture with Tailwind's JIT processing.

License: MIT Version Node npm css-framework PostCSS plugin JIT Themes

css-framework · tailwindcss · bootstrap · postcss · postcss-plugin · jit · component-library · theming · utility-first

Getting Started · Live Demo · Components · Utilities · Theming · Configuration


What is Strata?

Strata is an open source CSS framework that takes the best from Bootstrap and Tailwind while fixing their biggest pain points.

From Bootstrap — component-first classes (btn-primary, card, navbar) that work out of the box with zero configuration.

From Tailwind — JIT post-processing that generates only the CSS you actually use, keeping output lean.

Strata's own contributions:

  • No !important anywhere in framework CSS — @layer handles all specificity
  • Custom CSS is fully compatible and always wins automatically
  • Three built-in themes: light, dark, and dim — plus unlimited custom themes
  • Buttery smooth transitions built in by default on all interactive elements
  • State management via data-st-* attributes — no class toggling in JavaScript
  • Arbitrary value utilities — mt-[24px], bg-[#ff0000], w-[347px]

Benchmarks

| Metric | Strata | Tailwind CSS 3 | |---|---|---| | Cold build average | 3.82ms | 7.21ms | | Cold build median | 3.78ms | 4.55ms | | Cold build p95 | 4.40ms | 6.12ms |

Tailwind figures are official watch-mode reference numbers. Strata numbers are from a cold build with cache invalidated on every run — the most conservative possible measurement. Warm rebuilds (the common case in development) are significantly faster as unchanged output is returned from cache with zero reprocessing.

Results generated via npm run benchmark. See benchmark/ for the reproducible script.


Live Demo

View the interactive component showcase: aftabibrahimkazi.github.io/strata

To view locally: open docs/index.html directly in a browser — no build step required.


Getting Started

Installation

npm install strata-css

Publishing: Run npm publish --dry-run to verify the package contents, then npm publish to release.

Scaffold a new project

npx strata-css init

Note: Use strata-css (with the hyphen), not strata — there is an unrelated npm package called strata that will be picked up instead.

This creates:

strata.config.js    ← configuration
strata.css          ← entry point with @strata directives
postcss.config.js   ← PostCSS setup
dist/               ← generated CSS output

Link the output CSS in your HTML

<link rel="stylesheet" href="dist/strata.output.css">

Set a theme on your HTML element

<html data-st-theme="light">

Run in development

npm run dev

Build for production

npm run build

How It Works

Strata is a PostCSS plugin. It scans your source files for class names and generates only the CSS those classes need — nothing more.

Source files (HTML/JSX/Vue/Astro)
        ↓
    Scanner (extracts class names)
        ↓
    Registry (O(1) Map lookup)
        ↓
    Generator (builds CSS)
        ↓
    @layer st-base, st-components, st-utilities
        ↓
    Output CSS

Your custom CSS lives outside any layer and automatically wins over Strata styles — no !important needed.


Components

Components are full Bootstrap-style classes with states baked in. They live in @layer st-components so your custom CSS always overrides them.

Buttons

<button class="btn-primary">Primary</button>
<button class="btn-secondary">Secondary</button>
<button class="btn-success">Success</button>
<button class="btn-danger">Danger</button>
<button class="btn-warning">Warning</button>
<button class="btn-info">Info</button>
<button class="btn-light">Light</button>
<button class="btn-dark">Dark</button>

Layout

<div class="container">
  <div class="row">
    <div class="col-md-6 col-lg-4">Column</div>
    <div class="col-md-6 col-lg-8">Column</div>
  </div>
</div>

Cards

<div class="card">
  <div class="card-header">Header</div>
  <div class="card-body">Body</div>
  <div class="card-footer">Footer</div>
</div>

Utilities

Utilities follow Bootstrap's naming convention and support arbitrary values via Tailwind-style syntax.

Spacing

<!-- Scale values (0-5) -->
<div class="mt-3 mb-2 px-4 py-1">
<div class="mx-auto my-3">

<!-- Arbitrary values -->
<div class="mt-[24px] px-[1.5rem]">

<!-- Important variants -->
<div class="!mt-0 !mb-0">

Display

<div class="d-flex">
<div class="d-none">
<div class="d-block">
<div class="d-grid">

<!-- Responsive -->
<div class="d-none d-md-flex">

Colours

<!-- Text -->
<p class="text-primary">
<p class="text-[#ff0000]">

<!-- Background -->
<div class="bg-success">
<div class="bg-[rgba(0,0,0,0.5)]">

Theming

Built-in themes

<html data-st-theme="light">   <!-- default -->
<html data-st-theme="dark">    <!-- dark mode -->
<html data-st-theme="dim">     <!-- intermediate -->

System preference

If no data-st-theme is set, Strata automatically follows the user's system preference via prefers-color-scheme.

Custom theme

[data-st-theme="brand"] {
  --st-primary: #7c3aed;
  --st-bg:      #0f0f0f;
  --st-text:    #fafafa;
}
<html data-st-theme="brand">

Switch theme with JavaScript

document.documentElement.setAttribute('data-st-theme', 'dark')

Theme Toggle

Cycle through all built-in themes with a single button — no framework needed.

<button id="theme-toggle">Toggle Theme</button>

<script>
  const themes = ['light', 'dark', 'dim']
  let current = 0

  document.getElementById('theme-toggle').addEventListener('click', () => {
    current = (current + 1) % themes.length
    document.documentElement.setAttribute('data-st-theme', themes[current])
  })
</script>

To start from the user's current theme rather than always resetting to light, read the attribute first:

const themes = ['light', 'dark', 'dim']
const initial = document.documentElement.getAttribute('data-st-theme') || 'light'
let current = themes.indexOf(initial)
if (current === -1) current = 0

To include your own custom themes in the cycle, add them to the array:

const themes = ['light', 'dark', 'dim', 'brand']

Any theme in the array must have its CSS variables defined before it can be toggled to:

[data-st-theme="brand"] {
  --st-primary: #7c3aed;
  --st-bg:      #0f0f0f;
  --st-text:    #fafafa;
}

Override CSS variables

:root {
  --st-primary:        #7c3aed;
  --st-border-radius:  8px;
  --st-duration:       300ms;
}

Transitions

Strata builds smooth transitions into every interactive element by default.

Control globally

/* Slow all transitions */
:root { --st-duration: 400ms; }

/* Kill all transitions */
:root { --st-duration: 0ms; }

Control per component

.btn-primary { --st-duration: 80ms; }

Transition utilities

<div class="transition">
<div class="transition-fast">
<div class="transition-slow">
<div class="transition-none">
<div class="transition-[background-color_0.3s_ease]">
<div class="duration-[400ms]">
<div class="ease-in">
<div class="ease-out">

Reduced motion

Strata automatically respects prefers-reduced-motion — no configuration needed.


State Management

States are managed via data-st-* attributes. JavaScript sets the attribute, CSS handles the visual change.

<!-- Visibility with fade transition -->
<div data-st-visible="true">Visible</div>
<div data-st-visible="false">Hidden (faded out)</div>

<!-- Collapse with smooth height transition -->
<div data-st-collapsed="false">Expanded</div>
<div data-st-collapsed="true">Collapsed</div>

<!-- Loading state -->
<button data-st-loading="true">Loading...</button>

<!-- Disabled state -->
<button data-st-disabled="true">Disabled</button>
// Toggle visibility
element.setAttribute('data-st-visible', 'false')

// Collapse/expand
element.setAttribute('data-st-collapsed', 'true')

Standalone Packages

All Strata plugins are available as independent packages. Use them without Strata, or use them with Strata — the API is identical either way.

| Package | Standalone global | With Strata | Install | |---|---|---|---| | @strata-css/skeleton-loader | SkeletonLoader | Strata.skeleton | npm i @strata-css/skeleton-loader | | @strata-css/modal | StrataModal | Strata.Modal | npm i @strata-css/modal | | @strata-css/chart | StrataChart | Strata.Chart | npm i @strata-css/chart |

How detection works

When strata.components.js is loaded it sets data-strata on <html>. Each plugin checks for this at runtime and registers under the Strata namespace if present, or its own standalone global if not. No configuration required from you — it is automatic.

Standalone usage (no Strata)

<!-- Skeleton -->
<link rel="stylesheet" href="node_modules/@strata-css/skeleton-loader/skeleton-loader.css">
<script src="node_modules/@strata-css/skeleton-loader/skeleton-loader.js"></script>
<script>SkeletonLoader.init('.card')</script>

<!-- Modal -->
<link rel="stylesheet" href="node_modules/@strata-css/modal/modal.css">
<script src="node_modules/@strata-css/modal/modal.js"></script>
<script>StrataModal.open('#myModal')</script>

<!-- Chart (requires Three.js) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="node_modules/@strata-css/chart/chart.js"></script>
<script>StrataChart.create('#myChart', { type: 'bar', data: [...] })</script>

Migrating from standalone to Strata

If you installed a standalone package first and later add Strata, no code changes are required. Strata's presence is detected automatically and the plugin re-registers under the Strata namespace. Your existing markup and JS calls continue to work.


Skeleton Loader

Skeleton loading shows animated shimmer placeholders while content is fetching — preventing layout shift and giving users instant visual feedback that something is coming.

Strata's skeleton system is entirely attribute-driven. There are no class names to add. Instead, set data-st-skeleton on your elements and use the Strata.skeleton JS utility to manage the lifecycle.

Attribute states

| Value | Meaning | |---|---| | "true" | Element shimmers (CSS applies animated ::before overlay) | | "false" | Element revealed (shimmer removed, content shows) | | "null" | JS-managed parent — no overlay on the parent itself, children shimmer individually |

Basic usage

Mark a container and call Strata.skeleton.init() — Strata auto-detects the leaf nodes inside and shimmers them individually.

<div class="card" data-st-skeleton="true">
  <div class="card-header">
    <h3>Card Title</h3>
  </div>
  <div class="card-body">
    <p>Some body text that will load soon.</p>
    <button class="btn-primary">Action</button>
  </div>
</div>
// Initialise — auto-detects leaf nodes inside all [data-st-skeleton="true"] parents
Strata.skeleton.init()

// Simulate data loading, then reveal
fetchData().then(() => {
  Strata.skeleton.reveal()
})

JS API

Strata.skeleton.init()              // auto-discover all skeleton parents on page
Strata.skeleton.init('.card')       // manage specific elements
Strata.skeleton.show('.card')       // re-enter skeleton state
Strata.skeleton.reveal('.card')     // reveal content (removes shimmer)
Strata.skeleton.toggle('.card')     // toggle between skeleton and revealed
Strata.skeleton.revealAt('.card', 0) // reveal one element by index
Strata.skeleton.isSkeleton(el)      // returns true if element is currently shimmering

Staggered reveal

Reveal a list of cards one by one with a delay between each:

Strata.skeleton.reveal('.card', { stagger: 150 })

Opt out a child element

Set data-st-skeleton="false" on any child to exclude it from shimmering entirely:

<div class="card" data-st-skeleton="true">
  <div class="card-header">
    <h3>Title</h3>
    <span data-st-skeleton="false">Always visible badge</span>
  </div>
</div>

Customise the shimmer

Control the shimmer appearance via CSS variables:

:root {
  --st-skeleton-base:     #e2e8f0;  /* bar background colour */
  --st-skeleton-shine:    #f8fafc;  /* highlight colour */
  --st-skeleton-duration: 1.5s;     /* animation speed */
  --st-skeleton-radius:   4px;      /* corner rounding on bars */
}

Realistic card example

A card that shimmers while data loads, then transitions to real content:

<div class="card" id="profile-card" data-st-skeleton="true">
  <div class="card-header">
    <div class="img-wrap">
      <img src="" alt="Avatar" id="avatar">
    </div>
    <h3 id="name"></h3>
  </div>
  <div class="card-body">
    <p id="bio"></p>
    <a href="#" id="profile-link" class="btn-primary">View Profile</a>
  </div>
</div>

<script>
  Strata.skeleton.init('#profile-card')

  loadUser(42).then(user => {
    document.getElementById('avatar').src       = user.avatarUrl
    document.getElementById('name').textContent = user.name
    document.getElementById('bio').textContent  = user.bio
    document.getElementById('profile-link').href = user.profileUrl

    Strata.skeleton.reveal('#profile-card')
  })
</script>

Note on images: Browsers do not support ::before on replaced elements (img, video, iframe). Wrap media in a div — Strata will shimmer the wrapper instead.


Modal

Strata's modal is attribute-driven. Open and close modals via data-st-* attributes or the JS API — no class toggling.

Basic usage

<!-- Trigger -->
<button data-st-toggle="modal" data-st-target="#myModal">Open Modal</button>

<!-- Modal -->
<div class="modal" id="myModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Title</h5>
        <button data-st-dismiss="modal">&times;</button>
      </div>
      <div class="modal-body">
        <p>Modal content here.</p>
      </div>
      <div class="modal-footer">
        <button class="btn-secondary" data-st-dismiss="modal">Close</button>
        <button class="btn-primary">Save</button>
      </div>
    </div>
  </div>
</div>

JS API

Strata.Modal.open('#myModal')   // open by selector or element
Strata.Modal.close()            // close current modal

Static backdrop

<div class="modal" data-st-backdrop="static" ...>

Clicking outside the modal shakes it instead of closing it.

Size variants

<div class="modal modal-sm">   <!-- 300px -->
<div class="modal modal-lg">   <!-- 800px -->
<div class="modal modal-xl">   <!-- 1140px -->
<div class="modal modal-fullscreen">

Events

document.addEventListener('st:modal:open',  e => console.log('opened', e.detail.modal))
document.addEventListener('st:modal:close', e => console.log('closed', e.detail.modal))

Custom CSS

Strata uses CSS @layer internally. Any CSS you write outside a layer automatically wins over Strata styles.

/* This overrides Strata's .btn-primary — no !important needed */
.btn-primary {
  background-color: purple;
  border-radius: 0;
}

/* Only overrides what you specify — other properties stay from Strata */
.card {
  border-radius: 16px; /* changed */
  /* padding, shadow etc. stay as Strata defined */
}

JavaScript Integration

Class naming convention

Classes used in JavaScript carry a -js suffix. Classes used in TypeScript carry a -ts suffix. This signals to any developer reading the code that the element is touched by a script.

<div class="modal-js" id="main-modal-js">
<div class="modal-ts" id="main-modal-ts">

Never toggle classes for state

// Wrong — don't do this
element.classList.add('hidden')
element.classList.toggle('active')

// Right — use data attributes
element.setAttribute('data-st-visible', 'false')
element.setAttribute('data-st-active', 'true')

Configuration

// strata.config.js
module.exports = {
  // Files to scan for class names
  content: [
    './src/**/*.{html,jsx,tsx,vue,astro,svelte}'
  ],

  // Input and output paths
  input:  './strata.css',
  output: './dist/strata.output.css',

  // Theme overrides
  theme: {
    breakpoints: {
      '3xl': '1600px'  // add custom breakpoints
    },
    colors: {
      primary: '#7c3aed'  // override default colors
    }
  },

  // Include or exclude specific components
  components: {
    exclude: ['carousel']
  }
}

Breakpoints

Bootstrap-style — breakpoint embedded inside the class name.

| Breakpoint | Prefix | Min-width | |---|---|---| | Extra small | xs | 0px | | Small | sm | 576px | | Medium | md | 768px | | Large | lg | 992px | | Extra large | xl | 1200px | | Extra extra large | xxl | 1400px |

<div class="col-12 col-md-6 col-lg-4">
<div class="d-none d-md-block">
<div class="mt-2 mt-md-4 mt-lg-5">

CSS Variables Reference

| Variable | Default | Purpose | |---|---|---| | --st-primary | #0d6efd | Primary brand colour | | --st-secondary | #6c757d | Secondary colour | | --st-success | #198754 | Success colour | | --st-danger | #dc3545 | Danger colour | | --st-warning | #ffc107 | Warning colour | | --st-info | #0dcaf0 | Info colour | | --st-bg | #ffffff | Page background | | --st-text | #212529 | Body text | | --st-border | #dee2e6 | Border colour | | --st-border-radius | 0.375rem | Default radius | | --st-duration | 200ms | Transition duration | | --st-easing | cubic-bezier(0.4,0,0.2,1) | Transition easing | | --st-shadow | 0 0.5rem 1rem rgba(0,0,0,0.15) | Default shadow | | --st-font-family | System font stack | Body font |


Framework Compatibility

Strata works with any project that can consume a CSS file.

| Framework | Supported | |---|---| | Plain HTML | ✓ | | React / Next.js | ✓ | | Vue / Nuxt | ✓ | | Astro | ✓ | | Svelte / SvelteKit | ✓ | | Angular | ✓ | | PHP / Laravel | ✓ | | Django / Rails | ✓ |


Build Tool Integration

Vite

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  css: {
    postcss: {
      plugins: [require('strata-css')]
    }
  }
})

Webpack

// webpack.config.js
module.exports = {
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader', 'css-loader', 'postcss-loader']
    }]
  }
}

PostCSS

// postcss.config.js
module.exports = {
  plugins: [
    require('strata-css'),
    require('autoprefixer')
  ]
}

Roadmap

v1.0 — Current

Full component library, utility system, JIT processing, three-theme system, transition system.

v2.0 — Planned

  • Formal plugin API
  • VSCode IntelliSense extension
  • Strata DevTools browser extension
  • Design token pipeline (Figma support)
  • Storybook integration

Acknowledgements

Strata builds on the shoulders of excellent prior work:

  • Bootstrap (MIT) — component class naming conventions, breakpoint scale, color palette, and form patterns that Strata's API is compatible with
  • Tailwind CSS (MIT) — the JIT processing concept and arbitrary value syntax (mt-[24px], bg-[#ff0000])
  • PostCSS (MIT) — the build pipeline that powers Strata's @strata directive processing

Strata's component architecture, cascade layer system, data-st-* state model, theming engine, and JIT registry are original work.


Creating a GitHub Release

The v1.0.0 tag already exists. To publish the GitHub Release from it:

gh release create v1.0.0 \
  --title "Strata CSS v1.0.0" \
  --notes-file CHANGELOG.md \
  --verify-tag

Contributing

Contributions are welcome. Please read CONTRIBUTING.md before submitting a pull request.


License

MIT © 2026 Aftab Ibrahim Kazi