openstatus logoDashboard

Create Your Own Status Page Theme

Prerequisitesa GitHub account, Node.js and pnpm installed, basic familiarity with CSS custom properties

Community themes let you restyle a status page with your own colors and design — and once merged, everyone can pick your theme from the theme explorer. This guide walks you through designing a palette, testing it locally, and opening a pull request.

Themes are contributed through GitHub. We keep them in version control so every theme stays reviewable, accessible, and consistent across the platform.

Tip

If you use AI agents, install the openstatus-theme skill with npx skills add openstatushq/skills --skill openstatus-theme for guided help through palette design, accessibility checks, file scaffolding, and PR submission.

Two ways to build a theme

Visual builder

Configure a palette at themes.openstatus.dev and copy the generated configuration. Fastest way to get a starting point.

Local development

Run the status page app locally and iterate against real, seeded content. Best for fine-tuning and final testing.

Most contributors start in the builder, then test locally before submitting.

1. Run the project locally

Fork the openstatus repository to your GitHub account, then follow the Getting Started steps. From the repository root, start the status page app:

pnpm dev:status-page

Then open one of:

A configuration button in the bottom-right corner gives you access to settings, including the community theme switcher.

2. Create your theme file

Theme files live in packages/theme-store/src. Create a new TypeScript file there (for example my-theme.ts). The easiest start is to copy an existing theme such as github.ts and edit the values.

3. Define your theme

Export a constant that satisfies the Theme interface. Each theme has an id, a display name, an author, and light / dark color maps:

import type { Theme } from "./types";

export const MY_THEME = {
  id: "my-theme", // unique, kebab-case
  name: "My Awesome Theme", // display name
  author: {
    name: "@yourusername",
    url: "https://github.com/yourusername", // website or social link
  },
  light: {
    "--background": "oklch(100% 0 0)",
    "--foreground": "oklch(20% 0 0)",
    "--success": "oklch(60.81% 0.1567 142.5)", // operational
    "--destructive": "oklch(58.79% 0.1577 22.18)", // outage
    // ...more variables
  },
  dark: {
    "--background": "oklch(10% 0 0)",
    "--foreground": "oklch(90% 0 0)",
    // ...more variables
  },
} as const satisfies Theme;

Note

You don't need to set every variable. Anything you leave out falls back to the default openstatus theme, so you can override only the colors that matter for your design.

Status colors

These four drive the meaning of a status page, so set them deliberately and make sure they're distinguishable:

VariableMeaning
--successresolved / operational (green)
--warningidentified / degraded (yellow)
--infomonitoring / maintenance (blue)
--destructiveinvestigating / outage / error (red)

The remaining variables follow the shadcn/ui naming convention — --background, --foreground, --primary, --secondary, --accent, --muted, --border, --input, --ring, the --chart-* series, and more. The complete list lives in packages/theme-store/src/types.ts as THEME_VAR_NAMES.

What about the --rainbow-* variables?

The --rainbow-1 through --rainbow-17 variables color the per-region series in the public monitor charts. They're optional — if you skip them, the defaults apply.

4. Register your theme

Add your theme to the THEMES_LIST array in packages/theme-store/src/index.ts. Keep the list ordered:

const THEMES_LIST = [
  OPENSTATUS_THEME,
  OPENSTATUS_ROUNDED_THEME,
  // ...
  MY_THEME,
] satisfies Theme[];

Theme IDs are validated at runtime to be unique, so a duplicate id will throw — pick something descriptive.

5. Test your theme

Before submitting, verify the theme against a real page:

  1. Apply it on a status page via the configuration button.
  2. Confirm both light and dark modes look correct.
  3. Check contrast with your browser dev tools.
  4. Make sure every status indicator (operational, degraded, monitoring, outage) is clearly distinguishable.

Tip

To preview themes outside local development, run sessionStorage.setItem("community-theme", "true") in the browser console. A floating button appears that lets you switch between themes and light/dark mode.

6. Submit a pull request

Open a pull request against the openstatus repository with your new theme file and the index.ts change. We'll review it for design consistency and accessibility.

Design guidelines

  • Use OKLCH for better perceptual uniformity — though any valid CSS color is supported.
  • Support both modes. A theme must define a coherent light and dark variant.
  • Meet WCAG contrast guidelines. Test readability in both modes.
  • Keep it cohesive. All components should feel like one design.
  • No "Christmas tree." Avoid overly colorful or distracting palettes.

What you've accomplished

  • Designed a light and dark color palette
  • Created and registered a theme in the theme store
  • Tested it against a real status page in both modes
  • Opened a pull request to share it with the community

What's next

Questions?

Need help building a theme? Open an issue, join our Discord, or reach out to the openstatus community.