NeonKit
esc
  • IntroductionGetting started
  • InstallationGetting started
  • ThemingGetting started
  • Use with AIGetting started
  • All componentsGetting started
  • ButtonSolid, outline, soft, ghost and link buttons that light up on hover.Forms
  • InputText field with an animated neon focus ring, icons, labels and error states.Forms
  • TextareaMulti-line field that grows with its content and counts characters.Forms
  • SelectKeyboard-friendly listbox with a glowing popover and typeahead.Forms
  • CheckboxCheckbox with a drawn-on checkmark and indeterminate state.Forms
  • Radio GroupSingle choice from a set, with arrow-key navigation and card layouts.Forms
  • SwitchA toggle that powers on like a neon tube.Forms
  • SliderPointer and keyboard slider with a glowing track and optional range.Forms
  • OTP InputOne-time code input with auto-advance, paste and backspace handling.Forms
  • BadgeStatus labels with optional live dot and remove button.Data Display
  • AvatarProfile image with initials fallback, status light and stacked groups.Data Display
  • CardSurface with header, content and footer slots and a lit edge.Data Display
  • KbdKeyboard keys and shortcuts that glow when pressed.Data Display
  • TabsTabbed panels with a sliding light indicator and roving focus.Data Display
  • AccordionCollapsible sections with smooth height animation.Data Display
  • ProgressLinear and circular progress with a moving highlight.Feedback
  • SpinnerRing, dots and bars loaders in any neon color.Feedback
  • SkeletonLoading placeholders with a scanning shimmer.Feedback
  • AlertInline messages for info, success, warning and errors.Feedback
  • ToastStacked notifications with a tiny toast() API. No provider needed.Feedback
  • DialogAccessible modal built on the native dialog element.Overlay
  • TooltipHover and focus hints on four sides.Overlay
  • Neon TextText rendered as a glowing tube sign, with optional power-on flicker.Effects
  • Border BeamA beam of light that travels around any element's border.Effects
  • Spotlight CardCard whose border and surface light up under the cursor.Effects
  • Retro GridSynthwave perspective grid that scrolls toward the horizon.Effects

Getting started

Installation

You need React 18 or newer and Tailwind CSS 3.4 or 4. Any framework works. The examples use Next.js and TypeScript.

With the shadcn CLI#

This is the quickest route. Each component is published as a shadcn registry item, so the CLI writes the file, installs its npm dependencies and adds lib/neon.ts for you.

  1. Set up shadcn (skip if you already use it)

    This creates components.json and lib/utils.ts.

    npx shadcn@latest init
  2. Add a component

    npx shadcn@latest add https://get-neonkit.vercel.app/r/switch.json

    Pass several URLs to add them in one go.

    npx shadcn@latest add https://get-neonkit.vercel.app/r/tabs.json https://get-neonkit.vercel.app/r/toast.json https://get-neonkit.vercel.app/r/slider.json
  3. Use it

    import { Switch } from "@/components/ui/switch"
    
    export default function Page() {
      return <Switch color="lime" label="Neon on" defaultChecked />
    }

NeonKit writes to the same components/ui folder as shadcn/ui. If a file with the same name exists (a fresh shadcn init ships a button), the CLI asks first. Add --overwrite to replace it without asking.

Short names#

Register the @neonkit namespace in components.json and drop the URLs. This also makes NeonKit visible to the shadcn MCP server.

components.json
{
  "registries": {
    "@neonkit": "https://get-neonkit.vercel.app/r/{name}.json"
  }
}
npx shadcn@latest add @neonkit/button @neonkit/select

Manual#

Prefer to see every line? It takes about a minute.

  1. Install the two class helpers

    npm install clsx tailwind-merge

    Some components also use motion, lucide-react or @radix-ui/react-slot. Each component page lists what it needs.

  2. Add lib/utils.ts

    lib/utils.ts
    import { type ClassValue, clsx } from "clsx";
    import { twMerge } from "tailwind-merge";
    
    export function cn(...inputs: ClassValue[]) {
      return twMerge(clsx(inputs));
    }
  3. Add lib/neon.ts

    The palette and the one helper that turns a color into the CSS variable.

    lib/neon.ts
    import type * as React from "react";
    
    /**
     * The NeonKit palette, stored as space-separated RGB channels so components
     * can apply any alpha with `rgb(var(--neon) / 0.4)`.
     */
    export const neonColors = {
      cyan: "34 211 238",
      blue: "79 139 255",
      violet: "168 85 247",
      magenta: "240 70 235",
      pink: "255 95 162",
      red: "255 77 94",
      orange: "255 138 61",
      amber: "251 191 36",
      lime: "163 230 53",
      green: "52 211 153",
      white: "230 237 247",
    } as const;
    
    export type NeonColorName = keyof typeof neonColors;
    
    /** A palette name or any hex color (`#0ff`, `#ff00aa`). */
    export type NeonColor = NeonColorName | (string & {});
    
    export const neonColorNames = Object.keys(neonColors) as NeonColorName[];
    
    /** Resolves a palette name or hex string to `"r g b"` channels. */
    export function toNeonRgb(color: NeonColor): string {
      if (color in neonColors) return neonColors[color as NeonColorName];
    
      let hex = color.trim().replace(/^#/, "");
      if (hex.length === 3) hex = hex.replace(/./g, (c) => c + c);
      if (!/^[0-9a-f]{6}$/i.test(hex)) return neonColors.cyan;
    
      const value = parseInt(hex, 16);
      return `${(value >> 16) & 255} ${(value >> 8) & 255} ${value & 255}`;
    }
    
    /**
     * Inline style that sets a component's neon color.
     *
     * Components read `--neon`. Leave `color` undefined and they inherit
     * `--neon-accent` from any ancestor, falling back to cyan.
     */
    export function neonVars(
      color?: NeonColor,
      style?: React.CSSProperties,
    ): React.CSSProperties | undefined {
      if (!color) return style;
      const rgb = toNeonRgb(color);
      return { "--neon": rgb, "--neon-accent": rgb, ...style } as React.CSSProperties;
    }
  4. Check the path alias

    Components import from @/lib/…. Most templates set this up already.

    tsconfig.json
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": { "@/*": ["./*"] }
      }
    }
  5. Copy a component

    Open any component, choose Manual and paste the source into components/ui.

Tailwind 3#

The components avoid utilities that were renamed in v4 and style everything through arbitrary values, so they compile the same on 3.4. Make sure your content globs include the folder you paste them into.

tailwind.config.js
module.exports = {
  content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}"],
}

Background#

NeonKit is dark only. The glows are tuned against #05060a, and anything close to black works.

<body className="bg-[#05060a] text-white antialiased">