Contributing
@cloudflare/kumo

Repository Contribution Workflow

Useful commands for developing Kumo (run from repository root):

  • Build everything once: pnpm i; pnpm build
  • Use watch mode while developing: pnpm dev
  • Before opening a PR, add a changeset: pnpm changeset
  • Do not squash commits after review feedback starts.

Before Getting Started

For non-trivial changes, engage on an issue first (or open a discussion or feature request) before writing code. For trivial changes, opening a PR directly is fine.

Set Up Your Environment

  • Install the latest LTS version of Node.js (we recommend a version manager like nvm).
  • Install a code editor (we recommend VS Code) and project-recommended extensions.
  • Install git.
  • Install dependencies from the repository root with pnpm install.

Fork and Clone

External contributors should fork first and add cloudflare/kumo as upstream. Cloudflare employees can clone the main repository directly.

# External contributors
git clone https://github.com/<your-github-username>/kumo
cd kumo
git remote add upstream https://github.com/cloudflare/kumo

# Keep your local main current
git switch main
git pull upstream main

# Cloudflare employees can clone directly
git clone https://github.com/cloudflare/kumo.git

Create and Push Your Branch

git switch main
git pull upstream main
git checkout -b <new-branch-name> main

git add <paths-to-changed-files>
git commit
git push -u origin <new-branch-name>

Quality Checks Before PR

Run the same core checks from CONTRIBUTING.md before opening or updating a PR.

pnpm run typecheck
pnpm run lint
pnpm run format
pnpm run test

If you recently rebased on main, run pnpm i first.

PR Expectations

  • PR title format: [package name] description
  • Fill out the full PR template with implementation details.
  • Keep commit history clean before first review; after review starts, address feedback in follow-up commits instead of force-pushing rewrites.
  • Include tests for new behavior.

PRs, Changesets, and Releases

PR Review and Previews

  • PR review is required for all changes.
  • Every PR has package pre-release links via pkg.pr.new in an automated PR comment.

Changesets

Every non-trivial change that should appear in changelogs needs a changeset.

pnpm changeset
git add .changeset/*.md

See .changeset/README.md for detailed guidance.

Styleguide

Follow STYLEGUIDE.md to keep contributions consistent.

Release Process

Kumo releases are typically cut on weekdays. For out-of-band releases, contact the kumo-maintainers team.

  1. Merged changesets on main cause the Changesets bot to open or update a Version Packages PR.
  2. That PR bumps versions and aggregates changelog entries.
  3. Maintainers merge that PR to trigger publication to npm.

Creating New Components

Kumo includes a scaffolding tool that automates component creation. This ensures all components follow the same structure and are properly configured.

Run the Scaffolding Tool

From the workspace root, run:

pnpm --filter @cloudflare/kumo new-component

What the Scaffolding Tool Does

The tool automatically creates and updates several files:

  • Component file - src/components/{name}/{name}.tsx
  • Index file - src/components/{name}/index.ts
  • Story file - src/components/{name}/{name}.stories.tsx
  • Test file - src/components/{name}/{name}.test.tsx
  • Main exports - Updates src/index.ts
  • Build config - Updates vite.config.ts
  • Package exports - Updates package.json

Example

Here's what the scaffolding process looks like:

? Component name: Alert Banner

 Component scaffolded successfully!

📁 Files created:
   - src/components/alert-banner/alert-banner.tsx
   - src/components/alert-banner/index.ts
   - src/components/alert-banner/alert-banner.stories.tsx
   - src/components/alert-banner/alert-banner.test.tsx

📝 Files updated:
   - src/index.ts
   - vite.config.ts
   - package.json

💡 Import examples:
   import { AlertBanner } from "@cloudflare/kumo";
   import { AlertBanner } from "@cloudflare/kumo/components/alert-banner";

Component Naming

The scaffolding tool handles naming automatically. You can input the name in any format:

  • Spaces - "Alert Banner" → alert-banner directory, AlertBanner component
  • PascalCase - "AlertBanner" → alert-banner directory, AlertBanner component
  • kebab-case - "alert-banner" → alert-banner directory, AlertBanner component

Creating New Blocks

Blocks are higher-level components that compose multiple base components. Use the block scaffolding tool to create them:

Run the Block Scaffolding Tool

From the workspace root, run:

pnpm --filter @cloudflare/kumo new-block

What It Creates

The block scaffolding tool creates the same structure as components, but in the src/blocks directory:

  • Block file - src/blocks/{name}/{name}.tsx
  • Index file - src/blocks/{name}/index.ts
  • Story file - src/blocks/{name}/{name}.stories.tsx
  • Test file - src/blocks/{name}/{name}.test.tsx
  • Main exports - Updates src/index.ts (Blocks section)
  • Build config - Updates vite.config.ts
  • Package exports - Updates package.json

Example

? Block name: Navigation Bar

 Block scaffolded successfully!

📁 Files created:
   - src/blocks/navigation-bar/navigation-bar.tsx
   - src/blocks/navigation-bar/index.ts
   - src/blocks/navigation-bar/navigation-bar.stories.tsx
   - src/blocks/navigation-bar/navigation-bar.test.tsx

📝 Files updated:
   - src/index.ts
   - vite.config.ts
   - package.json

💡 Import examples:
   import { NavigationBar } from "@cloudflare/kumo";
   import { NavigationBar } from "@cloudflare/kumo/blocks/navigation-bar";

Creating New Layouts

Layouts are page-level components that provide consistent structure for common page patterns. Use the layout scaffolding tool:

Run the Layout Scaffolding Tool

From the workspace root, run:

pnpm --filter @cloudflare/kumo new-layout

What It Creates

The layout scaffolding tool creates the same structure as components and blocks, but in the src/layouts directory:

  • Layout file - src/layouts/{name}/{name}.tsx
  • Index file - src/layouts/{name}/index.ts
  • Story file - src/layouts/{name}/{name}.stories.tsx
  • Test file - src/layouts/{name}/{name}.test.tsx
  • Main exports - Updates src/index.ts (Layouts section)
  • Build config - Updates vite.config.ts
  • Package exports - Updates package.json

Example

? Layout name: Dashboard Page

 Layout scaffolded successfully!

📁 Files created:
   - src/layouts/dashboard-page/dashboard-page.tsx
   - src/layouts/dashboard-page/index.ts
   - src/layouts/dashboard-page/dashboard-page.stories.tsx
   - src/layouts/dashboard-page/dashboard-page.test.tsx

📝 Files updated:
   - src/index.ts
   - vite.config.ts
   - package.json

💡 Import examples:
   import { DashboardPage } from "@cloudflare/kumo";
   import { DashboardPage } from "@cloudflare/kumo/layouts/dashboard-page";

Development Workflow

After scaffolding a component, block, or layout, use the watch build setup to develop with the documentation site:

Watch Build Setup

Run these commands in separate terminals for development with HMR:

# Terminal 1: Watch mode for kumo package
pnpm --filter @cloudflare/kumo dev

# Terminal 2: Documentation site dev server
pnpm dev
  • Fast rebuild time (~400ms)
  • Validates bundle exports/imports
  • Tests actual build output
  • See components in real documentation context

Implementation Steps

  1. Implement the component/block/layout

    Edit the generated .tsx file in the kumo package.

  2. Create demo file

    Add a {Name}Demo.tsx file in kumo-docs-astro/src/components/demos/ to showcase component variants.

  3. Write tests

    Add tests to the generated .test.tsx file. Run tests in watch mode while developing.

    pnpm --filter @cloudflare/kumo test
  4. Build the package

    Before committing, do a full production build to ensure everything works:

    pnpm --filter @cloudflare/kumo build
  5. Regenerate registry

    Update the component registry to include examples from your demo file:

    pnpm --filter @cloudflare/kumo codegen:registry
  6. Add documentation page

    Create a documentation page in kumo-docs-astro/src/pages/ showing real-world usage examples.

Testing

The test suite automatically validates your component, block, or layout configuration:

  • Main entry point exports the component/block/layout
  • Deep import paths work correctly (@cloudflare/kumo/components/*, @cloudflare/kumo/blocks/*, or @cloudflare/kumo/layouts/*)
  • Package.json exports are properly configured
  • Build configuration is correct
  • All files exist in the correct locations

Run the test suite to ensure everything is configured correctly:

pnpm --filter @cloudflare/kumo test:run

The tests will provide helpful error messages with exact code snippets if any configuration is missing.

Component Guidelines

When implementing components, follow these guidelines:

  • Accessibility - Include proper ARIA attributes and keyboard navigation
  • TypeScript - Export prop types and use proper type annotations
  • Styling - Use Tailwind CSS classes and the cn utility
  • Consistency - Follow existing component patterns and naming conventions
  • Documentation - Add clear JSDoc comments and usage examples
  • Testing - Include unit tests for component behavior
  • Single Responsibility - Keep components focused on one task

Block Guidelines

When implementing blocks, follow these additional guidelines:

  • Composition - Compose existing components rather than reimplementing functionality
  • Framework Agnostic - Use LinkProvider for routing to remain framework-agnostic
  • Flexible Props - Accept both simple and complex props to support various use cases
  • Common Patterns - Focus on patterns that appear in multiple applications
  • Documentation - Include JSDoc explaining the block's purpose and when to use it
  • Examples - Provide clear usage examples showing composition

When to Create a Block

  • Pattern appears in multiple places across applications
  • Combines 2+ base components
  • Implements a common layout or page structure
  • Has specific business logic or behavior

When NOT to Create a Block

  • Single component with styling variations (use component variants instead)
  • Application-specific logic (keep in application code)
  • One-off patterns (wait for reuse before abstracting)

Additional Resources

For more detailed information, refer to: