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

zynaui

v0.1.0-beta.1

Published

Tailwind CSS component library + D3 chart Web Components by Binary Tech Ltd

Readme

Zyna UI

Tailwind CSS component library + D3-powered chart Web Components Built by Binary Tech Ltd · Open source · MIT License

npm version License: MIT Website


What's included

| Package | Description | |---------|-------------| | Tailwind plugin | Semantic classes: .btn, .card, .badge, .alert | | Chart Web Components | <zyna-waffle>, <zyna-timeline>, <zyna-nightingale>, <zyna-lollipop>, <zyna-orbital> |

Framework-agnostic — works in React, Vue, Svelte, Blade, or plain HTML.


UI Components (Tailwind Plugin)

Installation

npm install zynaui tailwindcss

Tailwind v3tailwind.config.js:

module.exports = {
  content: ['./src/**/*.{html,js,jsx,ts,tsx,vue,svelte}'],
  plugins: [require('zynaui')],
}

Tailwind v4app.css:

@import "tailwindcss";
@plugin "zynaui";

Plugin options

prefix — avoid class name conflicts

If another library in your project already uses .btn, .card, .badge, or .alert, add a prefix:

Tailwind v3:

plugins: [require('zynaui')({ prefix: 'z-' })]
// → .z-btn, .z-btn-primary, .z-card, .z-badge, .z-alert …

Tailwind v4:

@plugin "zynaui" {
  prefix: z-;
}

Tailwind utilities

ZynaUI extends the Tailwind theme with semantic color and radius tokens, so you can use them as native utility classes:

<!-- Status colors -->
<span class="text-zyna-success">Operational</span>
<span class="text-zyna-danger">Critical</span>
<span class="text-zyna-warning">Degraded</span>
<span class="text-zyna-info">Updating</span>
<span class="text-zyna-muted">Offline</span>

<!-- Brand color -->
<span class="text-zyna">Gold accent</span>

<!-- Corner radius (respects active genre) -->
<div class="rounded-zyna-sm">…</div>
<div class="rounded-zyna">…</div>
<div class="rounded-zyna-lg">…</div>

These resolve to CSS variables (e.g. text-zyna-successcolor: var(--z-color-success)) and update automatically when the active genre changes.


Buttons

<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-ghost">Ghost</button>
<button class="btn btn-danger">Danger</button>

<!-- Sizes -->
<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary btn-lg">Large</button>

<!-- Icon button -->
<button class="btn btn-primary btn-icon">
  <svg>…</svg>
</button>

Custom button variant — set CSS variables, no plugin changes needed:

.btn-plasma {
  --btn-bg:                rgba(139, 0, 255, 0.38);
  --btn-color:             #BF5FFF;
  --btn-filter:            drop-shadow(0 0 8px rgba(139,0,255,0.45));
  --btn-scan-color:        rgba(139, 0, 255, 0.18);
  --btn-hover-filter:      drop-shadow(0 0 22px rgba(139,0,255,1)) brightness(1.10);
  --btn-hover-text-shadow: 0 0 16px rgba(200,100,255,0.7);
}

Badges

<span class="badge badge-primary">New</span>
<span class="badge badge-success badge-pulse">Active</span>
<span class="badge badge-danger">Error</span>
<span class="badge badge-warning">Pending</span>
<span class="badge badge-info">Info</span>
<span class="badge badge-neutral">Draft</span>

<!-- Large -->
<span class="badge badge-primary badge-lg">Featured</span>

Custom badge variant:

.badge-plasma {
  --badge-bg:    rgba(139, 0, 255, 0.10);
  --badge-color: #BF5FFF;
  --badge-glow:  drop-shadow(0 0 5px rgba(139,0,255,0.45))
                 drop-shadow(0 0 14px rgba(139,0,255,0.14));
}

Cards

<div class="card">
  <div class="card-header">System Status</div>
  <div class="card-body">
    <p class="card-title">Card Title</p>
    <p class="card-subtitle">Supporting subtitle</p>
    <p>Body content here.</p>
  </div>
  <div class="card-footer">Footer</div>
</div>

<!-- Variants -->
<div class="card card-dark">…</div>
<div class="card card-glow">…</div>
<div class="card card-compact">…</div>

Custom card variant:

.card-cyber {
  --card-gradient:      linear-gradient(145deg, rgba(0,20,30,0.97) 0%, rgba(0,10,18,0.97) 100%);
  --card-border-color:  rgba(0,212,255,0.22);
  --card-bracket-color: rgba(0,212,255,0.55);
  --card-bar-gradient:  linear-gradient(90deg, transparent 0%, rgba(0,212,255,0.55) 25%, rgba(0,212,255,0.55) 75%, transparent 100%);
  --card-glow-lo:       rgba(0,212,255,0.12);
  --card-glow-hi:       rgba(0,212,255,0.26);
  --card-animation:     zyna-card-pulse 4s ease-in-out infinite;
}

Alerts

<div class="alert alert-success">
  <p class="alert-title">Success</p>
  <p>Your changes have been saved.</p>
</div>

<div class="alert alert-danger">…</div>
<div class="alert alert-warning">…</div>
<div class="alert alert-info">…</div>

Custom alert variant:

.alert-plasma {
  --alert-bar-color:    #BF5FFF;
  --alert-bg:           rgba(139, 0, 255, 0.055);
  --alert-color:        rgba(191, 95, 255, 0.88);
  --alert-shadow:       0 0 30px rgba(139,0,255,0.08),
                        inset 4px 0 18px rgba(139,0,255,0.05);
  --alert-title-shadow: 0 0 12px rgba(191,95,255,0.65);
}

Chart Web Components

React & Next.js — typed wrapper components

Install the wrapper and get typed React components that accept native arrays and numbers:

npm install zynaui
import { ZynaWaffle, ZynaTimeline, ZynaNightingale, ZynaLollipop, ZynaOrbital } from 'zynaui/react'

export default function Charts() {
  const data = [
    { label: 'Food',    value: 35, color: '#C9A84C' },
    { label: 'Shelter', value: 25, color: '#009EDB', outline: true },
  ]
  return <ZynaWaffle data={data} cols={10} gap={3} />
}

The 'use client' directive is baked into the package — works with Next.js App Router out of the box. The IIFE bundle is inlined, so no file copying or next/script setup is needed.


Via bundler (Vue / Svelte / Astro)

import 'zynaui/charts'

Individual chart imports

import 'zynaui/charts/waffle'
import 'zynaui/charts/timeline'
import 'zynaui/charts/nightingale'
import 'zynaui/charts/lollipop'
import 'zynaui/charts/orbital'

Via CDN / Vanilla HTML (no bundler)

Link the pre-compiled CSS and load the IIFE bundle — no build step needed:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/zynaui/dist/zynaui.css" />
<script src="https://cdn.jsdelivr.net/npm/zynaui/dist/zyna-charts.iife.js"></script>

Or if installed via npm:

<link rel="stylesheet" href="node_modules/zynaui/dist/zynaui.css" />
<script src="node_modules/zynaui/dist/zyna-charts.iife.js"></script>

<zyna-waffle>

Waffle chart — square-grid cells, each filled or outline-only.

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | data | JSON array | [] | [{ label, value, color?, outline? }] | | color | hex | #C9A84C | Fallback cell color | | cols | number | 10 | Grid columns | | gap | number | 3 | Gap between cells (px) |

<zyna-waffle
  data='[
    { "label": "UK",  "value": 24, "color": "#1A3A6B" },
    { "label": "US",  "value": 28, "color": "#009EDB" },
    { "label": "EU",  "value": 20, "color": "#4A6741", "outline": true }
  ]'
></zyna-waffle>

<zyna-timeline>

Proportional-circle timeline — bubble area encodes value.

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | data | JSON array | [] | [{ label, value, note? }] | | color | hex | #C9A84C | Accent color for highlighted item | | theme | dark/light | dark | Color theme | | highlight | string | highest value | Label of the item to emphasize |

<zyna-timeline
  data='[
    { "label": "2019", "value": 120 },
    { "label": "2020", "value": 95, "note": "COVID" },
    { "label": "2021", "value": 180 },
    { "label": "2022", "value": 210 }
  ]'
  highlight="2022"
></zyna-timeline>

<zyna-nightingale>

Nightingale (rose) chart — sector radius encodes value.

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | data | JSON array | [] | [{ label, value, color? }] | | color | hex | #C9A84C | Fallback sector color | | theme | dark/light | dark | Color theme |

<zyna-nightingale
  data='[
    { "label": "Food",      "value": 42, "color": "#C9A84C" },
    { "label": "Shelter",   "value": 31, "color": "#009EDB" },
    { "label": "Education", "value": 18, "color": "#00FFB2" },
    { "label": "Health",    "value": 27, "color": "#FF3366" }
  ]'
></zyna-nightingale>

<zyna-lollipop>

Horizontal lollipop chart — line + circle encodes value.

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | data | JSON array | [] | [{ label, value }] sorted descending recommended | | color | hex | #C9A84C | Accent color for the top item | | theme | dark/light | dark | Color theme |

<zyna-lollipop
  data='[
    { "label": "Libya",  "value": 820 },
    { "label": "Sudan",  "value": 610 },
    { "label": "Syria",  "value": 490 },
    { "label": "Yemen",  "value": 380 }
  ]'
></zyna-lollipop>

<zyna-orbital>

Concentric arc chart — each ring filled as a proportion of a full circle.

| Attribute | Type | Default | Description | |-----------|------|---------|-------------| | data | JSON array | [] | [{ label, value, color? }]value is 01 | | color | hex | #C9A84C | Fallback ring color | | theme | dark/light | dark | Color theme |

<zyna-orbital
  data='[
    { "label": "Delivered", "value": 0.78, "color": "#C9A84C" },
    { "label": "In Transit","value": 0.55, "color": "#009EDB" },
    { "label": "Planned",   "value": 0.32, "color": "#00FFB2" }
  ]'
></zyna-orbital>

Custom genres

Create a fully custom visual paradigm with defineGenre:

import { defineGenre, registerGenre } from 'zynaui/genres'

const aurora = defineGenre({
  name: 'Aurora',
  palette: { brand: '#BF5FFF' },
  tokens: {
    '--zyna':            '#BF5FFF',
    '--z-ease-enter':    'cubic-bezier(0.34, 1.56, 0.64, 1)',
    '--z-duration-fast': '0.14s',
  },
  styles: {
    'html[data-genre="aurora"]': {
      '--z-btn-clip':   'inset(0)',
      '--z-badge-clip': 'inset(0 round 4px)',
    },
  },
})

registerGenre(aurora)

Activate at runtime:

document.documentElement.setAttribute('data-genre', 'aurora')

Note: Genre structural styles (styles) are compiled into zynaui.css at Tailwind build time. Register custom genres before your build step runs so their rules are included in the output.


Build

npm install
npm run build

Outputs:

| File | Format | Use case | |------|--------|----------| | dist/zyna-plugin.cjs | CommonJS | Tailwind config require() | | dist/zyna-plugin.js | ESM | Bundler import | | dist/genres.js | ESM | import { defineGenre } from 'zynaui/genres' | | dist/zyna-charts.js | ESM | Bundler import 'zynaui/charts' | | dist/zyna-charts.iife.js | IIFE | <script src> with no bundler | | dist/zyna-charts-stub.cjs | CJS stub | SSR environments (auto-selected) | | dist/react.js | ESM | import { ZynaWaffle } from 'zynaui/react' | | dist/zynaui.css | CSS | Pre-compiled CSS for CDN / vanilla HTML |

# Build only the Tailwind plugin
npm run build:lib

# Build only the IIFE bundle (CDN)
npm run build:iife

# Build only the docs CSS
npm run build:css

CSS Variable API

All components are driven entirely by CSS custom properties. Create custom variants without touching plugin source:

/* A custom button — just set variables */
.btn-ocean {
  --btn-bg:           linear-gradient(135deg, #006994 0%, #003d5b 100%);
  --btn-color:        #7ED8F6;
  --btn-filter:       drop-shadow(0 0 8px rgba(0,105,148,0.5));
  --btn-hover-filter: drop-shadow(0 0 22px rgba(0,185,255,0.9)) brightness(1.12);
}

See the JSDoc at the top of each component file in src/plugin/components/ for the full variable reference.


Credits

The semantic component class naming convention (.btn, .btn-primary, .card, .badge, .alert, etc.) is inspired by DaisyUI by Pouya Saadeghi — the leading semantic Tailwind component library. Zyna UI takes that convention and applies a dark, HUD-style aesthetic with CSS custom properties, clip-path geometry, and D3-powered chart Web Components.


License

MIT © Binary Tech Ltd