Next.js integration

Set up a Next.js project with Untitled UI React in seconds. Our Next.js starter kit includes providers, routing, and everything you need to get started.

Installation

The easiest way to get started with Untitled UI in a Next.js project is to use our CLI:

Initialize a new Next.js project with Untitled UI

Using our CLI, you can initialize a new Next.js project with Untitled UI with the following command:

npx untitledui@latest init untitled-ui --nextjs

While running the command, you'll be asked a few questions to set up your project:

? What is your project named? › untitled-ui
? Which color would you like to use as the brand color? ›
❯   brand
    red
    orange
    amber
    yellow
    lime
    green
    ...
    zinc
    neutral
    stone

This will create a new Next.js project in the untitled-ui directory with all the necessary configurations and components pre-installed. The choices are Tailwind's built-in palettes; picking one points the --color-brand-* variables in theme.css at it, and brand keeps the default purple. You can change the brand color at any time later (see Theming).

Ready to go!

Great! You're all set to start using Untitled UI components.

If something is missing, you can copy/paste what you need into your project directly from individual components pages.

Need help? Check our GitHub repository for examples, or open an issue if you run into any problems. Our community is here to help!

Manual installation

If you prefer to add Untitled UI to an existing Next.js project, you can follow these steps:

Install packages

Simply install the required packages with your favorite package manager:

npm install @untitledui/icons react-aria-components tailwindcss @tailwindcss/postcss postcss tailwindcss-react-aria-components tailwind-merge tailwindcss-animate next-themes

Create a custom Tailwind CSS configuration

Create a theme.css file in your styles directory and add the following code:

@theme {
    /* FONT FAMILY */
    --font-body: var(--font-inter, "Inter"), -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --font-display: var(--font-inter, "Inter"), -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    --font-mono: ui-monospace, "Roboto Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
 
    /* FONT SIZE */
    --text-xs: calc(var(--spacing) * 3);
    --text-xs--line-height: calc(var(--spacing) * 4.5);
 
    --text-sm: calc(var(--spacing) * 3.5);
    --text-sm--line-height: calc(var(--spacing) * 5);
 
    --text-md: calc(var(--spacing) * 4);
    --text-md--line-height: calc(var(--spacing) * 6);
 
    --text-lg: calc(var(--spacing) * 4.5);
    --text-lg--line-height: calc(var(--spacing) * 7);
 
    --text-xl: calc(var(--spacing) * 5);
    --text-xl--line-height: calc(var(--spacing) * 7.5);
 
    --text-display-xs: calc(var(--spacing) * 6);
    --text-display-xs--line-height: calc(var(--spacing) * 8);
 
    --text-display-sm: calc(var(--spacing) * 7.5);
    --text-display-sm--line-height: calc(var(--spacing) * 9.5);
 
    --text-display-md: calc(var(--spacing) * 9);
    --text-display-md--line-height: calc(var(--spacing) * 11);
    --text-display-md--letter-spacing: -0.72px;
 
    --text-display-lg: calc(var(--spacing) * 12);
    --text-display-lg--line-height: calc(var(--spacing) * 15);
    --text-display-lg--letter-spacing: -0.96px;
 
    --text-display-xl: calc(var(--spacing) * 15);
    --text-display-xl--line-height: calc(var(--spacing) * 18);
    --text-display-xl--letter-spacing: -1.2px;
 
    --text-display-2xl: calc(var(--spacing) * 18);
    --text-display-2xl--line-height: calc(var(--spacing) * 22.5);
    --text-display-2xl--letter-spacing: -1.44px;
 
    /* MAX WIDTH */
    --max-width-container: 1280px;
 
    /* BREAKPOINTS */
    --breakpoint-xxs: 320px;
    /* This must match the breakpoint in Sonner: https://github.com/emilkowalski/sonner/blob/main/src/styles.css */
    --breakpoint-xs: 600px;
 
    /* RADIUS */
    --radius-none: 0px;
    --radius-xs: 0.125rem;
    --radius-sm: 0.25rem;
    --radius-DEFAULT: 0.25rem;
    --radius-md: 0.375rem;
    --radius-lg: 0.5rem;
    --radius-xl: 0.75rem;
    --radius-2xl: 1rem;
    --radius-3xl: 1.5rem;
    --radius-full: 9999px;
 
    /* SHADOW */
    --shadow-xs: 0px 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-sm: 0px 1px 3px rgba(0, 0, 0, 0.1), 0px 1px 2px -1px rgba(0, 0, 0, 0.1);
    --shadow-md: 0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.06);
    --shadow-lg: 0px 12px 16px -4px rgba(0, 0, 0, 0.08), 0px 4px 6px -2px rgba(0, 0, 0, 0.03), 0px 2px 2px -1px rgba(0, 0, 0, 0.04);
    --shadow-xl: 0px 20px 24px -4px rgba(0, 0, 0, 0.08), 0px 8px 8px -4px rgba(0, 0, 0, 0.03), 0px 3px 3px -1.5px rgba(0, 0, 0, 0.04);
    --shadow-2xl: 0px 24px 48px -12px rgba(0, 0, 0, 0.18), 0px 4px 4px -2px rgba(0, 0, 0, 0.04);
    --shadow-3xl: 0px 32px 64px -12px rgba(0, 0, 0, 0.14), 0px 5px 5px -2.5px rgba(0, 0, 0, 0.04);
 
    --shadow-skeuomorphic: 0px 0px 0px 1px rgba(0, 0, 0, 0.18) inset, 0px -2px 0px 0px rgba(0, 0, 0, 0.05) inset;
    --shadow-xs-skeuomorphic: var(--shadow-skeuomorphic), var(--shadow-xs);
 
    --shadow-modern-mockup-inner-lg: 0px 0px 3.765px 1.255px rgba(10, 13, 18, 0.08) inset, 0px 0px 2.51px 1.255px rgba(10, 13, 18, 0.03) inset;
    --shadow-modern-mockup-inner-md: 0px 0px 1.692px 0.564px rgba(10, 13, 18, 0.08) inset, 0px 0px 1.128px 0.564px rgba(10, 13, 18, 0.03) inset;
    --shadow-modern-mockup-inner-sm: 0px 0px 4.48px 1.493px rgba(10, 13, 18, 0.08) inset, 0px 0px 2.987px 1.493px rgba(10, 13, 18, 0.03) inset;
 
    --shadow-modern-mockup-outer-lg:
        0px 7.529px 10.039px -2.51px rgba(10, 13, 18, 0.08), 0px 2.51px 3.765px -1.255px rgba(10, 13, 18, 0.03),
        0px 1.255px 1.255px -0.627px rgba(10, 13, 18, 0.04);
    --shadow-modern-mockup-outer-md:
        0px 3.385px 4.513px -1.128px rgba(10, 13, 18, 0.08), 0px 1.128px 1.692px -0.564px rgba(10, 13, 18, 0.03),
        0px 0.564px 0.564px -0.282px rgba(10, 13, 18, 0.04);
 
    --drop-shadow-iphone-mockup: 20px 12px 18px rgba(16, 24, 40, 0.2);
 
    /* ANIMATIONS */
    --animate-marquee: marquee 60s linear infinite;
    --animate-caret-blink: caret-blink 1s infinite;
 
    @keyframes marquee {
        0% {
            transform: translateX(0);
        }
        100% {
            transform: translateX(-100%);
        }
    }
 
    @keyframes caret-blink {
        0%,
        50% {
            opacity: 1;
        }
        51%,
        100% {
            opacity: 0;
        }
    }
 
    /* BASE COLOR */
    --color-transparent: rgb(0 0 0 / 0);
 
    --color-white: rgb(255 255 255);
    --color-black: rgb(0 0 0);
 
    /* These will be inverted in dark mode. */
    --color-alpha-white: rgb(255 255 255);
    --color-alpha-black: rgb(0 0 0);
 
    --color-brand-50: rgb(249 245 255);
    --color-brand-100: rgb(244 235 255);
    --color-brand-200: rgb(233 215 254);
    --color-brand-300: rgb(214 187 251);
    --color-brand-400: rgb(182 146 246);
    --color-brand-500: rgb(158 119 237);
    --color-brand-600: rgb(127 86 217);
    --color-brand-700: rgb(105 65 198);
    --color-brand-800: rgb(83 56 158);
    --color-brand-900: rgb(66 48 125);
    --color-brand-950: rgb(44 28 95);
 
    /* LIGHT MODE VARIABLES */
 
    --color-alpha-white: rgb(255 255 255);
    --color-alpha-black: rgb(0 0 0);
 
    /* UTILITY COLORS */
    --color-utility-blue-50: var(--color-blue-50);
    --color-utility-blue-100: var(--color-blue-100);
    --color-utility-blue-200: var(--color-blue-200);
    --color-utility-blue-300: var(--color-blue-300);
    --color-utility-blue-400: var(--color-blue-400);
    --color-utility-blue-500: var(--color-blue-500);
    --color-utility-blue-600: var(--color-blue-600);
    --color-utility-blue-700: var(--color-blue-700);
 
    --color-utility-brand-50: var(--color-brand-50);
    --color-utility-brand-50_alt: var(--color-brand-50);
    --color-utility-brand-100: var(--color-brand-100);
    --color-utility-brand-100_alt: var(--color-brand-100);
    --color-utility-brand-200: var(--color-brand-200);
    --color-utility-brand-200_alt: var(--color-brand-200);
    --color-utility-brand-300: var(--color-brand-300);
    --color-utility-brand-300_alt: var(--color-brand-300);
    --color-utility-brand-400: var(--color-brand-400);
    --color-utility-brand-400_alt: var(--color-brand-400);
    --color-utility-brand-500: var(--color-brand-500);
    --color-utility-brand-500_alt: var(--color-brand-500);
    --color-utility-brand-600: var(--color-brand-600);
    --color-utility-brand-600_alt: var(--color-brand-600);
    --color-utility-brand-700: var(--color-brand-700);
    --color-utility-brand-700_alt: var(--color-brand-700);
    --color-utility-brand-800: var(--color-brand-800);
    --color-utility-brand-800_alt: var(--color-brand-800);
    --color-utility-brand-900: var(--color-brand-900);
    --color-utility-brand-900_alt: var(--color-brand-900);
 
    --color-utility-neutral-50: var(--color-neutral-50);
    --color-utility-neutral-100: var(--color-neutral-100);
    --color-utility-neutral-200: var(--color-neutral-200);
    --color-utility-neutral-300: var(--color-neutral-300);
    --color-utility-neutral-400: var(--color-neutral-400);
    --color-utility-neutral-500: var(--color-neutral-500);
    --color-utility-neutral-600: var(--color-neutral-600);
    --color-utility-neutral-700: var(--color-neutral-700);
    --color-utility-neutral-800: var(--color-neutral-800);
    --color-utility-neutral-900: var(--color-neutral-900);
 
    --color-utility-red-50: var(--color-red-50);
    --color-utility-red-100: var(--color-red-100);
    --color-utility-red-200: var(--color-red-200);
    --color-utility-red-300: var(--color-red-300);
    --color-utility-red-400: var(--color-red-400);
    --color-utility-red-500: var(--color-red-500);
    --color-utility-red-600: var(--color-red-600);
    --color-utility-red-700: var(--color-red-700);
 
    --color-utility-yellow-50: var(--color-yellow-50);
    --color-utility-yellow-100: var(--color-yellow-100);
    --color-utility-yellow-200: var(--color-yellow-200);
    --color-utility-yellow-300: var(--color-yellow-300);
    --color-utility-yellow-400: var(--color-yellow-400);
    --color-utility-yellow-500: var(--color-yellow-500);
    --color-utility-yellow-600: var(--color-yellow-600);
    --color-utility-yellow-700: var(--color-yellow-700);
 
    --color-utility-green-50: var(--color-green-50);
    --color-utility-green-100: var(--color-green-100);
    --color-utility-green-200: var(--color-green-200);
    --color-utility-green-300: var(--color-green-300);
    --color-utility-green-400: var(--color-green-400);
    --color-utility-green-500: var(--color-green-500);
    --color-utility-green-600: var(--color-green-600);
    --color-utility-green-700: var(--color-green-700);
 
    --color-utility-orange-50: var(--color-orange-50);
    --color-utility-orange-100: var(--color-orange-100);
    --color-utility-orange-200: var(--color-orange-200);
    --color-utility-orange-300: var(--color-orange-300);
    --color-utility-orange-400: var(--color-orange-400);
    --color-utility-orange-500: var(--color-orange-500);
    --color-utility-orange-600: var(--color-orange-600);
    --color-utility-orange-700: var(--color-orange-700);
 
    --color-utility-indigo-50: var(--color-indigo-50);
    --color-utility-indigo-100: var(--color-indigo-100);
    --color-utility-indigo-200: var(--color-indigo-200);
    --color-utility-indigo-300: var(--color-indigo-300);
    --color-utility-indigo-400: var(--color-indigo-400);
    --color-utility-indigo-500: var(--color-indigo-500);
    --color-utility-indigo-600: var(--color-indigo-600);
    --color-utility-indigo-700: var(--color-indigo-700);
 
    --color-utility-fuchsia-50: var(--color-fuchsia-50);
    --color-utility-fuchsia-100: var(--color-fuchsia-100);
    --color-utility-fuchsia-200: var(--color-fuchsia-200);
    --color-utility-fuchsia-300: var(--color-fuchsia-300);
    --color-utility-fuchsia-400: var(--color-fuchsia-400);
    --color-utility-fuchsia-500: var(--color-fuchsia-500);
    --color-utility-fuchsia-600: var(--color-fuchsia-600);
    --color-utility-fuchsia-700: var(--color-fuchsia-700);
 
    --color-utility-pink-50: var(--color-pink-50);
    --color-utility-pink-100: var(--color-pink-100);
    --color-utility-pink-200: var(--color-pink-200);
    --color-utility-pink-300: var(--color-pink-300);
    --color-utility-pink-400: var(--color-pink-400);
    --color-utility-pink-500: var(--color-pink-500);
    --color-utility-pink-600: var(--color-pink-600);
    --color-utility-pink-700: var(--color-pink-700);
 
    --color-utility-purple-50: var(--color-purple-50);
    --color-utility-purple-100: var(--color-purple-100);
    --color-utility-purple-200: var(--color-purple-200);
    --color-utility-purple-300: var(--color-purple-300);
    --color-utility-purple-400: var(--color-purple-400);
    --color-utility-purple-500: var(--color-purple-500);
    --color-utility-purple-600: var(--color-purple-600);
    --color-utility-purple-700: var(--color-purple-700);
 
    --color-utility-sky-50: var(--color-sky-50);
    --color-utility-sky-100: var(--color-sky-100);
    --color-utility-sky-200: var(--color-sky-200);
    --color-utility-sky-300: var(--color-sky-300);
    --color-utility-sky-400: var(--color-sky-400);
    --color-utility-sky-500: var(--color-sky-500);
    --color-utility-sky-600: var(--color-sky-600);
    --color-utility-sky-700: var(--color-sky-700);
 
    --color-utility-slate-50: var(--color-slate-50);
    --color-utility-slate-100: var(--color-slate-100);
    --color-utility-slate-200: var(--color-slate-200);
    --color-utility-slate-300: var(--color-slate-300);
    --color-utility-slate-400: var(--color-slate-400);
    --color-utility-slate-500: var(--color-slate-500);
    --color-utility-slate-600: var(--color-slate-600);
    --color-utility-slate-700: var(--color-slate-700);
 
    --color-utility-emerald-50: var(--color-emerald-50);
    --color-utility-emerald-100: var(--color-emerald-100);
    --color-utility-emerald-200: var(--color-emerald-200);
    --color-utility-emerald-300: var(--color-emerald-300);
    --color-utility-emerald-400: var(--color-emerald-400);
    --color-utility-emerald-500: var(--color-emerald-500);
    --color-utility-emerald-600: var(--color-emerald-600);
    --color-utility-emerald-700: var(--color-emerald-700);
 
    --color-utility-amber-50: var(--color-amber-50);
    --color-utility-amber-100: var(--color-amber-100);
    --color-utility-amber-200: var(--color-amber-200);
    --color-utility-amber-300: var(--color-amber-300);
    --color-utility-amber-400: var(--color-amber-400);
    --color-utility-amber-500: var(--color-amber-500);
    --color-utility-amber-600: var(--color-amber-600);
    --color-utility-amber-700: var(--color-amber-700);
 
    /* TEXT COLORS */
    --color-text-primary: var(--color-neutral-900);
    --color-text-tertiary: var(--color-neutral-600);
    --color-text-error-primary: var(--color-red-600);
    --color-text-warning-primary: var(--color-yellow-600);
    --color-text-success-primary: var(--color-green-600);
    --color-text-white: var(--color-white);
    --color-text-secondary: var(--color-neutral-700);
    --color-text-secondary_hover: var(--color-neutral-800);
    --color-text-tertiary_hover: var(--color-neutral-700);
    --color-text-brand-secondary: var(--color-brand-700);
    --color-text-placeholder: var(--color-neutral-500);
    --color-text-brand-tertiary: var(--color-brand-600);
    --color-text-editor-icon-fg: var(--color-neutral-400);
    --color-text-editor-icon-fg_active: var(--color-neutral-500);
    --color-text-quaternary: var(--color-neutral-500);
    --color-text-brand-primary: var(--color-brand-900);
    --color-text-primary_on-brand: var(--color-white);
    --color-text-secondary_on-brand: var(--color-brand-200);
    --color-text-tertiary_on-brand: var(--color-brand-200);
    --color-text-quaternary_on-brand: var(--color-brand-300);
    --color-text-brand-tertiary_alt: var(--color-brand-600);
    --color-text-error-primary_hover: var(--color-red-700);
    --color-text-brand-secondary_hover: var(--color-brand-800);
 
    /* BORDER COLORS */
    --color-border-primary: var(--color-neutral-300);
    --color-border-secondary: var(--color-neutral-200);
    --color-border-secondary_alt: rgb(0 0 0 / 0.1);
    --color-border-tertiary: var(--color-neutral-100);
    --color-border-error: var(--color-red-500);
    --color-border-error_subtle: var(--color-red-300);
    --color-border-brand: var(--color-brand-500);
    --color-border-brand_alt: var(--color-brand-600);
 
    /* FOREGROUND COLORS */
    --color-fg-secondary: var(--color-neutral-700);
    --color-fg-warning-primary: var(--color-yellow-600);
    --color-fg-success-primary: var(--color-green-600);
    --color-fg-white: var(--color-white);
    --color-fg-success-secondary: var(--color-green-500);
    --color-fg-secondary_hover: var(--color-neutral-800);
    --color-fg-primary: var(--color-neutral-900);
    --color-fg-brand-secondary: var(--color-brand-500);
    --color-fg-brand-primary: var(--color-brand-600);
    --color-fg-quaternary: var(--color-neutral-400);
    --color-fg-quaternary_hover: var(--color-neutral-500);
    --color-fg-error-primary: var(--color-red-600);
    --color-fg-warning-secondary: var(--color-yellow-500);
    --color-fg-error-secondary: var(--color-red-500);
    --color-fg-tertiary: var(--color-neutral-600);
    --color-fg-tertiary_hover: var(--color-neutral-700);
    --color-fg-brand-primary_alt: var(--color-fg-brand-primary);
    --color-fg-brand-secondary_alt: var(--color-fg-brand-secondary);
    --color-fg-brand-secondary_hover: var(--color-brand-600);
 
    /* BACKGROUND COLORS */
    --color-bg-primary: var(--color-white);
    --color-bg-tertiary: var(--color-neutral-100);
    --color-bg-brand-primary: var(--color-brand-50);
    --color-bg-error-secondary: var(--color-red-100);
    --color-bg-warning-primary: var(--color-yellow-50);
    --color-bg-warning-secondary: var(--color-yellow-100);
    --color-bg-success-primary: var(--color-green-50);
    --color-bg-success-secondary: var(--color-green-100);
    --color-bg-brand-solid: var(--color-brand-600);
    --color-bg-secondary-solid: var(--color-neutral-600);
    --color-bg-error-solid: var(--color-red-600);
    --color-bg-warning-solid: var(--color-yellow-600);
    --color-bg-success-solid: var(--color-green-600);
    --color-bg-secondary_hover: var(--color-neutral-100);
    --color-bg-primary_hover: var(--color-neutral-50);
    --color-bg-active: var(--color-neutral-50);
    --color-bg-brand-solid_hover: var(--color-brand-700);
    --color-bg-error-primary: var(--color-red-50);
    --color-bg-brand-secondary: var(--color-brand-100);
    --color-bg-secondary: var(--color-neutral-50);
    --color-bg-quaternary: var(--color-neutral-200);
    --color-bg-primary_alt: var(--color-white);
    --color-bg-brand-primary_alt: var(--color-brand-50);
    --color-bg-secondary_alt: var(--color-neutral-50);
    --color-bg-overlay: var(--color-neutral-950);
    --color-bg-brand-section: var(--color-brand-800);
    --color-bg-brand-section_subtle: var(--color-brand-700);
    --color-bg-primary-solid: var(--color-neutral-950);
    --color-bg-error-solid_hover: var(--color-red-700);
 
    /* COMPONENT COLORS */
    --color-app-store-badge-border: 166 166 166 1;
    --color-avatar-styles-bg-neutral: 224 224 224 1;
    --color-featured-icon-light-fg-brand: var(--color-brand-600);
    --color-featured-icon-light-fg-error: var(--color-red-600);
    --color-featured-icon-light-fg-gray: var(--color-neutral-500);
    --color-featured-icon-light-fg-success: var(--color-green-600);
    --color-featured-icon-light-fg-warning: var(--color-yellow-600);
    --color-focus-ring-error: var(--color-red-500);
    --color-focus-ring: var(--color-brand-500);
    --color-footer-button-fg: var(--color-brand-200);
    --color-footer-button-fg_hover: var(--color-white);
    --color-icon-fg-brand: var(--color-brand-600);
    --color-icon-fg-brand_on-brand: var(--color-brand-200);
    --color-screen-mockup-border: var(--color-neutral-900);
 
    --color-slider-handle-bg: var(--color-white);
    --color-slider-handle-border: var(--color-brand-600);
    --color-toggle-border: var(--color-neutral-300);
    --color-toggle-slim-border_pressed-hover: var(--color-bg-brand-solid_hover);
    --color-toggle-slim-border_pressed: var(--color-bg-brand-solid);
    --color-tooltip-supporting-text: var(--color-neutral-300);
 
    /* BACKGROUND PROPERTY COLORS */
    --background-color-primary: var(--color-bg-primary);
    --background-color-tertiary: var(--color-bg-tertiary);
    --background-color-brand-primary: var(--color-bg-brand-primary);
    --background-color-error-secondary: var(--color-bg-error-secondary);
    --background-color-warning-primary: var(--color-bg-warning-primary);
    --background-color-warning-secondary: var(--color-bg-warning-secondary);
    --background-color-success-primary: var(--color-bg-success-primary);
    --background-color-success-secondary: var(--color-bg-success-secondary);
    --background-color-brand-solid: var(--color-bg-brand-solid);
    --background-color-secondary-solid: var(--color-bg-secondary-solid);
    --background-color-error-solid: var(--color-bg-error-solid);
    --background-color-warning-solid: var(--color-bg-warning-solid);
    --background-color-success-solid: var(--color-bg-success-solid);
    --background-color-secondary_hover: var(--color-bg-secondary_hover);
    --background-color-primary_hover: var(--color-bg-primary_hover);
    --background-color-active: var(--color-bg-active);
    --background-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
    --background-color-error-primary: var(--color-bg-error-primary);
    --background-color-brand-secondary: var(--color-bg-brand-secondary);
    --background-color-secondary: var(--color-bg-secondary);
    --background-color-quaternary: var(--color-bg-quaternary);
    --background-color-primary_alt: var(--color-bg-primary_alt);
    --background-color-brand-primary_alt: var(--color-bg-brand-primary_alt);
    --background-color-secondary_alt: var(--color-bg-secondary_alt);
    --background-color-overlay: var(--color-bg-overlay);
    --background-color-brand-section: var(--color-bg-brand-section);
    --background-color-brand-section_subtle: var(--color-bg-brand-section_subtle);
    --background-color-primary-solid: var(--color-bg-primary-solid);
    --background-color-error-solid_hover: var(--color-bg-error-solid_hover);
    --background-color-border-brand: var(--color-border-brand);
    --background-color-border-brand_alt: var(--color-border-brand_alt);
 
    /* TEXT PROPERTY COLORS */
    --color-text-white: var(--color-white);
    --text-color-primary: var(--color-text-primary);
    --text-color-secondary: var(--color-text-secondary);
    --text-color-secondary_hover: var(--color-text-secondary_hover);
    --text-color-tertiary: var(--color-text-tertiary);
    --text-color-tertiary_hover: var(--color-text-tertiary_hover);
    --text-color-error-primary: var(--color-text-error-primary);
    --text-color-warning-primary: var(--color-text-warning-primary);
    --text-color-success-primary: var(--color-text-success-primary);
    --text-color-brand-secondary: var(--color-text-brand-secondary);
    --text-color-placeholder: var(--color-text-placeholder);
    --text-color-brand-tertiary: var(--color-text-brand-tertiary);
    --text-color-editor-icon-fg: var(--color-text-editor-icon-fg);
    --text-color-editor-icon-fg_active: var(--color-text-editor-icon-fg_active);
    --text-color-quaternary: var(--color-text-quaternary);
    --text-color-brand-primary: var(--color-text-brand-primary);
    --text-color-primary_on-brand: var(--color-text-primary_on-brand);
    --text-color-secondary_on-brand: var(--color-text-secondary_on-brand);
    --text-color-tertiary_on-brand: var(--color-text-tertiary_on-brand);
    --text-color-quaternary_on-brand: var(--color-text-quaternary_on-brand);
    --text-color-brand-tertiary_alt: var(--color-text-brand-tertiary_alt);
    --text-color-error-primary_hover: var(--color-text-error-primary_hover);
    --text-color-brand-secondary_hover: var(--color-text-brand-secondary_hover);
    --text-color-tooltip-supporting-text: var(--color-tooltip-supporting-text);
 
    /* BORDER PROPERTY COLORS */
    --border-color-primary: var(--color-border-primary);
    --border-color-secondary: var(--color-border-secondary);
    --border-color-secondary_alt: var(--color-border-secondary_alt);
    --border-color-tertiary: var(--color-border-tertiary);
    --border-color-error: var(--color-border-error);
    --border-color-error_subtle: var(--color-border-error_subtle);
    --border-color-brand: var(--color-border-brand);
    --border-color-brand_alt: var(--color-border-brand_alt);
    --border-color-brand-solid: var(--color-bg-brand-solid);
    --border-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
 
    /* RING PROPERTY COLORS */
    --ring-color-primary: var(--color-border-primary);
    --ring-color-secondary: var(--color-border-secondary);
    --ring-color-secondary_alt: var(--color-border-secondary_alt);
    --ring-color-tertiary: var(--color-border-tertiary);
    --ring-color-error: var(--color-border-error);
    --ring-color-error_subtle: var(--color-border-error_subtle);
    --ring-color-brand: var(--color-border-brand);
    --ring-color-brand_alt: var(--color-border-brand_alt);
    --ring-color-brand-solid: var(--color-bg-brand-solid);
    --ring-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
 
    /* OUTLINE PROPERTY COLORS */
    --outline-color-primary: var(--color-border-primary);
    --outline-color-secondary: var(--color-border-secondary);
    --outline-color-secondary_alt: var(--color-border-secondary_alt);
    --outline-color-tertiary: var(--color-border-tertiary);
    --outline-color-error: var(--color-border-error);
    --outline-color-error_subtle: var(--color-border-error_subtle);
    --outline-color-brand: var(--color-border-brand);
    --outline-color-brand_alt: var(--color-border-brand_alt);
    --outline-color-brand-solid: var(--color-bg-brand-solid);
    --outline-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
}
 
@layer base {
    /* DARK MODE VARIABLES */
 
    .dark-mode {
        --color-alpha-white: rgb(12 14 18);
        --color-alpha-black: rgb(255 255 255);
 
        /* UTILITY COLORS */
 
        --color-utility-blue-50: var(--color-blue-950);
        --color-utility-blue-100: var(--color-blue-900);
        --color-utility-blue-200: var(--color-blue-800);
        --color-utility-blue-300: var(--color-blue-700);
        --color-utility-blue-400: var(--color-blue-600);
        --color-utility-blue-500: var(--color-blue-500);
        --color-utility-blue-600: var(--color-blue-400);
        --color-utility-blue-700: var(--color-blue-300);
 
        --color-utility-brand-50: var(--color-brand-950);
        --color-utility-brand-50_alt: var(--color-utility-neutral-50);
        --color-utility-brand-100: var(--color-brand-900);
        --color-utility-brand-100_alt: var(--color-utility-neutral-100);
        --color-utility-brand-200: var(--color-brand-800);
        --color-utility-brand-200_alt: var(--color-utility-neutral-200);
        --color-utility-brand-300: var(--color-brand-700);
        --color-utility-brand-300_alt: var(--color-utility-neutral-300);
        --color-utility-brand-400: var(--color-brand-600);
        --color-utility-brand-400_alt: var(--color-utility-neutral-400);
        --color-utility-brand-500: var(--color-brand-500);
        --color-utility-brand-500_alt: var(--color-utility-neutral-500);
        --color-utility-brand-600: var(--color-brand-400);
        --color-utility-brand-600_alt: var(--color-utility-neutral-600);
        --color-utility-brand-700: var(--color-brand-300);
        --color-utility-brand-700_alt: var(--color-utility-neutral-700);
        --color-utility-brand-800: var(--color-brand-200);
        --color-utility-brand-800_alt: var(--color-utility-neutral-800);
        --color-utility-brand-900: var(--color-brand-100);
        --color-utility-brand-900_alt: var(--color-utility-neutral-900);
 
        --color-utility-neutral-50: var(--color-neutral-900);
        --color-utility-neutral-100: var(--color-neutral-800);
        --color-utility-neutral-200: var(--color-neutral-700);
        --color-utility-neutral-300: var(--color-neutral-700);
        --color-utility-neutral-400: var(--color-neutral-600);
        --color-utility-neutral-500: var(--color-neutral-500);
        --color-utility-neutral-600: var(--color-neutral-400);
        --color-utility-neutral-700: var(--color-neutral-300);
        --color-utility-neutral-800: var(--color-neutral-200);
        --color-utility-neutral-900: var(--color-neutral-100);
 
        --color-utility-red-50: var(--color-red-950);
        --color-utility-red-100: var(--color-red-900);
        --color-utility-red-200: var(--color-red-800);
        --color-utility-red-300: var(--color-red-700);
        --color-utility-red-400: var(--color-red-600);
        --color-utility-red-500: var(--color-red-500);
        --color-utility-red-600: var(--color-red-400);
        --color-utility-red-700: var(--color-red-300);
 
        --color-utility-yellow-50: var(--color-yellow-950);
        --color-utility-yellow-100: var(--color-yellow-900);
        --color-utility-yellow-200: var(--color-yellow-800);
        --color-utility-yellow-300: var(--color-yellow-700);
        --color-utility-yellow-400: var(--color-yellow-600);
        --color-utility-yellow-500: var(--color-yellow-500);
        --color-utility-yellow-600: var(--color-yellow-400);
        --color-utility-yellow-700: var(--color-yellow-300);
 
        --color-utility-green-50: var(--color-green-950);
        --color-utility-green-100: var(--color-green-900);
        --color-utility-green-200: var(--color-green-800);
        --color-utility-green-300: var(--color-green-700);
        --color-utility-green-400: var(--color-green-600);
        --color-utility-green-500: var(--color-green-500);
        --color-utility-green-600: var(--color-green-400);
        --color-utility-green-700: var(--color-green-300);
 
        --color-utility-orange-50: var(--color-orange-950);
        --color-utility-orange-100: var(--color-orange-900);
        --color-utility-orange-200: var(--color-orange-800);
        --color-utility-orange-300: var(--color-orange-700);
        --color-utility-orange-400: var(--color-orange-600);
        --color-utility-orange-500: var(--color-orange-500);
        --color-utility-orange-600: var(--color-orange-400);
        --color-utility-orange-700: var(--color-orange-300);
 
        --color-utility-indigo-50: var(--color-indigo-950);
        --color-utility-indigo-100: var(--color-indigo-900);
        --color-utility-indigo-200: var(--color-indigo-800);
        --color-utility-indigo-300: var(--color-indigo-700);
        --color-utility-indigo-400: var(--color-indigo-600);
        --color-utility-indigo-500: var(--color-indigo-500);
        --color-utility-indigo-600: var(--color-indigo-400);
        --color-utility-indigo-700: var(--color-indigo-300);
 
        --color-utility-fuchsia-50: var(--color-fuchsia-950);
        --color-utility-fuchsia-100: var(--color-fuchsia-900);
        --color-utility-fuchsia-200: var(--color-fuchsia-800);
        --color-utility-fuchsia-300: var(--color-fuchsia-700);
        --color-utility-fuchsia-400: var(--color-fuchsia-600);
        --color-utility-fuchsia-500: var(--color-fuchsia-500);
        --color-utility-fuchsia-600: var(--color-fuchsia-400);
        --color-utility-fuchsia-700: var(--color-fuchsia-300);
 
        --color-utility-pink-50: var(--color-pink-950);
        --color-utility-pink-100: var(--color-pink-900);
        --color-utility-pink-200: var(--color-pink-800);
        --color-utility-pink-300: var(--color-pink-700);
        --color-utility-pink-400: var(--color-pink-600);
        --color-utility-pink-500: var(--color-pink-500);
        --color-utility-pink-600: var(--color-pink-400);
        --color-utility-pink-700: var(--color-pink-300);
 
        --color-utility-purple-50: var(--color-purple-950);
        --color-utility-purple-100: var(--color-purple-900);
        --color-utility-purple-200: var(--color-purple-800);
        --color-utility-purple-300: var(--color-purple-700);
        --color-utility-purple-400: var(--color-purple-600);
        --color-utility-purple-500: var(--color-purple-500);
        --color-utility-purple-600: var(--color-purple-400);
        --color-utility-purple-700: var(--color-purple-300);
 
        --color-utility-sky-50: var(--color-sky-950);
        --color-utility-sky-100: var(--color-sky-900);
        --color-utility-sky-200: var(--color-sky-800);
        --color-utility-sky-300: var(--color-sky-700);
        --color-utility-sky-400: var(--color-sky-600);
        --color-utility-sky-500: var(--color-sky-500);
        --color-utility-sky-600: var(--color-sky-400);
        --color-utility-sky-700: var(--color-sky-300);
 
        --color-utility-slate-50: var(--color-slate-950);
        --color-utility-slate-100: var(--color-slate-900);
        --color-utility-slate-200: var(--color-slate-800);
        --color-utility-slate-300: var(--color-slate-700);
        --color-utility-slate-400: var(--color-slate-600);
        --color-utility-slate-500: var(--color-slate-500);
        --color-utility-slate-600: var(--color-slate-400);
        --color-utility-slate-700: var(--color-slate-300);
 
        --color-utility-emerald-50: var(--color-emerald-950);
        --color-utility-emerald-100: var(--color-emerald-900);
        --color-utility-emerald-200: var(--color-emerald-800);
        --color-utility-emerald-300: var(--color-emerald-700);
        --color-utility-emerald-400: var(--color-emerald-600);
        --color-utility-emerald-500: var(--color-emerald-500);
        --color-utility-emerald-600: var(--color-emerald-400);
        --color-utility-emerald-700: var(--color-emerald-300);
 
        --color-utility-amber-50: var(--color-amber-950);
        --color-utility-amber-100: var(--color-amber-900);
        --color-utility-amber-200: var(--color-amber-800);
        --color-utility-amber-300: var(--color-amber-700);
        --color-utility-amber-400: var(--color-amber-600);
        --color-utility-amber-500: var(--color-amber-500);
        --color-utility-amber-600: var(--color-amber-400);
        --color-utility-amber-700: var(--color-amber-300);
 
        --color-text-primary: var(--color-neutral-50);
        --color-text-tertiary: var(--color-neutral-400);
        --color-text-error-primary: var(--color-red-400);
        --color-text-warning-primary: var(--color-yellow-400);
        --color-text-success-primary: var(--color-green-400);
        --color-text-white: var(--color-white);
        --color-text-secondary: var(--color-neutral-300);
        --color-text-secondary_hover: var(--color-neutral-200);
        --color-text-tertiary_hover: var(--color-neutral-300);
        --color-text-brand-secondary: var(--color-neutral-300);
        --color-text-placeholder: var(--color-neutral-500);
        --color-text-brand-tertiary: var(--color-neutral-400);
        --color-text-editor-icon-fg: var(--color-neutral-400);
        --color-text-editor-icon-fg_active: var(--color-white);
        --color-text-quaternary: var(--color-neutral-400);
        --color-text-brand-primary: var(--color-neutral-50);
        --color-text-primary_on-brand: var(--color-neutral-50);
        --color-text-secondary_on-brand: var(--color-neutral-300);
        --color-text-tertiary_on-brand: var(--color-neutral-400);
        --color-text-quaternary_on-brand: var(--color-neutral-400);
        --color-text-brand-tertiary_alt: var(--color-neutral-50);
        --color-text-error-primary_hover: var(--color-red-300);
        --color-text-brand-secondary_hover: var(--color-neutral-200);
 
        --color-border-secondary: var(--color-neutral-800);
        --color-border-error_subtle: var(--color-red-500);
        --color-border-primary: var(--color-neutral-700);
        --color-border-brand: var(--color-brand-400);
        --color-border-error: var(--color-red-400);
        --color-border-tertiary: var(--color-neutral-800);
        --color-border-brand_alt: var(--color-neutral-700);
        --color-border-secondary_alt: var(--color-neutral-800);
 
        --color-fg-secondary: var(--color-neutral-300);
        --color-fg-warning-primary: var(--color-yellow-500);
        --color-fg-success-primary: var(--color-green-500);
        --color-fg-white: var(--color-white);
        --color-fg-success-secondary: var(--color-green-400);
        --color-fg-secondary_hover: var(--color-neutral-200);
        --color-fg-primary: var(--color-white);
        --color-fg-brand-secondary: var(--color-brand-500);
        --color-fg-brand-primary: var(--color-brand-500);
        --color-fg-quaternary: var(--color-neutral-600);
        --color-fg-quaternary_hover: var(--color-neutral-500);
        --color-fg-error-primary: var(--color-red-500);
        --color-fg-warning-secondary: var(--color-yellow-400);
        --color-fg-error-secondary: var(--color-red-400);
        --color-fg-tertiary: var(--color-neutral-400);
        --color-fg-tertiary_hover: var(--color-neutral-300);
        --color-fg-brand-primary_alt: var(--color-neutral-300);
        --color-fg-brand-secondary_alt: var(--color-neutral-600);
        --color-fg-brand-secondary_hover: var(--color-neutral-500);
 
        --color-bg-primary: var(--color-neutral-950);
        --color-bg-tertiary: var(--color-neutral-800);
        --color-bg-brand-primary: var(--color-brand-500);
        --color-bg-error-secondary: var(--color-red-600);
        --color-bg-warning-primary: var(--color-yellow-950);
        --color-bg-warning-secondary: var(--color-yellow-600);
        --color-bg-success-primary: var(--color-green-950);
        --color-bg-success-secondary: var(--color-green-600);
        --color-bg-brand-solid: var(--color-brand-600);
        --color-bg-secondary-solid: var(--color-neutral-600);
        --color-bg-error-solid: var(--color-red-600);
        --color-bg-warning-solid: var(--color-yellow-600);
        --color-bg-success-solid: var(--color-green-600);
        --color-bg-secondary_hover: var(--color-neutral-800);
        --color-bg-primary_hover: var(--color-neutral-900);
        --color-bg-active: var(--color-neutral-800);
        --color-bg-brand-solid_hover: var(--color-brand-500);
        --color-bg-error-primary: var(--color-red-950);
        --color-bg-brand-secondary: var(--color-brand-600);
        --color-bg-secondary: var(--color-neutral-900);
        --color-bg-quaternary: var(--color-neutral-700);
        --color-bg-primary_alt: var(--color-bg-secondary);
        --color-bg-brand-primary_alt: var(--color-bg-secondary);
        --color-bg-secondary_alt: var(--color-bg-primary);
        --color-bg-overlay: var(--color-neutral-800);
        --color-bg-brand-section: var(--color-bg-secondary);
        --color-bg-brand-section_subtle: var(--color-bg-primary);
        --color-bg-primary-solid: var(--color-bg-secondary);
        --color-bg-error-solid_hover: var(--color-red-500);
 
        --color-app-store-badge-border: var(--color-white);
        --color-avatar-styles-bg-neutral: 224 224 224 1;
        --color-featured-icon-light-fg-brand: var(--color-brand-200);
        --color-featured-icon-light-fg-error: var(--color-red-200);
        --color-featured-icon-light-fg-gray: var(--color-neutral-200);
        --color-featured-icon-light-fg-success: var(--color-green-200);
        --color-featured-icon-light-fg-warning: var(--color-yellow-200);
        --color-focus-ring-error: var(--color-red-500);
        --color-focus-ring: var(--color-brand-500);
        --color-footer-button-fg: var(--color-neutral-300);
        --color-footer-button-fg_hover: var(--color-neutral-100);
        --color-icon-fg-brand: var(--color-neutral-400);
        --color-icon-fg-brand_on-brand: var(--color-neutral-400);
        --color-screen-mockup-border: var(--color-neutral-700);
        --color-slider-handle-bg: var(--color-fg-brand-primary);
        --color-slider-handle-border: var(--color-bg-primary);
        --color-toggle-border: var(--color-transparent);
        --color-toggle-slim-border_pressed-hover: var(--color-transparent);
        --color-toggle-slim-border_pressed: var(--color-transparent);
        --color-tooltip-supporting-text: var(--color-neutral-300);
 
        /* BACKGROUND PROPERTY COLORS */
        --background-color-primary: var(--color-bg-primary);
        --background-color-tertiary: var(--color-bg-tertiary);
        --background-color-brand-primary: var(--color-bg-brand-primary);
        --background-color-error-secondary: var(--color-bg-error-secondary);
        --background-color-warning-primary: var(--color-bg-warning-primary);
        --background-color-warning-secondary: var(--color-bg-warning-secondary);
        --background-color-success-primary: var(--color-bg-success-primary);
        --background-color-success-secondary: var(--color-bg-success-secondary);
        --background-color-brand-solid: var(--color-bg-brand-solid);
        --background-color-secondary-solid: var(--color-bg-secondary-solid);
        --background-color-error-solid: var(--color-bg-error-solid);
        --background-color-warning-solid: var(--color-bg-warning-solid);
        --background-color-success-solid: var(--color-bg-success-solid);
        --background-color-secondary_hover: var(--color-bg-secondary_hover);
        --background-color-primary_hover: var(--color-bg-primary_hover);
        --background-color-active: var(--color-bg-active);
        --background-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
        --background-color-error-primary: var(--color-bg-error-primary);
        --background-color-brand-secondary: var(--color-bg-brand-secondary);
        --background-color-secondary: var(--color-bg-secondary);
        --background-color-quaternary: var(--color-bg-quaternary);
        --background-color-primary_alt: var(--color-bg-primary_alt);
        --background-color-brand-primary_alt: var(--color-bg-brand-primary_alt);
        --background-color-secondary_alt: var(--color-bg-secondary_alt);
        --background-color-overlay: var(--color-bg-overlay);
        --background-color-brand-section: var(--color-bg-brand-section);
        --background-color-brand-section_subtle: var(--color-bg-brand-section_subtle);
        --background-color-primary-solid: var(--color-bg-primary-solid);
        --background-color-error-solid_hover: var(--color-bg-error-solid_hover);
 
        --background-color-border-brand: var(--color-border-brand);
        --background-color-border-tertiary: var(--color-border-tertiary);
        --background-color-border-brand_alt: var(--color-border-brand_alt);
 
        /* TEXT PROPERTY COLORS */
        --text-color-primary: var(--color-text-primary);
        --text-color-tertiary: var(--color-text-tertiary);
        --text-color-error-primary: var(--color-text-error-primary);
        --text-color-warning-primary: var(--color-text-warning-primary);
        --text-color-success-primary: var(--color-text-success-primary);
        --text-color-white: var(--color-text-white);
        --text-color-secondary: var(--color-text-secondary);
        --text-color-secondary_hover: var(--color-text-secondary_hover);
        --text-color-tertiary_hover: var(--color-text-tertiary_hover);
        --text-color-brand-secondary: var(--color-text-brand-secondary);
        --text-color-placeholder: var(--color-text-placeholder);
        --text-color-brand-tertiary: var(--color-text-brand-tertiary);
        --text-color-editor-icon-fg: var(--color-text-editor-icon-fg);
        --text-color-editor-icon-fg_active: var(--color-text-editor-icon-fg_active);
        --text-color-quaternary: var(--color-text-quaternary);
        --text-color-brand-primary: var(--color-text-brand-primary);
        --text-color-primary_on-brand: var(--color-text-primary_on-brand);
        --text-color-secondary_on-brand: var(--color-text-secondary_on-brand);
        --text-color-tertiary_on-brand: var(--color-text-tertiary_on-brand);
        --text-color-quaternary_on-brand: var(--color-text-quaternary_on-brand);
        --text-color-brand-tertiary_alt: var(--color-text-brand-tertiary_alt);
        --text-color-error-primary_hover: var(--color-text-error-primary_hover);
        --text-color-brand-secondary_hover: var(--color-text-brand-secondary_hover);
        --text-color-tooltip-supporting-text: var(--color-tooltip-supporting-text);
 
        /* BORDER PROPERTY COLORS */
        --border-color-primary: var(--color-border-primary);
        --border-color-secondary: var(--color-border-secondary);
        --border-color-secondary_alt: var(--color-border-secondary_alt);
        --border-color-tertiary: var(--color-border-tertiary);
        --border-color-error: var(--color-border-error);
        --border-color-error_subtle: var(--color-border-error_subtle);
        --border-color-brand: var(--color-border-brand);
        --border-color-brand_alt: var(--color-border-brand_alt);
        --border-color-brand-solid: var(--color-bg-brand-solid);
        --border-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
 
        /* RING PROPERTY COLORS */
        --ring-color-primary: var(--color-border-primary);
        --ring-color-secondary: var(--color-border-secondary);
        --ring-color-secondary_alt: var(--color-border-secondary_alt);
        --ring-color-tertiary: var(--color-border-tertiary);
        --ring-color-error: var(--color-border-error);
        --ring-color-error_subtle: var(--color-border-error_subtle);
        --ring-color-brand: var(--color-border-brand);
        --ring-color-brand-solid: var(--color-bg-brand-solid);
        --ring-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
        --ring-color-brand_alt: var(--color-border-brand_alt);
 
        /* OUTLINE PROPERTY COLORS */
        --outline-color-primary: var(--color-border-primary);
        --outline-color-secondary: var(--color-border-secondary);
        --outline-color-secondary_alt: var(--color-border-secondary_alt);
        --outline-color-tertiary: var(--color-border-tertiary);
        --outline-color-error: var(--color-border-error);
        --outline-color-error_subtle: var(--color-border-error_subtle);
        --outline-color-brand: var(--color-border-brand);
        --outline-color-brand-solid: var(--color-bg-brand-solid);
        --outline-color-brand-solid_hover: var(--color-bg-brand-solid_hover);
        --outline-color-brand_alt: var(--color-border-brand_alt);
    }
}

Extend Tailwind CSS config

Now, in your globals.css file, import the theme.css and necessary plugins:

@import "tailwindcss";
@import "./theme.css";
 
@plugin "tailwindcss-animate";
@plugin "tailwindcss-react-aria-components";
 
@custom-variant dark (&:where(.dark-mode, .dark-mode *));
@custom-variant label (& [data-label]);
@custom-variant focus-input-within (&:has(input:focus));
 
@utility scrollbar-hide {
    /* For Webkit-based browsers (Chrome, Safari and Opera) */
    &::-webkit-scrollbar {
        display: none;
        -webkit-appearance: none;
    }
 
    /* For IE, Edge and Firefox */
    -ms-overflow-style: none; /* IE and Edge */
    scrollbar-width: none; /* Firefox */
}
 
@utility transition-inherit-all {
    transition-property: inherit;
    transition-duration: inherit;
    transition-timing-function: inherit;
}
 
html,
body {
    font-family: var(--font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-variant-ligatures: contextual;
    font-variant-ligatures: contextual;
    -webkit-font-kerning: normal;
    font-kerning: normal;
}
 
/* Hide the default expand arrow on Safari.  */
details summary::-webkit-details-marker {
    display: none;
}
 
/* Hide default arrows from number inputs. */
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
/* Firefox */
input[type="number"] {
    -moz-appearance: textfield;
}
 
/* Hide the default clear button (X) from search inputs. */
input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
}
 
/* Hide the default outline on chart elements. */
.recharts-surface,
.recharts-surface g,
.recharts-surface path {
    outline: none;
}

Add utility functions

In order to make the development experience slightly better we have added a few utility functions which we'll use throughout our project. Create these files under utils and hooks directories.

import { extendTailwindMerge } from "tailwind-merge";
 
const twMerge = extendTailwindMerge({
    extend: {
        theme: {
            text: ["display-xs", "display-sm", "display-md", "display-lg", "display-xl", "display-2xl"],
        },
    },
});
 
/**
 * This function is a wrapper around the twMerge function.
 * It is used to merge the classes inside style objects.
 */
export const cx = twMerge;
 
/**
 * This function does nothing besides helping us to be able to
 * sort the classes inside style objects which is not supported
 * by the Tailwind IntelliSense by default.
 */
export function sortCx<T extends Record<string, string | number | Record<string, string | number | Record<string, string | number>>>>(classes: T): T {
    return classes;
}

Add a route provider

For client-side routing integration with React Aria components, create a RouteProvider component in providers/route-provider.tsx or in your desired location:

"use client";
 
import type { PropsWithChildren } from "react";
import { useRouter } from "next/navigation";
import { RouterProvider } from "react-aria-components";
 
declare module "react-aria-components" {
    interface RouterConfig {
        routerOptions: NonNullable<Parameters<ReturnType<typeof useRouter>["push"]>[1]>;
    }
}
 
export const RouteProvider = ({ children }: PropsWithChildren) => {
    const router = useRouter();
 
    return <RouterProvider navigate={router.push}>{children}</RouterProvider>;
};

Add a theme provider

For dark mode support, use the next-themes package in providers/theme-provider.tsx or in your desired location:

"use client";
 
import { ThemeProvider as NextThemeProvider } from "next-themes";
import { type PropsWithChildren } from "react";
 
export function ThemeProvider({ children }: PropsWithChildren) {
    return (
        <NextThemeProvider disableTransitionOnChange attribute="class" value={{ light: "light-mode", dark: "dark-mode" }}>
            {children}
        </NextThemeProvider>
    );
}

Update the root layout

Update the root layout in app/layout.tsx to include the providers, the Inter font and the global styles:

import type { Metadata, Viewport } from "next";
import { Inter } from "next/font/google";
import { RouteProvider } from "@/providers/route-provider";
import { ThemeProvider } from "@/providers/theme-provider";
import "@/styles/globals.css";
 
const inter = Inter({
    subsets: ["latin"],
    display: "swap",
    variable: "--font-inter",
});
 
export const metadata: Metadata = {
    title: "Your App Name",
    description: "Your app description",
};
 
export const viewport: Viewport = {
    colorScheme: "light",
};
 
export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <html lang="en" className={`${inter.variable} scroll-smooth`}>
            <body className="bg-primary antialiased">
                <RouteProvider>
                    <ThemeProvider>
                        {children}
                    </ThemeProvider>
                </RouteProvider>
            </body>
        </html>
    );
}

Ready to go!

Great! You're all set to start using Untitled UI components.

If something is missing, you can copy/paste what you need into your project directly from individual components pages.

Need help? Check our GitHub repository for examples, or open an issue if you run into any problems. Our community is here to help!

App router vs pages router

Untitled UI supports both Next.js routing architectures. Here's how to set up each:

App router

The setup shown above is for the App Router. If you're using the App Router, make sure your client-side components that use interactivity have the "use client" directive.

Pages router

If you're using the Pages Router, create or modify your pages/_app.tsx file to include the providers, the Inter font and the global styles:

import type { AppProps } from "next/app";
import { type NextRouter } from "next/router";
import { Inter } from "next/font/google";
import { RouteProvider } from "@/providers/route-provider";
import { ThemeProvider } from "@/providers/theme-provider";
import "@/styles/globals.css";
 
const inter = Inter({
    subsets: ["latin"],
    display: "swap",
    variable: "--font-inter",
});
 
export default function MyApp({ Component, pageProps }: AppProps) {
    return (
        <div className={inter.variable}>
            <RouteProvider>
                <ThemeProvider>
                    <Component {...pageProps} />
                </ThemeProvider>
            </RouteProvider>
        </div>
    );
}

Using Untitled UI components

After setting up the providers, you can use Untitled UI components throughout your application:

"use client";
 
import { Button } from "@/components/base/buttons/button";
import { Input } from "@/components/base/input/input";
 
export default function Home() {
    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
 
        const formData = new FormData(e.target as HTMLFormElement);
        const name = formData.get("name") as string;
        
        console.log(name);
    };
 
    return (
        <main className="container mx-auto p-4">
            <h1 className="text-2xl font-bold">Welcome to Untitled UI + Next.js</h1>
            <form onSubmit={handleSubmit} className="mt-4">
                <Input label="Name" name="name" placeholder="Enter your name" />
                <Button type="submit" className="mt-2">Submit</Button>
            </form>
        </main>
    );
}

Dark mode

Untitled UI supports dark mode out of the box. The implementation uses CSS variables to provide a seamless experience.

Theme toggle

Create a toggle to switch between light and dark mode:

"use client";
 
import { useTheme } from "next-themes";
import { Button } from "@/components/base/buttons/button";
import { Moon01, Sun } from "@untitledui/icons";
 
export function ThemeToggle() {
    const { theme, setTheme } = useTheme();
 
    return (
        <Button
            aria-label="Toggle theme"
            color="tertiary"
            size="sm"
            iconLeading={theme === "light" ? Moon01 : Sun}
            onClick={() => setTheme(theme === "light" ? "dark" : "light")}
        />
    );
}

FAQs

Please refer to our frequently asked questions page for more.

Run npx untitledui@latest init untitled-ui --nextjs to create a new project with everything set up, or follow the manual installation: install the packages, add theme.css and globals.css, add the utility files, and wrap your root layout in the route and theme providers.

Yes. For the App Router, add the providers to app/layout.tsx; for the Pages Router, add them to pages/_app.tsx. In both cases the RouteProvider passes Next.js's router.push to React Aria's RouterProvider, so links inside components such as buttons with an href navigate on the client.

Yes. The component files already start with the "use client" directive, so you can import them directly into a server component. Add "use client" to your own file only when it needs client features itself, such as state or event handlers like onClick.

Install next-themes and wrap your app in the ThemeProvider from the installation steps. It uses attribute="class" and maps the themes to the light-mode and dark-mode classes, so you can switch themes with setTheme from useTheme, as in the theme toggle example.

No. With Tailwind CSS v4.3, Tailwind and its plugins are imported directly in globals.css (@import "tailwindcss", @plugin "tailwindcss-animate" and so on), and the design tokens live in theme.css. Next.js compiles it through the @tailwindcss/postcss plugin.

Load Inter with next/font/google, set variable: "--font-inter", and add inter.variable as a class on your root element. theme.css uses var(--font-inter, "Inter") for the body and display fonts, so the components pick it up automatically.