ObsidianUI: React Components & Animated UI Blocks

Create dashboards, landing pages, and animated product UI with 52 UI components and 22 blocks.

ObsidianUI is a React and Tailwind CSS component library for building animated websites and dashboard UIs.

You can start with a ready-made dashboard layout, add interactive galleries to a portfolio, or build account settings with device sign-out controls.

The shadcn CLI installs the selected components as editable files in your project.

Features

  • 50+ reusable UI components and 20+ blocks.
  • Component-specific styles and utility files that you can edit locally.
  • GSAP-based image and text effects, Motion animations, and Three.js graphics.
  • Resizable dashboard navigation, responsive drawer, tabs, menus, and toolbar controls.
  • Device-session management UI with loading, sign-out, and error states.
  • Component-level CSS variables for colors and styling.

Available Components

Blocks

CategoryBlocks
Buttons and pointer effectsClick Spark, Interactive Hover Button, Liquid Metal, Playground Button
Navigation and layoutFooter, Playground Navbar, Sidebar Stackbits
Forms and contentFile Input, Skeumorphic Music Card, Visitor Count
ScrollingSmooth Scroll

UI Components

CategoryComponents
Forms and inputsButton, Button Group, Calendar, Checkbox, Field, Form, Input, Input Group, Input OTP, Label, Radio Group, Select, Slider, Switch, Textarea, Toggle, Toggle Group
NavigationBreadcrumb, Command, Menubar, Navigation Menu, Pagination, Sidebar, Tabs
Menus and overlaysContext Menu, Dialog, Drawer, Dropdown Menu, Hover Card, Popover, Sheet, Tooltip
Layout and contentAvatar, Card, Carousel, Chart, Collapsible, Empty, Item, Resizable, Scroll Area, Separator, Table
FeedbackAlert, Badge, Kbd, Gooey Blob Loaders, Progress, Raised Button, Skeleton, Sonner, Spinner

How to Use ObsidianUI

1. Set Up shadcn/ui

In an existing React or Next.js project with Tailwind CSS, run the initializer if you do not already have components.json:

npx shadcn@latest init

For a new Next.js App Router project, use:

npx create-next-app@latest workspace-demo --typescript --tailwind --eslint --app --src-dir --import-alias '@/*'
cd workspace-demo
npx shadcn@latest init

2. Install Discover Button

npx shadcn@latest add "https://www.obsidianui.dev/r/discover-button.json"

3. Basic Usage

Discover Button accepts href for links, onClick for button actions, and label for text. Import it in src/app/page.tsx:

import { DiscoverButton } from "@/components/block/discover-button";
export default function HomePage() {
  return (
    <main className="mx-auto max-w-5xl px-6 py-20">
      <h1 className="mb-8 text-4xl font-semibold">Explore our products</h1>
      <DiscoverButton href="/products" label="View Products" />
    </main>
  );
}

Example: Build an Admin Dashboard

Install Dashboard Shell:

npx shadcn@latest add "https://www.obsidianui.dev/r/dashboard-shell.json"

Create src/app/dashboard/page.tsx as a Client Component because the navigation object passes React icon components. Give the wrapper a height so the dashboard fills the viewport.

"use client";
import { LayoutDashboard, Settings } from "lucide-react";
import { DashboardShell } from "@/components/block/dashboard-shell";
const navigation = [
  {
    id: "workspace",
    title: "Workspace",
    items: [
      { id: "overview", label: "Overview", icon: LayoutDashboard, href: "/dashboard" },
      { id: "settings", label: "Settings", icon: Settings, href: "/dashboard/settings" },
    ],
  },
];
export default function DashboardPage() {
  return (
    <div className="h-dvh">
      <DashboardShell
        brand={{ name: "Northstar" }}
        navigation={navigation}
        defaultActiveItemId="overview"
        title="Overview"
      >
        <section className="p-6">
          <h2 className="text-xl font-semibold">Workspace activity</h2>
          <p className="mt-2 text-sm text-muted-foreground">
            Review activity and manage team settings.
          </p>
        </section>
      </DashboardShell>
    </div>
  );
}

Dashboard Shell Props

The sidebar collapses into a drawer when the dashboard container is narrower than 672px. Items with href navigate to another page. Items with no href update the selected navigation item.

PropPurpose
brand, navigation, titleBrand information, sidebar sections, and page heading.
activeItemId, onActiveItemChangeControlled navigation selection.
defaultActiveItemIdInitial selection when the parent does not control it.
tabs, tab, onTabChangeTabs and selected-tab state.
filters, toolbarActionsContent for the two sides of the toolbar.
sidebarWidth, onSidebarWidthChangeControlled sidebar width in pixels.
defaultSidebarWidthInitial sidebar width. Default: 200.
minSidebarWidth, maxSidebarWidthResize limits. Defaults: 180 and 400.

Example: Manage Active Sessions

Install Active Sessions for an account settings page. Your backend must revoke the real session:

npx shadcn@latest add "https://www.obsidianui.dev/r/active-sessions.json"

The component handles pending requests and errors after calling your DELETE /api/sessions/:id endpoint. Create src/app/settings/sessions/page.tsx:

"use client";
import {
  ActiveSessions,
  type ActiveSession,
} from "@/components/block/active-sessions";
const initialSessions: ActiveSession[] = [
  {
    id: "current-browser",
    device: "laptop",
    browser: "Chrome",
    os: "macOS",
    lastActiveAt: new Date(),
    current: true,
  },
  {
    id: "tablet-login",
    device: "tablet",
    browser: "Safari",
    os: "iPadOS",
    lastActiveAt: "2026-10-08T16:00:00Z",
  },
];
export default function SessionSettingsPage() {
  return (
    <main className="mx-auto max-w-3xl p-6">
      <ActiveSessions
        defaultSessions={initialSessions}
        onRevoke={async (session) => {
          const response = await fetch(
            `/api/sessions/${encodeURIComponent(session.id)}`,
            { method: "DELETE" },
          );
          if (!response.ok) throw new Error("Session revocation failed");
        }}
      />
    </main>
  );
}

Active Sessions Props

Each session needs an id, a device type (desktop, laptop, phone, or tablet), and lastActiveAt. Use current: true for the current login. That row stays at the top and cannot be signed out through the list.

PropPurpose
defaultSessionsInitial sessions managed inside the component.
sessions, onSessionsChangeControlled sessions and list updates.
onRevokeAsync or synchronous callback for signing out one session.
onRevokeOthersCallback for signing out other sessions. Falls back to onRevoke for each session.
loadingSkeleton state while session data loads.
activeWithinMinutes used to determine the active-now label.
localeLocale for date formatting.

Optional Registry Namespace

For repeated installs, configure @obsidian in the registries section of components.json:

{
  "registries": {
    "@obsidian": "https://www.obsidianui.dev/r/{name}.json"
  }
}

Install File Input through the registry namespace:

npx shadcn@latest add @obsidian/file-input

Alternatives and Related Resources

Atharvsinh Jadav

Atharvsinh Jadav

Founder of CognixAI Ambassador Factory-AI

Leave a Reply

Your email address will not be published. Required fields are marked *