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

@fcstudio/fc-ui

v0.1.0

Published

Flying Cat UI — theme-aware React component library. Swap a single provider and reskin every component (Dashboard, Glass, 8-bit, or your own).

Readme

@fcstudio/fc-ui

Flying Cat UI — a theme-aware React component library. Swap one provider and the entire interface reskins.

@fcstudio/fc-ui ships a curated set of accessible React components and three production-ready visual presets — Dashboard, Glass (Apple-style), and 8-bit — driven by a single CSS-variable bag. There is no per-component theme prop, no runtime style engine, no global stylesheet to bolt on. Wrap your tree in <FcProvider>, pick a theme, and every component picks up the new look in the same render.

Why fc-ui

  • One source of truth for theming. Every component reads from --fc-* CSS variables. Switch themes by changing one attribute on the root.
  • Three opinionated presets out of the box. Dashboard for product UI, Glass for marketing-grade visuals, 8-bit for playful surfaces — including fonts, radii, shadows, and motion.
  • Bring your own theme. Add an entry to the exported THEMES map and it shows up in the switcher automatically.
  • Distinct themes, identical API. The same <FcButton> adapts to each preset without prop or className gymnastics.
  • Light footprint. ESM + CJS dual build, tree-shakeable exports, only react, react-dom, and lucide-react as peer dependencies.

Installation

npm install @fcstudio/fc-ui react react-dom lucide-react

Peer requirements: React 18+, React DOM 18+, lucide-react 0.300+.

Quick start

import {
  FcProvider,
  FcToastProvider,
  FcCard,
  FcTitle,
  FcEm,
  FcButton,
  useToast,
} from '@fcstudio/fc-ui';

function SaveButton() {
  const toast = useToast();
  return (
    <FcButton onClick={() => toast({ message: 'Saved!', tone: 'success' })}>
      Save
    </FcButton>
  );
}

export default function App() {
  return (
    <FcProvider defaultTheme="glass">
      <FcToastProvider>
        <FcCard>
          <FcTitle>
            Hello, <FcEm>world</FcEm>
          </FcTitle>
          <SaveButton />
        </FcCard>
      </FcToastProvider>
    </FcProvider>
  );
}

That's it — no CSS import required. <FcProvider> injects the active theme's variables and the base keyframes on its own root.

Switching themes at runtime

useFc() exposes the active theme key and a setter. Every built-in or registered theme works the same way.

import { useFc, THEMES } from '@fcstudio/fc-ui';

function ThemeSwitcher() {
  const { theme, setTheme } = useFc();
  return (
    <select value={theme} onChange={(e) => setTheme(e.target.value)}>
      {Object.entries(THEMES).map(([key, { name }]) => (
        <option key={key} value={key}>
          {name}
        </option>
      ))}
    </select>
  );
}

There's also a ready-made <FcThemeSwitcher /> that renders the same dropdown styled for the current theme.

Adding a custom theme

A theme is just a flat bag of CSS variables. Register a new entry and the switcher picks it up.

import { THEMES } from '@fcstudio/fc-ui';

THEMES.midnight = {
  name: 'Midnight',
  mascot: '🌙',
  vars: {
    '--fc-bg': '#0a0a0f',
    '--fc-surface': '#15151c',
    '--fc-ink': '#e4e4e7',
    '--fc-accent': '#a78bfa',
    // …rest of the --fc-* tokens (see THEMES.dashboard for the full list)
  },
};

Spread an existing theme's vars to inherit defaults and override only what you need:

THEMES.midnight.vars = { ...THEMES.dashboard.vars, '--fc-bg': '#0a0a0f' /* … */ };

What's included

Components are exported flat — no subpaths.

| Category | Exports | | ----------- | -------------------------------------------------------------------------------- | | Core | FcProvider, useFc, THEMES, FONTS_URL | | Layout | HolyGrail (5-slot compound layout) | | Skeleton | Sk.Box, Sk.Circle, Sk.Text | | Typography | FcTitle, FcEm, FcSubtitle, FcText, FcCaption, FcEyebrow, FcLabel | | Buttons | FcButton, FcIconButton, FcSwitch, FcSegmented | | Tags | FcTag, FcBadge, FcKbd, FcChip, FcDot | | Form | FcInput, FcTextarea, FcCheckbox, FcRadio, FcSelect, FcSlider | | Display | FcAvatar, FcAvatarGroup, FcProgress, FcSpinner, FcMetric | | Disclosure | FcAccordion, FcAccordionItem, FcTabs | | Feedback | FcAlert, FcToastProvider, useToast, FcEmpty, FcTooltip, FcModal | | Container | FcCard, FcPanel, FcDivider, FcSection, FcRow | | Navigation | FcNavGroup, FcNavItem, FcBreadcrumb, FcLogo, FcThemeSwitcher, FcDotNavigation, FcDialNav |

How theming works

<FcProvider theme="glass"> sets data-fc-theme="glass" on its root and inlines the matching theme's --fc-* variables. Components reference those variables directly via var(--fc-*), so a theme swap is a one-frame restyle.

Theme-specific treatments (Glass backdrop blur, 8-bit scanlines, press effects) live inside the provider's scoped global stylesheet and are gated by the same data-fc-theme attribute. Components opt into them via lightweight markers like data-fc-slot, data-fc-glass, data-fc-sk, and data-fc-mascot.

The implication: building a custom component that fits the system means consuming --fc-* tokens — never hardcoded colors, radii, or fonts.

TypeScript

Components are authored in JSX and consumed without types in the current release. A .d.ts build is on the roadmap.

Compatibility

  • React 18+ (uses useId, automatic batching paths)
  • Modern evergreen browsers (CSS custom properties, backdrop-filter for the Glass preset)
  • ESM and CJS consumers (dual exports map)

License

MIT © Hyun

Contributing

This repository ships an llms.txt summary for LLM tooling. When you change README.md or the public API under src/ (exports, component files, theme keys, provider/hook signatures), update llms.txt in the same commit. See CLAUDE.md for the exact triggers.