From blank HTML to SaaS Dashboard in 5 minutes.
No Tailwind config. No build step. No setup. Just paste the CDN link and ship high-density, production-ready interfaces instantly. ~25KB total. 13 premium themes.
Installation
Integrate RAVN UI into your project in seconds. No build tools required for CDN usage.
<!-- Core Styles -->
<link rel="stylesheet" href="https://unpkg.com/@ravn-ui/core/dist/ui.css">
<link rel="stylesheet" href="https://unpkg.com/@ravn-ui/core/dist/themes.css">
<!-- Core Logic -->
<script src="https://unpkg.com/@ravn-ui/core/dist/ui.js"></script># Using Bun (Recommended)
bun add @ravn-ui/core
# Using NPM
npm install @ravn-ui/core<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<link rel="stylesheet" href="https://unpkg.com/@ravn-ui/core/dist/ui.css">
<link rel="stylesheet" href="https://unpkg.com/@ravn-ui/core/dist/themes.css">
</head>
<body>
<button class="btn btn-primary">Hello RAVN</button>
<script src="https://unpkg.com/@ravn-ui/core/dist/ui.js"></script>
</body>
</html>Building with an AI Agent? Use our machine-readable llms.txt for instant context.
Theming
RAVN UI is built on a robust token system. Apply themes globally via the data-theme attribute.
<!-- Apply midnight theme globally -->
<html data-theme="midnight">
...
</html>// Switch themes dynamically with persistence
RAVN.setTheme('supabase');
// Available themes:
// light, dark, claude, midnight, supabase, linear,
// zinc, forest, indigo, retro, pixel-craft, rose-pine, nordInputs
Refined data entry fields with consistent focus rings and utility states.
<div class="form-group">
<label class="label">Project Name</label>
<input type="text" class="input" placeholder="e.g. Apollo Dashboard">
<span class="helper-text">Unique name for your workspace.</span>
</div>
<!-- Error State -->
<div class="form-group">
<label class="label">Email Address</label>
<input type="email" class="input input-error" value="invalid-email">
<span class="helper-text" style="color: var(--error);">Please enter a valid email address.</span>
</div>
<!-- Success State -->
<div class="form-group">
<label class="label">Username</label>
<input type="text" class="input input-success" value="ravn_developer">
<span class="helper-text" style="color: var(--success);">Username is available!</span>
</div>
<!-- Disabled State -->
<div class="form-group">
<label class="label">API Key</label>
<input type="password" class="input" disabled value="••••••••••••••••">
<span class="helper-text">API key is disabled for this project.</span>
</div>
Cards
Modular containers designed for data density and hierarchical clarity.
Revenue Stream
Monthly recurring revenue analysis.Quick Actions
Common operations for this project.<!-- Metric Card -->
<div class="card">
<div class="card-header">
<h3>Revenue Stream</h3>
<small>Monthly recurring revenue analysis.</small>
</div>
<div class="card-content">
<div style="font-size: 1.5rem; font-weight: 700;">$14,290.00</div>
<div class="trend trend-up">↑ 12.5% from last month</div>
</div>
<div class="card-footer">
<button class="btn btn-outline btn-sm w-full">View Full Report</button>
</div>
</div>
<!-- Actions Card -->
<div class="card">
<div class="card-header">
<h3>Quick Actions</h3>
</div>
<div class="card-content flex gap-2">
<button class="btn btn-primary btn-sm">Primary</button>
<button class="btn btn-secondary btn-sm">Invite</button>
</div>
</div>
Tables
High-density data grids with refined hover states and header alignment.
| Customer | Status | Amount |
|---|---|---|
| Alex Rivera | Paid | $240.00 |
| Sarah Chen | Pending | $1,200.00 |
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>Customer</th>
<th>Status</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alex Rivera</td>
<td><span class="badge">Paid</span></td>
<td>$240.00</td>
</tr>
<tr>
<td>Sarah Chen</td>
<td><span class="badge badge-secondary">Pending</span></td>
<td>$1,200.00</td>
</tr>
</tbody>
</table>
</div>
Avatars
High-fidelity profile representation.
<!-- Simple Text -->
<div class="avatar">JD</div>
<!-- Primary Variant -->
<div class="avatar" style="background: var(--primary); color: var(--primary-foreground);">RV</div>
<!-- Image variant -->
<div class="avatar">
<img src="user.jpg" alt="Avatar">
</div>
Toggles & Status
High-fidelity binary controls and real-time state indicators.
<div class="flex items-center gap-8">
<div class="flex items-center gap-3">
<input type="checkbox" class="switch" checked>
<span class="text-sm">Push Notifications</span>
</div>
<div class="status">
<div class="status-dot status-online"></div>
System Live
</div>
</div>
Accordions
Expandable containers for hierarchical information or FAQs. Optimized for accessibility with Space/Enter trigger support.
<div class="accordion">
<div class="accordion-item">
<div class="accordion-trigger">How do I install RAVN UI?</div>
<div class="accordion-content">
You can install RAVN UI via Bun, NPM, or simply by including the CDN links in your HTML head.
</div>
</div>
<div class="accordion-item">
<div class="accordion-trigger">Is it compatible with Tailwind?</div>
<div class="accordion-content">
Yes, RAVN UI uses standard CSS variables and classes that can coexist perfectly with Tailwind.
</div>
</div>
</div>
Skeletons
Progressive loading states with smooth pulse animations.
<div class="flex items-center gap-4">
<div class="avatar skeleton"></div>
<div class="flex flex-col gap-1">
<div class="skeleton" style="width: 120px; height: 16px;"></div>
<div class="skeleton" style="width: 80px; height: 12px;"></div>
</div>
</div>
Forms
High-density form layouts for enterprise configuration.
Project Settings
Manage your workspace configuration.<div class="card">
<div class="card-header">
<h3>Project Settings</h3>
<small>Manage your workspace configuration.</small>
</div>
<div class="card-content">
<div class="form-group">
<label class="label">Organization Name</label>
<input type="text" class="input" placeholder="e.g. Acme Corp">
<span class="helper-text">This will be visible on your invoices.</span>
</div>
<div class="form-group">
<label class="label">Visibility</label>
<div class="flex items-center gap-3">
<input type="checkbox" class="switch">
<span class="text-sm">Make profile public</span>
</div>
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary w-full">Save Changes</button>
</div>
</div>
Alerts
Contextual feedback messages for user actions and system states.
<!-- Default -->
<div class="alert">
<span>Terminal access has been granted to this session.</span>
</div>
<!-- Success -->
<div class="alert alert-success">
<span>Payment processed successfully. Transaction ID: #8291.</span>
</div>
<!-- Error -->
<div class="alert alert-error">
<span>Failed to sync with the database. Please check your connection.</span>
</div>
Modals
High-fidelity dialogs for critical actions and focused tasks.
<!-- Trigger -->
<button class="btn btn-primary" data-modal-target="demo-modal">Launch Modal</button>
<!-- Modal Structure -->
<div id="demo-modal" class="modal">
<div class="modal-backdrop"></div>
<div class="modal-content">
<h3 style="margin-bottom: var(--space-2);">Confirm Deletion</h3>
<p style="color: var(--muted-foreground); margin-bottom: var(--space-8);">
Are you sure you want to delete this project? This action cannot be undone.
</p>
<div class="flex justify-end gap-2">
<button class="btn btn-ghost" data-modal-close>Cancel</button>
<button class="btn btn-primary" style="background: var(--error);">Delete Project</button>
</div>
</div>
</div>
Dropdowns
Contextual menus for actions and navigation.
<div class="dropdown">
<button class="btn btn-outline" data-dropdown>Actions</button>
<div class="dropdown-menu">
<button class="dropdown-item">Edit Profile</button>
<button class="dropdown-item">Project Settings</button>
<div class="divider"></div>
<button class="dropdown-item" style="color: var(--error);">Delete Account</button>
</div>
</div>
Progress
Visual indicators for task completion and capacity.
<div class="progress">
<div class="progress-bar" style="width: 75%;"></div>
</div>
<!-- Colored variant -->
<div class="progress">
<div class="progress-bar" style="width: 99%; background: var(--success);"></div>
</div>
Tooltips
Zero-JS contextual information on hover.
<!-- Basic Text -->
<span data-tooltip="This is a top tooltip">Hover me</span>
<!-- On a button -->
<button class="btn btn-primary" data-tooltip="Saves your changes">Save Changes</button>
Dashboard Patterns
High-density SaaS layout patterns for complex data interfaces.
Recent Transactions
| Customer | Status | Amount |
|---|---|---|
| Alex Rivera | Paid | $240.00 |
| Sarah Chen | Pending | $1,200.00 |
<!-- Dashboard Shell -->
<div style="display: flex; height: 500px; border: 1px solid var(--border);">
<!-- Sidebar -->
<aside class="sidebar" style="width: 200px; border-right: 1px solid var(--border);">
<nav class="sidebar-nav">
<a href="#" class="sidebar-item active">Overview</a>
<a href="#" class="sidebar-item">Analytics</a>
</nav>
</aside>
<!-- Main Content -->
<main style="flex: 1; display: flex; flex-direction: column;">
<header style="height: 56px; border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 var(--space-6);">
<div class="breadcrumbs">
<a href="#" class="breadcrumb-item">Project</a>
<span class="breadcrumb-item active">Overview</span>
</div>
</header>
<div style="padding: var(--space-6);">
<!-- Metrics Grid -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4);">
<div class="card" style="padding: var(--space-4);">
<div style="font-size: 0.7rem; color: var(--muted-foreground);">Total Revenue</div>
<div style="font-size: 1.5rem; font-weight: 700;">$45,231.89</div>
<div class="trend trend-up">↑ 20.1%</div>
</div>
<!-- Add more cards... -->
</div>
</div>
</main>
</div>
Core API Reference
RAVN UI ships with a lightweight, framework-agnostic runtime exposed globally under window.RAVN.
RAVN.store
A simple global state management system. No Redux, no context API.
// Set state
RAVN.store.set('todos', [{ id: 1, text: 'Ship faster' }]);
// Get state
const todos = RAVN.store.get('todos');
// Subscribe to changes
const unsubscribe = RAVN.store.subscribe((key, val, state) => {
if (key === 'todos') console.log('Todos updated!', val);
});
RAVN.route(path)
Built-in router for SPA applications. Automatically toggles data-route blocks and pushes history state.
// Navigate to a view
RAVN.route('dashboard');
// Run a hook when a view loads
RAVN.onViewEnter('dashboard', () => {
fetchAnalytics();
});
RAVN.on(event, selector, handler)
High-performance event delegation. Stop writing inline onclick attributes.
RAVN.on('click', '[data-action="delete"]', (event, target) => {
const id = target.getAttribute('data-id');
deleteItem(id);
});
RAVN.fetch(url, options)
Minimal wrapper over the native fetch API that assumes JSON payloads.
const user = await RAVN.fetch('/api/user', {
method: 'POST',
body: JSON.stringify({ name: 'John' })
});
Golden Patterns
Adhere to these rules to maintain an elite, fast, and scalable codebase without relying on a VDOM framework.
✅ DO: Micro Components
Write pure functions that take data and return HTML strings. Compose them like React.
function Card(title, content) {
return `
<div class="card p-4">
<h3>${title}</h3>
<div>${content}</div>
</div>
`;
}
❌ DON'T: Inline Handlers
Never use onclick="..." in your HTML string components. It breaks CSP and makes code hard to test.
// BAD
return `<button onclick="save()">Save</button>`;
// GOOD
return `<button data-action="save">Save</button>`;
// Handled by RAVN.on('click', '[data-action="save"]', ...)
The Standard Render Cycle
Use a single entry point for rendering your views to keep state predictable.
function renderTodos() {
const list = document.getElementById('todo-list');
if (!list) return;
const todos = RAVN.store.get('todos') || [];
list.innerHTML = todos.map(t => TodoItem(t)).join('');
}
// Re-render when state changes
RAVN.store.subscribe((key) => {
if (key === 'todos') renderTodos();
});
Examples
Drop these copy-paste snippets into your app to build complex layouts in minutes.
Vanilla Todo App
// Component
function TodoItem(item) {
return `
<div class="flex items-center justify-between p-3 border-b">
<span class="${item.done ? 'text-muted-foreground line-through' : ''}">${item.text}</span>
<button class="btn btn-ghost btn-sm text-error" data-action="delete-todo" data-id="${item.id}">×</button>
</div>`;
}
// Logic
document.addEventListener('DOMContentLoaded', () => {
RAVN.store.set('todos', [{ id: 1, text: 'Learn RAVN', done: false }]);
RAVN.on('click', '[data-action="add-todo"]', () => {
const input = document.getElementById('new-todo');
const todos = RAVN.store.get('todos');
RAVN.store.set('todos', [...todos, { id: Date.now(), text: input.value, done: false }]);
input.value = '';
});
RAVN.on('click', '[data-action="delete-todo"]', (e, el) => {
const id = parseInt(el.getAttribute('data-id'));
const todos = RAVN.store.get('todos');
RAVN.store.set('todos', todos.filter(t => t.id !== id));
});
RAVN.store.subscribe((key) => {
if (key === 'todos') {
document.getElementById('todo-list').innerHTML =
RAVN.store.get('todos').map(TodoItem).join('');
}
});
});
RAVN