Get started
Install the free tier in two commands, connect your agent, and add Pro or Premium items with your licence key when you need them.
01Install the free tier
In a React 19 app with Tailwind 4 (Next.js or Vite).
initadds the@candorregistry tocomponents.json, installs the theme and imports it after Tailwind. In a project without shadcn yet it sets shadcn up first;--yesanswers its questions (Radix, the nova preset) for CI or a coding agent.Set up CandorAdd the chat core02Render it
Put this in a page (
app/page.tsxin Next.js) to see a working chat with a canned reply. The imports are whereaddput the files:@/components/…and@/lib/….TSX · app/page.tsx "use client" import * as React from "react" import { Composer } from "@/components/composer" import { Message } from "@/components/message" import { Thread } from "@/components/thread" import type { Message as MessageData } from "@/lib/chat" const agent = { id: "a1", name: "Support agent", role: "assistant" } const line = (i: number): MessageData => ({ id: `h${i}`, author: i % 2 ? { role: "agent", agent } : { role: "user" }, status: "complete", blocks: [{ kind: "paragraph", nodes: [{ kind: "text", text: i % 2 ? `Order ${1000 + i} shipped on Tuesday.` : `Where is order ${1001 + i}?` }] }], }) const history = Array.from({ length: 600 }, (_, i) => line(i)) export default function Example() { const [value, setValue] = React.useState("") const [messages, setMessages] = React.useState<MessageData[]>([]) const [long, setLong] = React.useState(false) const shown = long ? [...history, ...messages] : messages const send = (text: string) => { setMessages((m) => [ ...m, { id: `u${m.length}`, author: { role: "user" }, status: "complete", blocks: [{ kind: "paragraph", nodes: [{ kind: "text", text }] }] }, { id: `a${m.length}`, author: { role: "agent", agent }, status: "complete", blocks: [{ kind: "paragraph", nodes: [{ kind: "text", text: "Got it. I’ll look into that." }] }] }, ]) setValue("") } return ( <div className="flex flex-col gap-2"> <label className="flex items-center gap-1.5 text-xs text-muted-foreground"> <input type="checkbox" checked={long} onChange={(e) => setLong(e.target.checked)} /> A history of 600 messages, virtualised </label> <div className="h-80 overflow-hidden rounded-lg border"> <Thread className="h-full" // virtualize renders only the messages in or near view; each child needs a key. virtualize={long} empty={<p className="text-sm text-muted-foreground">Ask about an order to start.</p>} footer={<Composer value={value} onChange={setValue} onSubmit={send} placeholder="Ask about an order" />} > {shown.length ? shown.map((m) => <Message key={m.id} message={m} />) : null} </Thread> </div> </div> ) }03Connect your agent
Candor's components take plain data, so they work with any backend. The adapters turn an SDK's messages into that data: the Vercel AI SDK (
useCandorChat), the Claude Agent SDK (useClaudeAgent) and AG-UI (useAgUi). They're free.Add an adapter04Or start from a working app
The starter is a Next.js app with an agent chat built from the free items, for the AI SDK and the Claude Agent SDK. It needs an Anthropic API key to run.
Copy the starter06Keep it up to date
addrecords each item incandor-lock.json: the version it came from and a hash of each file as it was installed. Commit it.updatecompares each file with that hash: one you haven't touched is replaced with the new version; one you changed gets a three-way merge, with conflict markers (<<<<<<<) only where your edit and the new version touch the same lines.--dry-runsays what would change and writes nothing;--to <version>picks a version; items installed before the lockfile need--from <the version you installed>. If you moved a file,updatefinds it when it's still as installed, or you say where with--moved <installed path>=<where it is now>; the lockfile remembers, even for an item already at the latest version. An item with a file it can't find stays at its old version until the file is found.See what an update would changeUpdate installed itemsUpdate a moved themeSee:Changelog
07Check it in CI
verifycheckscandor-lock.jsonagainst the registry's versioned snapshots and the files in your repository, without running shadcn: every recorded item exists at its version, and every file is there. Files you've changed since install are listed, not failed. It exits 1 on anything missing or unknown. Paid items needCANDOR_LICENSE_KEYset as a CI secret.Verify the lockfile08With a coding agent
The docs MCP server lets Claude Code, Cursor, VS Code and other agents search these docs, read any page and pick components for a task while they work. It's free and read-only: no licence key, and it serves docs, never paid source. For other clients, add
https://candor.themethodic.com/mcpas a remote (streamable HTTP) server; the setup guides have each tool's own config. The skill teaches which component fits which job and the rules the kit keeps. Every docs page is also Markdown at the same address plus.md, listed in llms.txt.Add the docs MCP server to Claude CodeInstall the skill09If something looks wrong
doctorchecks the registry, your key, the theme import, React and Tailwind versions, and says how to fix each. Premium and Team include email support at info@themethodic.com.Check the setup