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 🙏

© 2025 – Pkg Stats / Ryan Hefner

apple-liquid-glass-ui

v1.0.9

Published

A premium React UI library with Apple-inspired glass surfaces. Features true glassmorphism with translucent backgrounds, blur effects, and smooth animations.

Downloads

971

Readme

glass-ui

A premium React UI library with Apple-inspired glass surfaces. Features true glassmorphism with translucent backgrounds, blur effects, and smooth animations.

Perfect for creating modern, elegant UIs with authentic macOS/iOS feel.

🚀 View Live Demo | 📦 npm | 📖 GitHub

Features

  • True Glassmorphism: Translucent backgrounds with backdrop blur and saturation filters
  • Apple-Inspired Design: Authentic macOS/iOS aesthetic with refined typography and spacing
  • Dual API: Use as React components or standalone CSS classnames
  • Dark Mode Support: Seamless light/dark theme switching
  • Mobile-First: Touch-friendly with responsive breakpoints
  • 27+ Components: Complete UI toolkit from buttons to navigation
  • TypeScript: Full type definitions included
  • Tree-Shakeable: Import only what you need
  • Zero Runtime: No CSS-in-JS overhead - just static CSS

⚡️ Performance

Apple Liquid Glass UI is built for speed. Unlike traditional CSS-in-JS libraries, we use zero runtime CSS for maximum performance.

Bundle Size

| Library | Full Bundle (gzipped) | vs Glass UI | |---------|----------------------|-------------| | Apple Liquid Glass UI | 24.1 KB | baseline | | Material-UI (MUI) | 95.0 KB | +293% | | Chakra UI | 85.0 KB | +252% | | Ant Design | 180.0 KB | +645% | | Mantine | 75.0 KB | +211% |

Key Metrics:

  • 📦 24.1 KB total (gzipped) - JavaScript + CSS combined
  • 🎯 6.6 KB JavaScript (gzipped)
  • 🎨 10.9 KB CSS (gzipped)
  • ⚡️ 72% smaller than Chakra UI
  • 🚀 75% smaller than Material-UI

Zero Runtime CSS-in-JS

Traditional CSS-in-JS libraries (styled-components, emotion, etc.) have runtime overhead:

  • ❌ Parse style objects on every render
  • ❌ Generate class names dynamically
  • ❌ Inject styles into the DOM
  • ❌ Additional ~30KB bundle size

Apple Liquid Glass UI uses static CSS:

  • ✅ Zero runtime overhead
  • ✅ Styles loaded once, cached forever
  • ✅ No style computation during renders
  • ✅ Maximum performance

Tree-Shaking Support

Import only what you need. Each component adds minimal weight:

| Component | Size (with CSS) | |-----------|----------------| | Button | 3.9 KB | | Input | 4.7 KB | | Badge | 2.5 KB | | Avatar | 3.3 KB | | Card | 4.8 KB | | DatePicker | 14.5 KB |

Average component size: ~5.1 KB (uncompressed source)

Performance Benchmarks

Run the benchmark yourself:

npm run benchmark
# or open scripts/benchmark.html in your browser

Typical results (1000 components):

  • 30-40% faster initial mount vs CSS-in-JS
  • 25-35% faster updates vs CSS-in-JS
  • 0KB runtime vs ~30KB for styled-components

Why It Matters

For a typical application using 10-15 components:

  • Glass UI: ~15-20 KB total
  • MUI/Chakra: ~100 KB total
  • You save: ~80 KB (4-5x smaller bundle)

Result: Faster page loads, better Core Web Vitals, improved user experience.

Installation

npm install apple-liquid-glass-ui

Quick Start

Import the CSS tokens and utilities in your app entry point:

import 'apple-liquid-glass-ui/dist/index.css';

Set the theme attribute on your HTML element:

<html data-gl-theme="light">
  <!-- or data-gl-theme="dark" -->
</html>

Add a colorful background to see the glass effect:

import { Button, Card } from 'apple-liquid-glass-ui';

function App() {
  return (
    <div
      className="gl-base"
      style={{
        minHeight: '100vh',
        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%)',
        backgroundAttachment: 'fixed',
        padding: '2rem'
      }}
    >
      <Card padding="lg">
        <h1>Welcome to apple-liquid-glass-ui</h1>
        <Button variant="primary">Get Started</Button>
      </Card>
    </div>
  );
}

Dual API

apple-liquid-glass-ui supports both React components and classname utilities.

React Components

import { Button } from 'apple-liquid-glass-ui';

<Button variant="primary" size="md">
  Click me
</Button>

Classname Utilities

<button class="gl-btn gl-btn-primary gl-btn-md">
  Click me
</button>

Both approaches provide the same authentic Apple Glass styling with blur effects, translucency, and smooth animations.

Components

Button

import { Button } from 'glass-ui';

<Button variant="primary" size="md">Primary</Button>
<Button variant="subtle" size="md">Subtle</Button>
<Button variant="ghost" size="md">Ghost</Button>

// Icon button
<Button variant="primary" size="md" iconOnly>
  ×
</Button>

Classname API:

<button class="gl-btn gl-btn-primary gl-btn-md">Primary</button>
<button class="gl-btn gl-btn-subtle gl-btn-md">Subtle</button>
<button class="gl-btn gl-btn-ghost gl-btn-md">Ghost</button>
<button class="gl-btn gl-btn-primary gl-btn-icon-md">×</button>

Input

import { Input, Textarea, InputGroup } from 'glass-ui';

<Input size="md" placeholder="Enter text..." />
<Textarea size="md" placeholder="Enter text..." />

<InputGroup
  label="Email"
  hint="We'll never share your email"
  error="Invalid email"
  required
>
  <Input type="email" error />
</InputGroup>

Classname API:

<input class="gl-input gl-input-md" placeholder="Enter text..." />
<textarea class="gl-input gl-textarea gl-textarea-md" placeholder="Enter text..."></textarea>

<div class="gl-input-group">
  <label class="gl-input-label">Email <span style="color: var(--gl-color-error)"> *</span></label>
  <input class="gl-input gl-input-md gl-input-invalid" type="email" />
  <span class="gl-input-error">Invalid email</span>
</div>

Card

import { Card, CardHeader, CardBody, CardFooter } from 'glass-ui';

<Card variant="default" padding="md">
  <CardHeader title="Card Title" description="Card description" />
  <CardBody>Content goes here</CardBody>
  <CardFooter>
    <Button variant="ghost">Cancel</Button>
    <Button variant="primary">Save</Button>
  </CardFooter>
</Card>

Classname API:

<div class="gl-card gl-card-md">
  <div class="gl-card-header">
    <div>
      <h3 class="gl-card-header-title">Card Title</h3>
      <p class="gl-card-header-description">Card description</p>
    </div>
  </div>
  <div class="gl-card-body">Content goes here</div>
  <div class="gl-card-footer">
    <button class="gl-btn gl-btn-ghost gl-btn-md">Cancel</button>
    <button class="gl-btn gl-btn-primary gl-btn-md">Save</button>
  </div>
</div>

Sheet (Modal)

import { Sheet } from 'glass-ui';

const [open, setOpen] = useState(false);

<Sheet open={open} onClose={() => setOpen(false)} size="md">
  <Sheet.Header title="Sheet Title" onClose={() => setOpen(false)} />
  <Sheet.Body>Content goes here</Sheet.Body>
  <Sheet.Footer>
    <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
    <Button variant="primary">Confirm</Button>
  </Sheet.Footer>
</Sheet>

Select & Dropdown

import { Select, Dropdown } from 'glass-ui';

// Native select
<Select size="md">
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</Select>

// Custom dropdown
<Dropdown
  options={[
    { value: '1', label: 'Option 1' },
    { value: '2', label: 'Option 2' },
  ]}
  value={value}
  onChange={setValue}
  size="md"
/>

Checkbox, Radio, Switch

import { Checkbox, Radio, Switch } from 'glass-ui';

<Checkbox label="Accept terms" size="md" />
<Radio name="option" label="Option 1" size="md" />
<Switch label="Enable notifications" size="md" />

Classname API:

<label class="gl-checkbox-wrapper">
  <input type="checkbox" class="gl-checkbox-input" />
  <span class="gl-checkbox-box"></span>
  <span class="gl-checkbox-label">Accept terms</span>
</label>

<label class="gl-radio-wrapper">
  <input type="radio" class="gl-radio-input" name="option" />
  <span class="gl-radio-circle"></span>
  <span class="gl-radio-label">Option 1</span>
</label>

<label class="gl-switch-wrapper">
  <input type="checkbox" class="gl-switch-input" />
  <span class="gl-switch-track"></span>
  <span class="gl-switch-label">Enable notifications</span>
</label>

DatePicker

Glass-styled calendar date picker with animations:

import { DatePicker } from 'apple-liquid-glass-ui';

const [date, setDate] = useState<Date | undefined>();

// Basic date picker
<DatePicker
  label="Select Date"
  placeholder="Choose a date"
  value={date}
  onChange={setDate}
  size="md"
/>

// With constraints
<DatePicker
  label="Birth Date"
  placeholder="MM/DD/YYYY"
  value={birthDate}
  onChange={setBirthDate}
  maxDate={new Date()}
  size="md"
/>

// Different sizes
<DatePicker label="Small" size="sm" />
<DatePicker label="Medium" size="md" />
<DatePicker label="Large" size="lg" />

Props:

  • value: Selected date (Date object)
  • onChange: Callback with selected date
  • label: Optional label text
  • placeholder: Input placeholder
  • minDate: Minimum selectable date
  • maxDate: Maximum selectable date
  • disabled: Disable picker
  • size: 'sm' | 'md' | 'lg'

Features:

  • Full calendar view with month/year navigation
  • Today button for quick access
  • Min/max date constraints
  • Glass-styled dropdown with blur effects
  • Smooth animations
  • Dark mode support

Badge

import { Badge } from 'glass-ui';

<Badge variant="primary" size="md">New</Badge>
<Badge variant="success" size="md">Success</Badge>
<Badge variant="default" size="md" dot />

Avatar

import { Avatar, AvatarGroup } from 'glass-ui';

<Avatar src="/path/to/image.jpg" size="md" />
<Avatar fallback="John Doe" size="md" status="online" />

<AvatarGroup>
  <Avatar fallback="JD" size="md" />
  <Avatar fallback="AS" size="md" />
  <Avatar fallback="BK" size="md" />
</AvatarGroup>

Typography

import { Heading, Text, Code, Link } from 'glass-ui';

<Heading level={1}>Main Heading</Heading>
<Text size="md" variant="secondary">Paragraph text</Text>
<Code>const foo = 'bar';</Code>
<Link href="#">Learn more</Link>

Classname API:

<h1 class="gl-heading gl-h1">Main Heading</h1>
<p class="gl-text gl-text-md gl-text-secondary">Paragraph text</p>
<code class="gl-code">const foo = 'bar';</code>
<a href="#" class="gl-link">Learn more</a>

Tooltip

import { Tooltip } from 'glass-ui';

<Tooltip content="Tooltip text" position="top">
  <Button>Hover me</Button>
</Tooltip>

Layout

import { Container, Stack, Grid, Flex, Divider, Spacer, Center } from 'apple-liquid-glass-ui';

<Container size="lg">
  <Stack gap="lg">
    <div>Item 1</div>
    <div>Item 2</div>
  </Stack>
</Container>

<Grid cols={3} gap="lg">
  <div>Grid item 1</div>
  <div>Grid item 2</div>
  <div>Grid item 3</div>
</Grid>

// Flex - Flexible layouts with props
<Flex direction="row" justify="between" align="center" gap="md">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</Flex>

<Flex direction="column" align="start" gap="sm">
  <Button variant="ghost">Action 1</Button>
  <Button variant="ghost">Action 2</Button>
</Flex>

<Divider />
<Divider vertical />

Flex Props:

  • direction: 'row' | 'column' | 'row-reverse' | 'column-reverse'
  • align: 'start' | 'center' | 'end' | 'stretch' | 'baseline'
  • justify: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
  • wrap: 'nowrap' | 'wrap' | 'wrap-reverse'
  • gap: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
  • inline: Display as inline-flex

Classname API:

<div class="gl-container gl-container-lg">
  <div class="gl-stack gl-stack-gap-lg">
    <div>Item 1</div>
    <div>Item 2</div>
  </div>
</div>

<div class="gl-grid gl-grid-cols-3 gl-grid-gap-lg">
  <div>Grid item 1</div>
  <div>Grid item 2</div>
  <div>Grid item 3</div>
</div>

<!-- Flex with utility classes -->
<div class="d-flex justify-content-between align-items-center gap-3">
  <div>Item 1</div>
  <div>Item 2</div>
</div>

<hr class="gl-divider" />
<span class="gl-divider-vertical"></span>

Alert

Display important messages with glass-styled alerts:

import { Alert } from 'apple-liquid-glass-ui';

<Alert
  variant="success"
  title="Success!"
  message="Your changes have been saved."
  closable
/>

<Alert
  variant="error"
  title="Error"
  message="Something went wrong."
/>

<Alert
  variant="warning"
  title="Warning"
  message="Please review before proceeding."
/>

<Alert variant="info">
  Simple info alert without title
</Alert>

Props:

  • variant: 'default' | 'success' | 'error' | 'warning' | 'info'
  • title: Optional alert title
  • message: Alert message content
  • closable: Show close button
  • onClose: Callback when closed

Navigation

Apple-style navigation with glass blur effect:

import { GlassTopNav, GlassNavItem, GlassBottomNav } from 'apple-liquid-glass-ui';

// Top Navigation
<GlassTopNav>
  <GlassTopNav.Left>
    <div className="gl-logo">MyApp</div>
  </GlassTopNav.Left>

  <GlassTopNav.Center>
    <GlassNavItem active onClick={() => setActive('home')}>
      Home
    </GlassNavItem>
    <GlassNavItem onClick={() => setActive('about')}>
      About
    </GlassNavItem>
    <GlassNavItem onClick={() => setActive('contact')}>
      Contact
    </GlassNavItem>
  </GlassTopNav.Center>

  <GlassTopNav.Right>
    <Button variant="primary" size="sm">Sign In</Button>
  </GlassTopNav.Right>
</GlassTopNav>

// Bottom Navigation (shows on mobile <768px)
<GlassBottomNav>
  <GlassNavItem active icon="🏠" label="Home" />
  <GlassNavItem icon="🔍" label="Search" />
  <GlassNavItem icon="⚙️" label="Settings" />
</GlassBottomNav>

Features:

  • Sticky top navigation with blur background
  • Mobile bottom navigation that appears on small screens
  • Active state styling with accent color
  • Compound component pattern for flexible layouts

Slider

Range input with glass styling and optional value display:

import { Slider } from 'apple-liquid-glass-ui';

const [volume, setVolume] = useState(50);

<Slider
  label="Volume"
  value={volume}
  onChange={setVolume}
  min={0}
  max={100}
  showValue
  size="md"
/>

<Slider
  label="Temperature"
  value={temp}
  onChange={setTemp}
  min={-20}
  max={40}
  step={0.5}
  showValue
  unit="°C"
/>

Props:

  • label: Optional label text
  • value: Current value
  • onChange: Callback with new value
  • min, max, step: Range configuration
  • showValue: Display current value
  • unit: Optional unit suffix
  • size: 'sm' | 'md' | 'lg'

Tabs

Content organization with default or underline variants:

import { Tabs } from 'apple-liquid-glass-ui';

<Tabs
  items={[
    { key: 'overview', label: 'Overview', content: <div>Overview content</div> },
    { key: 'details', label: 'Details', content: <div>Details content</div> },
    { key: 'settings', label: 'Settings', content: <div>Settings content</div> }
  ]}
  defaultActiveKey="overview"
  onChange={(key) => console.log('Tab changed:', key)}
/>

// Underline variant
<Tabs
  variant="underline"
  items={[...]}
/>

Props:

  • items: Array of { key, label, content }
  • defaultActiveKey: Initial active tab
  • onChange: Callback when tab changes
  • variant: 'default' | 'underline'

Progress

Progress indicators with optional percentage display:

import { Progress } from 'apple-liquid-glass-ui';

// Determinate progress
<Progress value={45} showPercent size="md" />

// Indeterminate (loading)
<Progress indeterminate size="md" />

// With label
<Progress
  value={75}
  showPercent
  label="Upload Progress"
  size="lg"
/>

// Variants
<Progress value={60} variant="success" />
<Progress value={30} variant="error" />

Props:

  • value: Progress value (0-100)
  • indeterminate: Show loading animation
  • showPercent: Display percentage text
  • label: Optional label above progress bar
  • variant: 'default' | 'success' | 'error' | 'warning'
  • size: 'sm' | 'md' | 'lg'

Spinner

Loading indicators with optional overlay mode:

import { Spinner } from 'apple-liquid-glass-ui';

// Basic spinner
<Spinner size="md" />

// With label
<Spinner label="Loading..." size="lg" />

// Full-page overlay
<Spinner overlay label="Processing..." size="lg" />

// Different sizes
<Spinner size="sm" />
<Spinner size="md" />
<Spinner size="lg" />

Props:

  • size: 'sm' | 'md' | 'lg'
  • label: Optional loading text
  • overlay: Full-page overlay mode with glass background

Skeleton

Bootstrap-style loading placeholders with smooth animations:

import { Skeleton, SkeletonText, SkeletonAvatar, SkeletonCard, SkeletonTable } from 'apple-liquid-glass-ui';

// Basic skeleton
<Skeleton variant="text" width="100%" />
<Skeleton variant="rectangular" width={200} height={100} />
<Skeleton variant="circular" width={40} height={40} />
<Skeleton variant="rounded" width="100%" height={200} />

// Animation types
<Skeleton animation="wave" /> // Default shimmering effect
<Skeleton animation="pulse" /> // Opacity pulsing
<Skeleton animation={false} /> // No animation

// Text lines
<SkeletonText lines={3} />
<SkeletonText lines={5} width="80%" />

// Avatar placeholder
<SkeletonAvatar size="sm" />
<SkeletonAvatar size="md" />
<SkeletonAvatar size="lg" />
<SkeletonAvatar size="xl" />

// Card with avatar and text
<SkeletonCard avatar lines={3} />
<SkeletonCard avatar={false} lines={5} />

// Table placeholder
<SkeletonTable rows={5} columns={4} />
<SkeletonTable rows={10} columns={6} animation="pulse" />

Skeleton Props:

  • variant: 'text' | 'circular' | 'rectangular' | 'rounded'
  • width: Width in pixels or percentage
  • height: Height in pixels or percentage
  • animation: 'wave' | 'pulse' | false

SkeletonText Props:

  • lines: Number of lines (default: 3)
  • width: Width for all lines except last
  • animation: Animation type

SkeletonAvatar Props:

  • size: 'sm' | 'md' | 'lg' | 'xl'
  • animation: Animation type

SkeletonCard Props:

  • avatar: Show avatar (default: true)
  • lines: Number of text lines (default: 3)
  • animation: Animation type

SkeletonTable Props:

  • rows: Number of rows (default: 5)
  • columns: Number of columns (default: 4)
  • animation: Animation type

Menu

Context menus and dropdown menus with glass styling:

import { Menu } from 'apple-liquid-glass-ui';

<Menu
  trigger={<Button>Actions</Button>}
  position="bottom"
  items={[
    { key: 'edit', label: 'Edit', icon: '✏️', shortcut: '⌘E', onClick: handleEdit },
    { key: 'duplicate', label: 'Duplicate', icon: '📋', onClick: handleDuplicate },
    { type: 'divider' },
    { type: 'label', label: 'Danger Zone' },
    { key: 'delete', label: 'Delete', icon: '🗑️', danger: true, onClick: handleDelete },
    { key: 'disabled', label: 'Disabled Action', disabled: true }
  ]}
/>

Props:

  • trigger: Element to click to open menu
  • position: 'top' | 'bottom' | 'left' | 'right'
  • items: Array of menu items, dividers, or labels

MenuItem Type:

  • key: Unique identifier
  • label: Display text
  • icon: Optional icon element
  • shortcut: Optional keyboard shortcut display
  • danger: Red text for destructive actions
  • disabled: Disable interaction
  • onClick: Callback when clicked

Table

Data tables with sorting, hover effects, and glass styling:

import { Table } from 'apple-liquid-glass-ui';

// Basic table
<Table>
  <Table.Header>
    <Table.Row>
      <Table.Head>Name</Table.Head>
      <Table.Head>Email</Table.Head>
      <Table.Head align="right">Status</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    <Table.Row>
      <Table.Cell>Sarah Chen</Table.Cell>
      <Table.Cell>[email protected]</Table.Cell>
      <Table.Cell align="right">
        <Badge variant="success">Active</Badge>
      </Table.Cell>
    </Table.Row>
  </Table.Body>
</Table>

// Table with sorting
const [sortColumn, setSortColumn] = useState<string | null>(null);
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');

<Table hover striped>
  <Table.Header>
    <Table.Row>
      <Table.Head
        sortable
        sorted={sortColumn === 'name' ? sortDirection : null}
        onSort={() => {
          if (sortColumn === 'name') {
            setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
          } else {
            setSortColumn('name');
            setSortDirection('asc');
          }
        }}
      >
        Name
      </Table.Head>
      <Table.Head>Project</Table.Head>
      <Table.Head align="right">Progress</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    {sortedData.map((row) => (
      <Table.Row key={row.id}>
        <Table.Cell>{row.name}</Table.Cell>
        <Table.Cell>{row.project}</Table.Cell>
        <Table.Cell align="right">{row.progress}%</Table.Cell>
      </Table.Row>
    ))}
  </Table.Body>
</Table>

// Compact table
<Table size="sm">
  {/* ... */}
</Table>

Props:

  • Table: hover, striped, size ('sm' | 'md' | 'lg')
  • Table.Head: sortable, sorted ('asc' | 'desc' | null), onSort, align ('left' | 'center' | 'right')
  • Table.Cell: align ('left' | 'center' | 'right')

Features:

  • Glassmorphism styling with backdrop blur
  • Sortable column headers with arrow indicators
  • Hover effect on rows
  • Striped rows for better readability
  • Three size variants (sm, md, lg)
  • Responsive design with horizontal scrolling
  • Cell alignment options

Theming

Toggle between light and dark themes:

// Toggle theme
const theme = document.documentElement.getAttribute('data-gl-theme');
document.documentElement.setAttribute('data-gl-theme', theme === 'light' ? 'dark' : 'light');

CSS Variables

All design tokens are available as CSS variables:

var(--gl-color-bg)
var(--gl-color-surface)
var(--gl-color-border)
var(--gl-color-accent)
var(--gl-radius-lg)
var(--gl-blur-surface)
var(--gl-shadow-soft)
var(--gl-space-md)
var(--gl-font-size-md)

See tokens.css for the complete list.

License

MIT