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

@fmlj/uikit

v1.0.11

Published

Modern React component library built with Tailwind CSS v4

Readme

@fmlj/uikit

A modern React component library built for speed.

76 components · Tailwind CSS v4 · Slot-based theming · Tree-shakeable

CI npm downloads bundle size license

Changelog · Report Bug · Request Feature


Why This Library?

| | @fmlj/uikit | shadcn/ui | Ant Design | Chakra UI | |---|---|---|---|---| | Theming | Slot-based color system — 1 prop themes everything | Copy-paste, manual | Token config object | colorScheme prop | | Tailwind | v4 native (@theme, @source) | v3 with config | No Tailwind | No Tailwind | | Bundle | Tree-shake per component | Copy into project | 300KB+ full bundle | 200KB+ full bundle | | Dark mode | Zero-config CSS variables | Manual dark: classes | ConfigProvider | ColorModeProvider | | Components | 76 production-ready | ~50 primitives | 60+ | 60+ | | Tests | 1,556 tests | Community | Extensive | Moderate |

The Slot Color System

One color prop. Every part of the component responds — backgrounds, borders, text, hover states, focus rings. No manual mapping. No 49 color variants hardcoded per component.

<Button color="primary">Submit</Button>
<Button color="error">Delete</Button>
<Alert color="warning">Watch out</Alert>
<Badge color="success">Active</Badge>

Under the hood, color="primary" sets a single CSS variable --_c. Every slot utility (bg-slot, text-slot, border-slot-30, bg-slot-10) derives from it automatically. Add a new color to your theme → every component supports it instantly.

Tailwind CSS v4 Native

Not "works with Tailwind" — built on v4's architecture:

  • @theme block defines all tokens as CSS custom properties
  • @source auto-scans compiled components — no manual safelist
  • @custom-variant dark — dark mode via .dark class on <html>
  • @utility defines the slot color system as real Tailwind utilities
  • When Tailwind ships new features, you get them. No wrapper layer in the way.

Per-Component Imports

Every component is its own entry point. Import what you use, ship only what you use:

import Button from '@fmlj/uikit/button'     // just Button
import Table from '@fmlj/uikit/table'        // just Table
import { useTheme } from '@fmlj/uikit/theme' // just the hook

Quick Start

npm install @fmlj/uikit

Peer deps: react ≥18, react-dom ≥18, lucide-react ≥0.400, tailwindcss ≥4.0

CSS Setup

Your project needs Tailwind CSS v4 with @tailwindcss/vite or @tailwindcss/postcss.

@import "tailwindcss";
@import "@fmlj/uikit/styles/global.css";

That's it. One import. Tokens, dark mode, utilities, component styles — all included.

Use It

import Button from '@fmlj/uikit/button'
import Input from '@fmlj/uikit/input'
import Select from '@fmlj/uikit/select'

function App() {
  return (
    <div className="flex gap-3">
      <Input placeholder="Search..." />
      <Select options={[{ label: 'React', value: 'react' }]} />
      <Button color="primary">Go</Button>
    </div>
  )
}

Dark Mode

import { ThemeProvider, useTheme } from '@fmlj/uikit/theme'

<ThemeProvider defaultTheme="system">
  <App />
</ThemeProvider>

// Toggle anywhere:
const { setTheme } = useTheme()
setTheme('dark') // 'light' | 'dark' | 'system'

SSR flash prevention — add to <head>:

import { getThemeScript } from '@fmlj/uikit/theme'

<script dangerouslySetInnerHTML={{ __html: getThemeScript() }} />

All components use CSS custom properties. Dark mode swaps values at :root. Zero dark: prefixes in component code.

Theme Presets

@import "@fmlj/uikit/styles/global.css";
@import "@fmlj/uikit/styles/themes/presets/corporate.css";
<html data-theme="corporate" class="dark">

Available: corporate, vibrant, minimal. Mix with dark/light freely.

Custom Tokens

Override after our import — no !important needed:

@import "tailwindcss";
@import "@fmlj/uikit/styles/global.css";

/* Your overrides — just plain :root, wins by source order */
:root {
  --color-primary: oklch(0.55 0.22 270);
  --color-primary-hover: oklch(0.50 0.24 270);
  --color-primary-foreground: oklch(1 0 0);
  --color-background: oklch(0.98 0 0);
  --font-sans: 'Inter', system-ui, sans-serif;
  --button-height-md: 2.5rem;
}

/* Optional: different dark mode values */
.dark {
  --color-primary: oklch(0.65 0.22 270);
  --color-background: oklch(0.12 0.01 270);
}

Every token is a CSS variable. Change one, it propagates everywhere. Your :root overrides win by source order — just import after global.css.


Common API

color

'default' | 'primary' | 'secondary' | 'accent' | 'success' | 'error' | 'warning' | 'info'

size

'xs' | 'sm' | 'md' | 'lg'

variant

Per-component:

  • Button: solid outline soft dashed link ghost
  • Card: default solid outline soft ghost elevated
  • Checkbox / Toggle: solid outline soft
  • Input: outline filled
  • Badge / Tag: default solid outline soft

Validation

<Input error="Required field" />
<Input warning="Weak password" />
<Input success />

Styling Escape Hatches

// Root element
<Button className="shadow-lg">Submit</Button>

// Internal parts
<Input classNames={{ root: 'mb-4', label: 'font-bold', input: 'tracking-wide' }} />

// CSS selectors — every part has a semantic class + data-slot
.input_label { font-weight: 700; }
[data-slot="trigger"] { min-width: 200px; }

All 76 Components

| Component | Import | |-----------|--------| | Input | @fmlj/uikit/input | | FloatInput | @fmlj/uikit/float-input | | InputPassword | @fmlj/uikit/input-password | | InputOTP | @fmlj/uikit/input-otp | | InputGroup | @fmlj/uikit/input-group | | NumberInput | @fmlj/uikit/number-input | | Textarea | @fmlj/uikit/textarea | | Select | @fmlj/uikit/select | | MultiSelect | @fmlj/uikit/multi-select | | Cascader | @fmlj/uikit/cascader | | TreeSelect | @fmlj/uikit/tree-select | | DatePicker | @fmlj/uikit/date-picker | | ColorPicker | @fmlj/uikit/color-picker | | Autocomplete | @fmlj/uikit/autocomplete | | Mentions | @fmlj/uikit/mentions | | Checkbox | @fmlj/uikit/checkbox | | CheckboxGroup | @fmlj/uikit/checkbox-group | | Radio | @fmlj/uikit/radio | | RadioGroup | @fmlj/uikit/radio-group | | Switch | @fmlj/uikit/switch | | Slider | @fmlj/uikit/slider | | Rating | @fmlj/uikit/rating | | Toggle | @fmlj/uikit/toggle | | ToggleGroup | @fmlj/uikit/toggle-group | | Upload | @fmlj/uikit/upload | | Clipboard | @fmlj/uikit/clipboard | | TagsInput | @fmlj/uikit/tags-input |

| Component | Import | |-----------|--------| | Button | @fmlj/uikit/button | | ButtonGroup | @fmlj/uikit/button-group | | Card | @fmlj/uikit/card | | Grid | @fmlj/uikit/grid | | Divider | @fmlj/uikit/divider | | Collapse | @fmlj/uikit/collapse | | Accordion | @fmlj/uikit/accordion | | ScrollArea | @fmlj/uikit/scroll-area | | Resizable | @fmlj/uikit/resizable |

| Component | Import | |-----------|--------| | Tabs | @fmlj/uikit/tabs | | Breadcrumbs | @fmlj/uikit/breadcrumbs | | Pagination | @fmlj/uikit/pagination | | Stepper | @fmlj/uikit/stepper | | Dropdown | @fmlj/uikit/dropdown | | ContextMenu | @fmlj/uikit/context-menu | | Menubar | @fmlj/uikit/menubar | | NavigationMenu | @fmlj/uikit/navigation-menu | | Command | @fmlj/uikit/command | | Anchor | @fmlj/uikit/anchor | | Link | @fmlj/uikit/link | | FloatButton | @fmlj/uikit/float-button |

| Component | Import | |-----------|--------| | Modal | @fmlj/uikit/modal | | Drawer | @fmlj/uikit/drawer | | Tooltip | @fmlj/uikit/tooltip | | Popover | @fmlj/uikit/popover | | Tour | @fmlj/uikit/tour |

| Component | Import | |-----------|--------| | Notification | @fmlj/uikit/notification | | Alert | @fmlj/uikit/alert | | Toast | @fmlj/uikit/toast | | Progress | @fmlj/uikit/progress | | Spinner | @fmlj/uikit/spinner | | Skeleton | @fmlj/uikit/skeleton | | Result | @fmlj/uikit/result | | FetchingOverlay | @fmlj/uikit/fetching-overlay |

| Component | Import | |-----------|--------| | Table | @fmlj/uikit/table | | Tree | @fmlj/uikit/tree | | Calendar | @fmlj/uikit/calendar | | Descriptions | @fmlj/uikit/descriptions | | Timeline | @fmlj/uikit/timeline | | Transfer | @fmlj/uikit/transfer | | Carousel | @fmlj/uikit/carousel | | Image | @fmlj/uikit/image | | QRCode | @fmlj/uikit/qr-code |

| Component | Import | |-----------|--------| | Badge | @fmlj/uikit/badge | | Tag | @fmlj/uikit/tag | | Avatar | @fmlj/uikit/avatar | | Kbd | @fmlj/uikit/kbd | | Typography | @fmlj/uikit/typography | | Watermark | @fmlj/uikit/watermark |

| Export | Import | |--------|--------| | ThemeProvider, useTheme, getThemeScript | @fmlj/uikit/theme | | useControllable | @fmlj/uikit/hooks/useControllable | | useDebounce | @fmlj/uikit/hooks/useDebounce | | useThrottle | @fmlj/uikit/hooks/useThrottle | | useMediaQuery | @fmlj/uikit/hooks/useMediaQuery | | useRipple | @fmlj/uikit/hooks/useRipple |


CSS Variables Reference

--color-primary / -hover / -active / -foreground
--color-secondary / -hover / -active / -foreground
--color-accent / -hover / -active / -foreground
--color-success / -hover / -active / -foreground
--color-error / -hover / -active / -foreground
--color-warning / -hover / -active / -foreground
--color-info / -hover / -active / -foreground

--color-background / -secondary
--color-surface
--color-card / -foreground
--color-border / -primary / -hover / -focus

--color-text-primary / -secondary / -muted / -disabled

--color-input-bg / -text / -placeholder / -border / -border-focus / -border-error
--color-focus / -ring
--color-disabled / -text
--color-overlay
--button-height-xs/sm/md/lg      --button-padding-x-xs/sm/md/lg
--input-height-xs/sm/md/lg       --input-padding-x-xs/sm/md/lg
--select-height-xs/sm/md/lg      --select-padding-x-xs/sm/md/lg
--toggle-height-xs/sm/md/lg      --toggle-padding-x-xs/sm/md/lg
--textarea-min-height-xs/sm/md/lg
--checkbox-size-xs/sm/md/lg
--switch-width-xs/sm/md/lg       --switch-height-xs/sm/md/lg
--otp-size-xs/sm/md/lg
--accordion-padding-x-xs/sm/md/lg
--shadow-sm / -md / -lg / -xl / -2xl

--z-dropdown  (1000)    --z-sticky   (1020)
--z-modal     (1040)    --z-popover  (1050)
--z-tooltip   (1060)    --z-overlay  (1070)

TypeScript

Full type coverage. Every prop, variant, and callback is typed:

import type { ButtonProps, SelectOption, TableColumn } from '@fmlj/uikit'

Browser Support

Chrome, Firefox, Safari, Edge — last 2 versions.

License

MIT