Manual
Install and configure Glass UI manually to your project.
Installation
Install core dependencies
Glass UI components rely on a few standard utilities to merge Tailwind classes and render icons. Install them in your project:
npm install clsx tailwind-merge lucide-reactInstall Tailwind CSS
Glass UI requires Tailwind CSS v4 for its styling and CSS-first theming. If you haven’t set it up yet, please follow the official Tailwind CSS installation guide for your specific framework.
Configure Path Aliases
Ensure your project has path aliases configured. Update your tsconfig.json (or tsconfig.app.json if using Vite) to include the @/* alias:
{ "compilerOptions": { "paths": { "@/*": ["./src/*"] }, },}{ "compilerOptions": { "paths": { "@/*": ["./src/*"] }, },}If your project already uses a different prefix (like ~/*), you can use that instead, but remember to update the imports in the components you copy later.
Add the utility function
Create a src/lib/utils.ts file. This helper function is used by all Glass UI components to conditionally merge Tailwind classes without style conflicts:
import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}Configure Global Styles
Add the core glassmorphism variables to your main CSS file (e.g., src/index.css or app/globals.css):
@import "tailwindcss";
@layer base { :root { --foreground: #18181b; --muted-foreground: #3f3f46; --glass-bg: rgba(255, 255, 255, 0.35); --glass-border: rgba(255, 255, 255, 0.6); --glass-shadow: var(--glass-shadow-sm); --glass-blur: 6px; --glass-shadow-sm: 0 2px 8px 0 rgba(0, 0, 0, 0.06); --glass-shadow-md: 0 4px 30px 0 rgba(0, 0, 0, 0.1); --glass-shadow-lg: 0 8px 40px 0 rgba(0, 0, 0, 0.2); --glass-radius-sm: 0.375rem; --glass-radius-md: 0.75rem; --glass-radius-lg: 1rem; --glass-radius-xl: 1.5rem; --glass-bg-strong: rgba(255, 255, 255, 0.5); --glass-border-strong: rgba(255, 255, 255, 0.8); --glass-blur-strong: 10px; --glass-bg-soft: rgba(255, 255, 255, 0.2); --glass-border-soft: rgba(255, 255, 255, 0.4); --glass-blur-soft: 2px; }
.dark { --foreground: #fafafa; --muted-foreground: #d4d4d8; --glass-bg: rgba(255, 255, 255, 0.08); --glass-border: rgba(255, 255, 255, 0.1); --glass-shadow: var(--glass-shadow-sm); --glass-shadow-sm: 0 2px 8px 0 rgba(0, 0, 0, 0.1); --glass-shadow-md: 0 4px 30px 0 rgba(0, 0, 0, 0.2); --glass-shadow-lg: 0 8px 40px 0 rgba(0, 0, 0, 0.35); --glass-bg-strong: rgba(255, 255, 255, 0.15); --glass-border-strong: rgba(255, 255, 255, 0.2); --glass-bg-soft: rgba(255, 255, 255, 0.03); --glass-border-soft: rgba(255, 255, 255, 0.06); }}
@theme { --color-foreground: var(--foreground); --color-muted-foreground: var(--muted-foreground); --color-glass-bg: var(--glass-bg); --color-glass-border: var(--glass-border); --shadow-glass: var(--glass-shadow); --shadow-glass-sm: var(--glass-shadow-sm); --shadow-glass-md: var(--glass-shadow-md); --shadow-glass-lg: var(--glass-shadow-lg); --backdrop-blur-glass: var(--glass-blur); --radius-glass-sm: var(--glass-radius-sm); --radius-glass-md: var(--glass-radius-md); --radius-glass-lg: var(--glass-radius-lg); --radius-glass-xl: var(--glass-radius-xl);}
input[type="password"]::-ms-reveal,input[type="password"]::-ms-clear { display: none; width: 0; height: 0;}
body { background: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%); background-attachment: fixed; color: var(--foreground); min-height: 100vh;}
.dark body { background: linear-gradient(135deg, #0f2027 0%, #203a43 50%, #2c5364 100%); background-attachment: fixed; color: var(--foreground);}
@utility glass { background-color: var(--glass-bg); border-width: 1px; border-style: solid; border-color: var(--glass-border); backdrop-filter: blur(var(--glass-blur)); box-shadow: var(--glass-shadow);}
@utility glass-strong { --glass-bg: var(--glass-bg-strong); --glass-border: var(--glass-border-strong); --glass-blur: var(--glass-blur-strong);}
@utility glass-soft { --glass-bg: var(--glass-bg-soft); --glass-border: var(--glass-border-soft); --glass-blur: var(--glass-blur-soft);}
@utility input-sm { height: 1.5rem; padding-left: 0.5rem; padding-right: 0.5rem; font-size: 0.75rem; line-height: 1rem; gap: 0.375rem;}
@utility btn-sm { height: 1.5rem; padding-left: 0.5rem; padding-right: 0.5rem; font-size: 0.75rem; line-height: 1rem; gap: 0.375rem;}
@utility input-md { height: 2rem; padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 0.625rem; padding-right: 0.625rem; font-size: 0.875rem; line-height: 1.25rem; gap: 0.5rem;}
@utility btn-md { height: 2rem; padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 0.625rem; padding-right: 0.625rem; font-size: 0.875rem; line-height: 1.25rem; gap: 0.5rem;}
@utility input-lg { height: 2.5rem; padding-left: 0.875rem; padding-right: 0.875rem; font-size: 1rem; line-height: 1.5rem; gap: 0.625rem;}
@utility btn-lg { height: 2.5rem; padding-left: 0.875rem; padding-right: 0.875rem; font-size: 1rem; line-height: 1.5rem; gap: 0.625rem;}
@utility btn-icon { padding: 0; width: 2rem; height: 2rem; aspect-ratio: 1 / 1;}@import "tailwindcss";
@layer base { :root { --foreground: #18181b; --muted-foreground: #3f3f46; --glass-bg: rgba(255, 255, 255, 0.35); --glass-border: rgba(255, 255, 255, 0.6); --glass-shadow: var(--glass-shadow-sm); --glass-blur: 6px; --glass-shadow-sm: 0 2px 8px 0 rgba(0, 0, 0, 0.06); --glass-shadow-md: 0 4px 30px 0 rgba(0, 0, 0, 0.1); --glass-shadow-lg: 0 8px 40px 0 rgba(0, 0, 0, 0.2); --glass-radius-sm: 0.375rem; --glass-radius-md: 0.75rem; --glass-radius-lg: 1rem; --glass-radius-xl: 1.5rem; --glass-bg-strong: rgba(255, 255, 255, 0.5); --glass-border-strong: rgba(255, 255, 255, 0.8); --glass-blur-strong: 10px; --glass-bg-soft: rgba(255, 255, 255, 0.2); --glass-border-soft: rgba(255, 255, 255, 0.4); --glass-blur-soft: 2px; }
.dark { --foreground: #fafafa; --muted-foreground: #d4d4d8; --glass-bg: rgba(255, 255, 255, 0.08); --glass-border: rgba(255, 255, 255, 0.1); --glass-shadow: var(--glass-shadow-sm); --glass-shadow-sm: 0 2px 8px 0 rgba(0, 0, 0, 0.1); --glass-shadow-md: 0 4px 30px 0 rgba(0, 0, 0, 0.2); --glass-shadow-lg: 0 8px 40px 0 rgba(0, 0, 0, 0.35); --glass-bg-strong: rgba(255, 255, 255, 0.15); --glass-border-strong: rgba(255, 255, 255, 0.2); --glass-bg-soft: rgba(255, 255, 255, 0.03); --glass-border-soft: rgba(255, 255, 255, 0.06); }}
@theme { --color-foreground: var(--foreground); --color-muted-foreground: var(--muted-foreground); --color-glass-bg: var(--glass-bg); --color-glass-border: var(--glass-border); --shadow-glass: var(--glass-shadow); --shadow-glass-sm: var(--glass-shadow-sm); --shadow-glass-md: var(--glass-shadow-md); --shadow-glass-lg: var(--glass-shadow-lg); --backdrop-blur-glass: var(--glass-blur); --radius-glass-sm: var(--glass-radius-sm); --radius-glass-md: var(--glass-radius-md); --radius-glass-lg: var(--glass-radius-lg); --radius-glass-xl: var(--glass-radius-xl);}
input[type="password"]::-ms-reveal,input[type="password"]::-ms-clear { display: none; width: 0; height: 0;}
body { background: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%); background-attachment: fixed; color: var(--foreground); min-height: 100vh;}
.dark body { background: linear-gradient(135deg, #0f2027 0%, #203a43 50%, #2c5364 100%); background-attachment: fixed; color: var(--foreground);}
@utility glass { background-color: var(--glass-bg); border-width: 1px; border-style: solid; border-color: var(--glass-border); backdrop-filter: blur(var(--glass-blur)); box-shadow: var(--glass-shadow);}
@utility glass-strong { --glass-bg: var(--glass-bg-strong); --glass-border: var(--glass-border-strong); --glass-blur: var(--glass-blur-strong);}
@utility glass-soft { --glass-bg: var(--glass-bg-soft); --glass-border: var(--glass-border-soft); --glass-blur: var(--glass-blur-soft);}
@utility input-sm { height: 1.5rem; padding-left: 0.5rem; padding-right: 0.5rem; font-size: 0.75rem; line-height: 1rem; gap: 0.375rem;}
@utility btn-sm { height: 1.5rem; padding-left: 0.5rem; padding-right: 0.5rem; font-size: 0.75rem; line-height: 1rem; gap: 0.375rem;}
@utility input-md { height: 2rem; padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 0.625rem; padding-right: 0.625rem; font-size: 0.875rem; line-height: 1.25rem; gap: 0.5rem;}
@utility btn-md { height: 2rem; padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 0.625rem; padding-right: 0.625rem; font-size: 0.875rem; line-height: 1.25rem; gap: 0.5rem;}
@utility input-lg { height: 2.5rem; padding-left: 0.875rem; padding-right: 0.875rem; font-size: 1rem; line-height: 1.5rem; gap: 0.625rem;}
@utility btn-lg { height: 2.5rem; padding-left: 0.875rem; padding-right: 0.875rem; font-size: 1rem; line-height: 1.5rem; gap: 0.625rem;}
@utility btn-icon { padding: 0; width: 2rem; height: 2rem; aspect-ratio: 1 / 1;}Add the configuration file
Create a glass.config.json file at the root of your project:
{ "framework": "remix", "style": "default", "css": "app/app.css", "aliases": { "components": "@/components/ui", "utils": "@/lib/utils" }}{ "framework": "remix", "style": "default", "css": "app/app.css", "aliases": { "components": "@/components/ui", "utils": "@/lib/utils" }}Adjust the framework and css paths according to your project structure. The aliases defined here must match your tsconfig.json exactly.