Installation
Install Clock and configure its components, styles, and inherited Kumo compatibility namespace.
Install Clock
Clock is published by ComHora as @comhora/clock on the public npm registry. The current package version is v2.8.0.
npm
npm install @comhora/clock
pnpm
pnpm add @comhora/clock
yarn
yarn add @comhora/clock
Install the peer dependencies if your project does not already provide them:
pnpm add react react-dom @phosphor-icons/react
Import Components
Import from the main package or use a granular component path:
import { Button, Input, LayerCard } from "@comhora/clock";
import { Dialog } from "@comhora/clock/components/dialog";
Clock is built on Base UI. Advanced applications can import the re-exported unstyled primitives:
import { Accordion, Popover, Slider } from "@comhora/clock/primitives";
import { Dialog } from "@comhora/clock/primitives/dialog";
Prefer Clock’s styled components when one is available. Base UI primitives are useful when building a component that Clock does not provide or when you need lower-level behavior and styling control.
Upstream Kumo Option
Clock is an independent fork of Cloudflare Kumo. The original upstream package remains available and is a supported provenance and compatibility reference:
pnpm add @cloudflare/kumo
import { Button } from "@cloudflare/kumo";
import "@cloudflare/kumo/styles";
Choose @comhora/clock for the ComHora-maintained Clock release line. Choose @cloudflare/kumo when you specifically need Cloudflare’s upstream release line or are checking behavior against upstream. The packages have separate maintainers and release histories; use one import namespace consistently within an application.
Why Some Names Still Say Kumo
Clock deliberately preserves inherited names such as KumoPortalProvider, useKumoToastManager, KUMO_* constants, and kumo-* semantic classes. Those names are a compatibility namespace, not the current product name. Keeping them stable allows incremental migration and makes curated upstream commits easier to review.
For example, Clock package imports and inherited styling names are used together:
import { Button, KumoPortalProvider } from "@comhora/clock";
export function App() {
return (
<KumoPortalProvider>
<Button className="bg-kumo-brand text-white">Continue</Button>
</KumoPortalProvider>
);
}
Import Styles
Tailwind CSS v4
Import Clock’s theme before Tailwind and tell Tailwind to scan the package output. Import order matters.
/* app.css or main.css */
@source "../node_modules/@comhora/clock/dist/**/*.{js,jsx,ts,tsx}";
@import "@comhora/clock/styles/tailwind";
@import "tailwindcss";
Tailwind CSS v4 does not scan node_modules/ by default. Adjust the @source
path relative to your CSS file or Clock components may render with missing
utility styles.
The default @comhora/clock/styles export is equivalent to styles/tailwind.
Without Tailwind
Use the standalone stylesheet when the application does not run Tailwind:
import "@comhora/clock/styles/standalone";
Complete Example
/* app.css */
@source "../node_modules/@comhora/clock/dist/**/*.{js,jsx,ts,tsx}";
@import "@comhora/clock/styles/tailwind";
@import "tailwindcss";
import { Button, Input, LayerCard } from "@comhora/clock";
import "./app.css";
export default function App() {
return (
<LayerCard className="rounded-lg p-6">
<h1 className="mb-4 text-2xl font-bold">Welcome to Clock</h1>
<Input placeholder="Enter your name..." className="mb-4" />
<Button variant="primary">Submit</Button>
</LayerCard>
);
}
Components and Blocks
Components are versioned npm exports:
import { Button, Dialog, Input } from "@comhora/clock";
Blocks are higher-level compositions installed as source code that your application owns:
npx @comhora/clock init
npx @comhora/clock blocks
npx @comhora/clock add PageHeader
See Components vs Blocks for ownership and customization guidance.
Utilities
import { cn, LinkProvider, safeRandomId } from "@comhora/clock";
const className = cn("base-class", condition && "conditional-class");
const id = safeRandomId();
<LinkProvider component={YourAppLink}>{/* Your application */}</LinkProvider>;