RanjuUI
The last UI library you'll ever need. 40+ beautiful components, zero dependencies, two files. Drop in and ship.
Installation
Include two files — CDN or self-hosted.
<link rel="stylesheet" href="https://alps-is-core.github.io/RanjuUI/ranju.css">
<script src="https://alps-is-core.github.io/RanjuUI/ranju.js" defer></script>
<link rel="stylesheet" href="ranju.css">
<script src="ranju.js" defer></script>
The CSS and JS bundles at the repo root are built from src/css/ and src/js/ via make dist. Use the bundles for the full library, or import individual component files for smaller payloads.
Theming & Dark Mode
Set data-theme="dark" on the <html> element, or use the JS API. RanjuUI auto-detects system preference.
Ranju.theme.toggle(); // switch between light/dark
Ranju.theme.set('dark'); // force dark
Ranju.theme.current(); // get 'light' or 'dark'
Typography
Clean heading scale, text utilities, and semantic inline elements.
Heading 1
Heading 2
Heading 3
Heading 4
Regular paragraph text with bold, italic, inline code, highlighted text, and links.
Muted small text for secondary content.
Blockquotes for pull quotes and citations.
const hello = "preformatted code block";
<h1>Heading 1</h1>
<p>Text with <strong>bold</strong>, <code>code</code>, <mark>highlight</mark>.</p>
<p class="text-muted text-sm">Muted secondary text.</p>
<blockquote>Blockquote.</blockquote>
<pre><code>const x = "preformatted";</code></pre>
Grid & Layout
Responsive CSS grid and flexbox utility classes.
<div class="grid grid-cols-3 gap-4">
<div class="p-4 rounded border">1</div>
<div class="p-4 rounded border">2</div>
<div class="p-4 rounded border">3</div>
</div>
Utilities
Common spacing, sizing, border-radius, shadow, and display helpers.
<div class="p-3 rounded shadow border">shadow</div>
<div class="p-3 rounded shadow-md border">shadow-md</div>
<div class="p-3 rounded shadow-lg border">shadow-lg</div>
<!-- gap-1 to gap-8, p-0 to p-8, flex, grid, etc. -->
Accordion
Expandable content panels, single or multi-open.
ranju.css and include ranju.js with the defer attribute. That's two files — zero configuration.<div class="accordion">
<div class="accordion-item" data-state="open">
<button class="accordion-trigger">Title</button>
<div class="accordion-content">
<div class="accordion-body">Content here...</div>
</div>
</div>
</div>
Alert
Contextual feedback messages with optional dismiss.
<div class="alert alert-info">
<div class="alert-content">
<div class="alert-title">Info</div>
<div class="alert-description">Message text.</div>
</div>
<button class="alert-close">×</button>
</div>
<!-- alert-success, alert-warning, alert-destructive -->
Aspect Ratio
Maintain consistent aspect ratios for media containers.
<div class="aspect-square">1:1</div>
<div class="aspect-video">16:9</div>
<div class="aspect-photo">4:3</div>
Avatar
User profile images with fallback initials and group stacking.
<div class="avatar avatar-sm">SM</div>
<div class="avatar">AP</div>
<div class="avatar avatar-lg">LG</div>
<div class="avatar-group">
<div class="avatar">A</div>
<div class="avatar">B</div>
</div>
Badge
Small status labels and tags.
<span class="badge">Primary</span>
<span class="badge badge-secondary">Secondary</span>
<span class="badge badge-outline">Outline</span>
<span class="badge badge-success badge-dot">Online</span>
Breadcrumb
Navigation path indicator.
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Components</a></li>
<li><span aria-current="page">Breadcrumb</span></li>
</ol>
Button
Action triggers in multiple variants and sizes.
<button class="btn">Primary</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-sm">Small</button>
<button class="btn btn-lg">Large</button>
<div class="btn-group">
<button class="btn btn-outline">Left</button>
<button class="btn btn-outline">Right</button>
</div>
Calendar
Interactive date picker calendar. Auto-initializes or use Ranju.calendar(el, options).
<div class="calendar"></div>
<!-- Auto-initializes. For manual control: -->
<script>
Ranju.calendar(el, {
onSelect: function(date) { console.log(date); }
});
</script>
Card
Flexible content container with header, body, and footer regions.
This is the main body content of the card. Cards can hold any type of content.
Building RanjuUI — an ultra-lightweight component library. No frameworks needed.
<div class="card">
<div class="card-header">
<div class="card-title">Title</div>
<div class="card-description">Description</div>
</div>
<div class="card-content">Content here</div>
<div class="card-footer">
<button class="btn btn-sm">Action</button>
</div>
</div>
Carousel
Image or content slider with navigation controls and dots.
<div class="carousel" style="height:200px">
<div class="carousel-track">
<div class="carousel-slide">Slide 1</div>
<div class="carousel-slide">Slide 2</div>
<div class="carousel-slide">Slide 3</div>
</div>
<button class="carousel-btn carousel-prev">‹</button>
<button class="carousel-btn carousel-next">›</button>
<div class="carousel-dots">
<button class="carousel-dot"></button>
<button class="carousel-dot"></button>
<button class="carousel-dot"></button>
</div>
</div>
Checkbox & Radio
Custom styled selection controls with native semantics.
<label class="checkbox">
<input type="checkbox" checked>
<span class="checkbox-mark"></span>
Option A
</label>
<label class="radio">
<input type="radio" name="choice" checked>
<span class="radio-mark"></span>
Choice 1
</label>
Collapsible
Simple show/hide toggle for any content block.
data-state to control initial state.
<div class="collapsible" data-state="closed">
<button class="btn btn-outline btn-sm collapsible-trigger">Toggle</button>
<div class="collapsible-content">
<div class="mt-4 p-4 rounded border">Hidden content</div>
</div>
</div>
Combobox
Searchable dropdown select with filtering.
- RanjuUI
- React
- Vue
- Svelte
- Angular
- Solid
<div class="combobox" data-state="closed" style="max-width:300px">
<input class="combobox-input input" placeholder="Search...">
<ul class="combobox-list">
<li class="combobox-option">Option 1</li>
<li class="combobox-option">Option 2</li>
</ul>
</div>
Command Palette
Keyboard-first command launcher. Press Ctrl + K or click the button below.
<button onclick="Ranju.command.open('cmd')">Open</button>
<div class="command-overlay" id="cmd" data-state="closed">
<div class="command-dialog">
<div class="command-input-wrapper">
<input class="command-input" placeholder="Type a command...">
</div>
<div class="command-list">
<div class="command-group-label">Actions</div>
<div class="command-item">Toggle Theme<span class="command-shortcut">T T</span></div>
</div>
</div>
</div>
<!-- Ctrl+K opens automatically -->
Data Table
Sortable data tables with hover and stripe options. Click headers to sort.
| Name | Status | Role | Actions |
|---|---|---|---|
| Alice Chen | Active | Admin | |
| Bob Smith | Inactive | Member | |
| Carol Davis | Active | Editor | |
| Dan Wilson | Pending | Member |
Dialog
Modal dialog with overlay, close on backdrop click, and escape key support.
<button data-dialog-open="my-dialog">Open</button>
<div class="dialog-overlay" id="my-dialog" data-state="closed">
<div class="dialog" style="position:relative">
<button class="dialog-close" data-dialog-close>×</button>
<div class="dialog-header">
<div class="dialog-title">Title</div>
</div>
<div class="dialog-body">Content</div>
<div class="dialog-footer">
<button data-dialog-close>Close</button>
</div>
</div>
</div>
Drawer & Sheet
Bottom drawer and side sheet panels. Use the standard dialog system with overlay.
Drawer Title
This is a bottom drawer panel. Use it for additional actions or content.
Sheet Panel
This is a side sheet panel that slides in from the right. Great for detail views, settings, or editing forms.
<button data-dialog-open="drawer-id">Open Drawer</button>
<div class="dialog-overlay" id="drawer-id" data-state="closed"></div>
<div class="drawer" data-state="closed">
<div class="drawer-handle"></div>
<div class="p-6">Content. Use Ranju.dialog.close('drawer-id') to close.</div>
</div>
Dropdown
Click-triggered menu overlays.
<div class="dropdown" data-state="closed">
<button class="btn btn-outline" data-dropdown-trigger>Options ▾</button>
<ul class="dropdown-menu">
<li class="dropdown-label">Section</li>
<li class="dropdown-item">Profile</li>
<li class="dropdown-item">Settings</li>
<li class="dropdown-separator"></li>
<li class="dropdown-item" style="color:var(--destructive)">Log Out</li>
</ul>
</div>
Empty State
Placeholder content for empty lists or search results.
<div class="empty-state">
<div class="empty-state-title">No results found</div>
<div class="empty-state-description">Try adjusting your search.</div>
<button class="btn btn-sm">Clear Filters</button>
</div>
Input & Textarea
Form controls with validation states, groups, and field layouts.
<div class="field">
<label class="label">Username</label>
<input type="text" class="input" placeholder="Enter username">
<div class="field-hint">Must be 3+ chars.</div>
</div>
<div class="field">
<label class="label label-required">Email</label>
<input type="email" class="input" placeholder="name@example.com">
</div>
<div class="input-group">
<span class="input-group-text">https://</span>
<input type="text" class="input" placeholder="example.com">
</div>
<textarea placeholder="Message..."></textarea>
Hover Card
Rich content preview on hover.
Creator of RanjuUI. Building beautiful standards-based web components.
<div class="hover-card">
<a href="#">@username</a>
<div class="hover-card-content">
<div class="flex items-center gap-3">
<div class="avatar">U</div>
<div><div class="font-semibold">Name</div><div class="text-xs text-muted">@user</div></div>
</div>
<p class="text-sm text-muted">Description.</p>
</div>
</div>
Kbd
Keyboard shortcut hints.
<kbd>Ctrl</kbd> + <kbd>C</kbd>
<kbd>Esc</kbd>
Label
Form labels with required indicator support.
<label class="label">Field name</label>
<label class="label label-required">Required</label>
Meter
Value gauge indicator with semantic colors.
<div class="meter"><div class="meter-fill" style="width:65%"></div></div>
<div class="meter meter-warning"><div class="meter-fill" style="width:80%"></div></div>
<div class="meter meter-destructive"><div class="meter-fill" style="width:95%"></div></div>
Pagination
Page navigation controls.
<nav class="pagination">
<a class="pagination-item" href="#">«</a>
<a class="pagination-item" href="#">1</a>
<a class="pagination-item active" aria-current="page" href="#">2</a>
<a class="pagination-item" href="#">»</a>
</nav>
Popover
Click-triggered floating content panel.
Dimensions
<div class="popover" data-state="closed">
<button class="btn btn-outline" data-popover-trigger>Open</button>
<div class="popover-content">
<h4>Content</h4>
<input type="text" class="input">
</div>
</div>
Progress
Determinate and indeterminate loading bars.
<div class="progress"><div class="progress-fill" style="width:65%"></div></div>
<div class="progress progress-sm"><div class="progress-fill" style="width:40%"></div></div>
<div class="progress progress-indeterminate"><div class="progress-fill"></div></div>
Resizable
Draggable resize handles between panels.
<div class="resizable border rounded" style="height:150px">
<div class="resizable-panel p-4">Left</div>
<div class="resizable-handle"></div>
<div class="resizable-panel p-4">Right</div>
</div>
Scroll Area
Custom styled scrollbar container.
Scrollable content area with custom thin scrollbars.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, turpis et commodo pharetra.
<div class="scroll-area" style="height:200px">
<p>Long scrollable content...</p>
</div>
Separator
Horizontal and vertical content dividers.
Content above
Content below
<hr class="separator">
<div class="separator-label">or continue with</div>
<div class="flex items-center gap-4">
<span>Left</span>
<div class="separator-vertical" style="height:1.5rem"></div>
<span>Right</span>
</div>
Sidebar
App sidebar navigation with sections, labels, and collapsible support.
<div class="sidebar" style="height:300px;width:240px">
<div class="sidebar-header"><div class="font-semibold">Workspace</div></div>
<div class="sidebar-content">
<div class="sidebar-label">Main</div>
<a class="sidebar-item active" href="#">Dashboard</a>
<a class="sidebar-item" href="#">Settings</a>
</div>
<div class="sidebar-footer">
<button class="btn btn-ghost btn-sm" data-sidebar-toggle="sidebar-id">Toggle</button>
</div>
</div>
Skeleton
Loading placeholder shimmer animations.
<div class="skeleton skeleton-avatar"></div>
<div class="skeleton skeleton-heading"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-image"></div>
<div class="skeleton skeleton-btn"></div>
Slider
Range input with custom styling.
<div class="field">
<label class="label">Volume <span id="vol">50</span>%</label>
<div class="slider">
<input type="range" min="0" max="100" value="50"
oninput="document.getElementById('vol').textContent=this.value">
</div>
</div>
Spinner
Loading indicator variants.
<div class="spinner spinner-sm"></div>
<div class="spinner"></div>
<div class="spinner spinner-lg"></div>
<div class="spinner-dots"><span></span><span></span><span></span></div>
<div class="spinner-bar"><span></span><span></span><span></span></div>
Switch & Toggle
On/off switches and pressable toggle buttons.
<label class="switch">
<input type="checkbox" checked>
<span class="switch-track"><span class="switch-thumb"></span></span>
Label
</label>
<button class="toggle active" aria-pressed="true">Bold</button>
<div class="toggle-group">
<button class="toggle active">Left</button>
<button class="toggle">Center</button>
<button class="toggle">Right</button>
</div>
Tabs
Tabbed content panels with underline and pill variants.
Account Settings
Manage your account details and preferences.
Password
Change your password and security settings.
Notifications
Configure how you receive notifications.
<div class="tabs">
<div class="tabs-list">
<button class="tabs-trigger active" data-tab="one">Tab 1</button>
<button class="tabs-trigger" data-tab="two">Tab 2</button>
</div>
<div class="tab-panel active" data-tab-panel="one">Content 1</div>
<div class="tab-panel" data-tab-panel="two">Content 2</div>
</div>
Toast / Notification
Non-blocking notifications via JavaScript API.
Ranju.toast({
title: 'Saved!',
description: 'Your changes have been saved.',
variant: 'success', // 'success' | 'destructive' | 'warning'
duration: 4000, // ms, 0 = persistent
position: 'bottom-right' // top-right, top-left, bottom-left, etc.
});
Tooltip
Lightweight hover hints. CSS-only or use data-tooltip for JS-enhanced tooltips.
<div class="tooltip">
<button class="btn btn-sm">Hover me</button>
<div class="tooltip-content">Tooltip text</div>
</div>
<button data-tooltip="JS tooltip">Hover me</button>
Item Group
Vertical or horizontal list layout for items with icons, text, and actions.
<div class="item-group border rounded">
<div class="item item-clickable">
<div class="item-content">
<div class="item-title">Dashboard</div>
<div class="item-description">Overview</div>
</div>
<span class="badge badge-ghost item-action">New</span>
</div>
<div class="item item-clickable">
<div class="item-content">
<div class="item-title">Settings</div>
</div>
</div>
</div>