Skip to content

Docs / Getting started

Quick start

FROM PREVIEW TO YOUR PROJECT

Your first block.

LEDGER is a collection of source files. Copy the blocks you need and edit them in your app. This guide uses Next.js App Router, TypeScript, and Tailwind CSS v4.

1. Prepare your app

Already using this stack? Skip the create command. For a new app, keep the default @/* import alias.

Terminal · new project
npx create-next-app@latest my-app --ts --tailwind --app
cd my-app

Install the icon package and the two utilities used by blocks that import cn. Each block’s Code tab lists any other dependencies.

Terminal · dependencies
npm install lucide-react clsx tailwind-merge
lib/utils.ts (or src/lib/utils.ts)
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

2. Bring the design with you

Choose a preset in the header or the design system. Copy its stylesheet into your global CSS file. In an existing app, merge the theme definitions and styles with your own CSS, keeping only one Tailwind import.

Current preset: Ledger. Both light and dark colors are included. Add the dark class to your root element to enable dark mode.

View and copy theme CSS
app/globals.css
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

@theme inline {
  --color-ledger-paper: var(--ledger-paper);
  --color-ledger-ink: var(--ledger-ink);
  --color-ledger-muted: var(--ledger-muted);
  --color-ledger-rule: var(--ledger-rule);
  --color-ledger-signal: var(--ledger-signal);
  --font-sans: var(--design-font);
  --font-mono: var(--font-geist-mono, ui-monospace), monospace;
}

:root {
  --ledger-paper: #f4f1ea;
  --ledger-ink: #171717;
  --ledger-muted: #6b645b;
  --ledger-rule: #d9d1c3;
  --ledger-signal: #c43e1c;
  --design-font: var(--font-geist-sans, ui-sans-serif), sans-serif;
  --spacing: 0.25rem;
  color-scheme: light;
}
.dark {
  --ledger-paper: #12110f;
  --ledger-ink: #ede8de;
  --ledger-muted: #9e9689;
  --ledger-rule: #2a2722;
  --ledger-signal: #e76b49;
  color-scheme: dark;
}
body {
  background: var(--ledger-paper);
  color: var(--ledger-ink);
  font-family: var(--design-font);
  -webkit-font-smoothing: antialiased;
}
* { border-radius: 0; box-shadow: none; }
:is(button, input, select, textarea, [class~="border"]) { border-radius: 0px; }

::selection { background: var(--ledger-signal); color: var(--ledger-paper); }
:focus-visible { outline: 2px solid var(--ledger-signal); outline-offset: 3px; }
.ledger-link { position: relative; display: inline-block; color: var(--ledger-ink); text-decoration: none; }
.ledger-link::after { content: ""; position: absolute; bottom: -2px; left: 0; width: 40px; height: 2px; background: var(--ledger-signal); transition: width 120ms ease-out; }
.ledger-link:hover::after, .ledger-link:focus-visible::after { width: 100%; }
.bg-grid-pattern { background-image: radial-gradient(var(--ledger-ink) 1px, transparent 1px); background-size: 24px 24px; }

For the original typography, load Geist in your root layout. The exported CSS also includes system-font fallbacks.

app/layout.tsx · fonts
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

const sans = Geist({ subsets: ["latin"], variable: "--font-geist-sans" });
const mono = Geist_Mono({ subsets: ["latin"], variable: "--font-geist-mono" });

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={`${sans.variable} ${mono.variable}`}>
      <body>{children}</body>
    </html>
  );
}

3. Copy a block and use it

Open Login, select Copy code, and save the source as components/blocks/login.tsx. Keep any "use client" directive in the source. Then import the named export:

app/page.tsx
import { Login01 } from "@/components/blocks/login";

export default function Page() {
  return <Login01 />;
}

Blocks demonstrate UI with sample data. Connect forms, links, authentication, and actions to your own application before shipping. The optional state prop lets you preview the states supported by each block.