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

burne-ui-devtools

v0.1.5

Published

Runtime theme editor for Burne UI

Readme

burne-ui-devtools

Runtime theme editor for applications using BurneUIProvider.

Compatibility

burne-ui-devtools requires burne-ui >=1.5.10 <2. Earlier releases do not provide the runtime theme API and custom-token support used by the editor.

Both stylesheets are required:

import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

The component must be rendered inside BurneUIProvider.

Vite: lazy, development-only loading

This keeps the devtools JavaScript out of production builds. Put the required stylesheet imports in the application entry file.

import { lazy, Suspense } from "react";
import { BurneUIProvider } from "burne-ui";
import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

import burneTheme from "./burne-theme";

const BurneThemeDevtools = import.meta.env.DEV
  ? lazy(() =>
      import("burne-ui-devtools").then(({ BurneThemeDevtools }) => ({
        default: BurneThemeDevtools,
      })),
    )
  : null;

export function App() {
  return (
    <BurneUIProvider config={burneTheme}>
      <YourApp />
      {BurneThemeDevtools ? (
        <Suspense fallback={null}>
          <BurneThemeDevtools />
        </Suspense>
      ) : null}
    </BurneUIProvider>
  );
}

Next.js: dynamic, development-only loading

Import the global styles from app/layout.tsx:

import "burne-ui/styles.css";
import "burne-ui-devtools/styles.css";

Create a client component such as app/BurneDevtools.tsx:

"use client";

import dynamic from "next/dynamic";

const DevelopmentDevtools =
  process.env.NODE_ENV === "development"
    ? dynamic(
        () =>
          import("burne-ui-devtools").then(
            ({ BurneThemeDevtools }) => BurneThemeDevtools,
          ),
        { ssr: false },
      )
    : null;

export function BurneDevtools() {
  return DevelopmentDevtools ? <DevelopmentDevtools /> : null;
}

Render <BurneDevtools /> anywhere below the client-side BurneUIProvider. The production branch does not request the devtools module.

Custom tokens

All customTokens from the provider config appear in the editor. Primitive shorthand values infer a suitable control:

import type { BurneThemeConfig } from "burne-ui";

export const burneTheme: BurneThemeConfig = {
  theme: "system",
  customTokens: {
    "--app-sidebar-width": "18rem",
    "--app-dense-mode": false,
    "--app-card-opacity": 0.9,
  },
};

Use metadata to control the label, group, description, input type, and range:

export const burneTheme: BurneThemeConfig = {
  customTokens: {
    "--app-card-opacity": {
      value: 0.9,
      label: "Card opacity",
      group: "Application",
      description: "Opacity used by elevated application cards.",
      control: "slider",
      min: 0.5,
      max: 1,
      step: 0.05,
      unit: "×",
    },
    "--app-density": {
      value: "comfortable",
      label: "Density",
      group: "Application",
      control: "select",
      options: [
        { label: "Compact", value: "compact" },
        { label: "Comfortable", value: "comfortable" },
      ],
    },
  },
};

Use values for mode-specific values. The active light or dark value is edited without replacing the other mode:

export const burneTheme: BurneThemeConfig = {
  theme: "system",
  customTokens: {
    "--app-hero-surface": {
      values: {
        light: "#f7f8ff",
        dark: "#111522",
      },
      label: "Hero surface",
      group: "Application colors",
      control: "color",
    },
  },
};

Font presets (Google Fonts)

Choosing a sans/mono preset only writes --font-family-* tokens. The matching Google Font file is lazy-loaded by the editor when you select the preset or when a persisted snapshot is restored:

  1. preconnect to fonts.googleapis.com / fonts.gstatic.com (once).
  2. Inject a stylesheet for that family only (data-burne-theme-font).
  3. Skip system stacks and unknown custom CSS stacks (no network request).

Helpers you can reuse outside the panel:

import {
  ensureThemeFontLoaded,
  FONT_PRESETS,
  THEME_SANS_FONTS_URL,
  THEME_MONO_FONTS_URL,
} from "burne-ui-devtools";

ensureThemeFontLoaded(FONT_PRESETS.find((p) => p.id === "inter"));
// or preload every preset family in docs layout:
// <link rel="stylesheet" href={THEME_SANS_FONTS_URL} />

Production: do not rely on the editor to load fonts. After you pick a face, ship it yourself (self-host, next/font, or a single Google Fonts <link> for the families you keep in burne-theme.ts). Copy/Download config only exports the CSS stack string — not font files.

Actions

  • Reset clears the preview and persisted editor snapshot, then restores the provider's base theme preference (including system) and token values.
  • Shuffle picks a random color preset, Scale slider values, and sans/mono fonts. Motion and animation toggles are left unchanged.
  • Copy CSS copies the current theme as CSS custom properties.
  • Copy config copies a serializable BurneThemeConfig source.
  • Download config downloads the current configuration as burne-theme.ts.

Control ranges (min / max / step)

Edit slider bounds in src/BurneThemeDevtools/burneThemeDevtoolsData.ts:

  • SCALE_CONTROLS — spacing, size, radius, border, type scale (also used by Shuffle)
  • SHADOW_CONTROLS — shadow / toast scrim
  • MOTION_DURATION_CONTROLS / MOTION_SCALE_CONTROLS — motion section

Custom token sliders use min / max / step from the token metadata in your burne-theme.ts customTokens entry.

Props

  • enabled?: boolean — explicit runtime switch, default true. A detected process.env.NODE_ENV === "production" always disables the component.
  • persist?: boolean — localStorage persistence, default true.
  • storageKey?: string — persistence key, default burne-ui-devtools.
  • defaultOpen?: boolean — render the editor open initially.
  • className?: string — class added to the fixed portal root.

For browser builds that do not expose process.env.NODE_ENV, pass the application's own development flag to enabled.