Getting Started

A quick tutorial to get you up and running with Apsara.

This guide walks you through installing Apsara and building your first component.

Prerequisites

Apsara requires:

  • Node.js 22 or later
  • React 19

React and React DOM are peer dependencies. Make sure your project has them installed:

1npm install react react-dom

Installation

Install the package using your preferred package manager:

1npm install @raystack/apsara

Try a preview build

Every pull request on GitHub gets a canary build, published automatically via pkg.pr.new. This lets you try out unreleased changes before they ship to npm. The PR will have a comment with an install command, for example:

1pnpm add https://pkg.pr.new/raystack/apsara/@raystack/apsara@<pr-number>

Setup

Three steps, in order. The styles and the provider are needed once, at the root of the app.

1. Import styles

Add the CSS import at the root of your application, before any component renders:

1import "@raystack/apsara/style.css";

This single stylesheet includes all component styles and CSS custom properties (tokens) for theming.

2. Add Theme

Wrap your application with Theme to enable theming support:

1import { Theme } from "@raystack/apsara";
2
3function App() {
4 return (
5 <Theme defaultTheme="system">
6 <YourApp />
7 </Theme>
8 );
9}

The defaultTheme prop accepts "light", "dark", or "system" (follows OS preference).

3. Use components

Import and use components directly:

1import { Button, Flex, Text } from "@raystack/apsara";
2
3function Example() {
4 return (
5 <Flex direction="column" gap={4}>
6 <Text size="regular" weight="medium">Welcome to Apsara</Text>
7 <Flex gap={3}>
8 <Button variant="solid" color="accent">Primary Action</Button>
9 <Button variant="outline">Secondary</Button>
10 </Flex>
11 </Flex>
12 );
13}

Framework setup

Where the two setup steps go depends on the framework.

Next.js (App Router)

Add the provider to your root layout:

1// app/layout.tsx
2import { Theme } from "@raystack/apsara";
3import "@raystack/apsara/style.css";
4
5export default function RootLayout({ children }: { children: React.ReactNode }) {
6 return (
7 <html lang="en" suppressHydrationWarning>
8 <body>
9 <Theme defaultTheme="system">
10 {children}
11 </Theme>
12 </body>
13 </html>
14 );
15}

The suppressHydrationWarning attribute is required because Theme injects a script to prevent theme flash during hydration.

Vite

Add the provider to your main entry file:

1// main.tsx
2import React from "react";
3import ReactDOM from "react-dom/client";
4import { Theme } from "@raystack/apsara";
5import "@raystack/apsara/style.css";
6import App from "./App";
7
8ReactDOM.createRoot(document.getElementById("root")!).render(
9 <React.StrictMode>
10 <Theme defaultTheme="system">
11 <App />
12 </Theme>
13 </React.StrictMode>
14);

Optional: normalize CSS

Apsara includes an optional normalize stylesheet that keeps rendering consistent across browsers while preserving useful defaults:

1import "@raystack/apsara/normalize.css";
2import "@raystack/apsara/style.css";

Import it before the main stylesheet if you choose to use it.

Importing icons

Apsara exports a set of icons that can be imported separately:

1import { Button } from "@raystack/apsara";
2import { SearchIcon, XIcon } from "@raystack/apsara/icons";
3
4<Button leadingIcon={<SearchIcon />}>Search</Button>

Importing hooks

Utility hooks such as useCopyToClipboard, useDebouncedState, and useMouse are available from a dedicated export:

1import { Button } from "@raystack/apsara";
2import { useCopyToClipboard } from "@raystack/apsara/hooks";
3
4function CopyButton({ value }: { value: string }) {
5 const { copy } = useCopyToClipboard();
6
7 return <Button onClick={() => copy(value)}>Copy</Button>;
8}

To read or change the active theme, use useTheme from the main entry:

1import { Button, useTheme } from "@raystack/apsara";
2
3function ThemeToggle() {
4 const { resolvedTheme, setTheme } = useTheme();
5
6 return (
7 <Button onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}>
8 Toggle Theme
9 </Button>
10 );
11}

Next steps

  • Theme Overview — Configure colors, spacing, and style variants
  • Button — Start with a common component
  • DataView — Build data-rich interfaces