Skip to main content

Overview

Widgets are the building blocks of the Radarboard dashboard. They display data from integrations in a 3x3 grid, with optional expanded views. Each widget lives under widgets/ and uses a template recipe system — you declare layouts as data structures, not JSX.

Prerequisites

  • Radarboard dev environment set up (Setup Guide)
  • At least one integration configured (widgets consume integration data)
  • Familiarity with React and TypeScript

Step 1: Scaffold

This creates widgets/my-widget/ with all boilerplate, registers it in radarboard.config.ts, and runs pnpm install.

Step 2: Define the Recipe

Edit index.ts to set your layout. The recipe system lets you compose widgets from primitives:

Recipe Kinds

Section Types

Step 3: Wire Up Data

Define types (types.ts)

Create the hook (hooks/use-my-widget.ts)

Connect to the template (data-resolver.tsx)

Step 4: Configure the Descriptor

Capability Governance

Use capabilities to describe widget ownership of shared product surfaces.
  • role: "canonical" means this is the primary Radarboard widget for that capability.
  • role: "specialized" means the widget intentionally overlaps an existing capability but is not the main shared surface.
  • providers must point at real integration/action pairs.
  • requiredIntegrations is still useful for availability filtering, but it does not define ownership.
When a new provider overlaps an existing canonical widget, prefer updating that widget’s provider list and runtime selection instead of creating a second widget for the same capability.

Step 5: Test

Run conformance tests:
pnpm check:extensions now audits capability governance. It fails on invalid provider references or duplicate canonical widgets, and warns when integrations and canonical widgets drift apart.

Adding Variants

Offer different views of the same widget that users can switch between:

Expanded Views

The compact component renders in the grid card. The expanded component renders in a larger overlay when the user clicks expand. Both receive the same props:

Data Flow

Module Boundaries

Widgets can only import from:
  • @radarboard/widget-sdk
  • @radarboard/widget-engine
  • @radarboard/types
  • @radarboard/utils
  • @radarboard/ui
  • @radarboard/charts
  • @radarboard/hooks
  • @radarboard/assistant-ui

Reference

  • Widget system deep dive: Widget System
  • Composition patterns: Widget Composition Reference
  • SDK types: @radarboard/widget-sdk — WidgetDescriptor, WidgetRenderProps
  • Capability-backed examples: widgets/revenue/, widgets/raindrop/, widgets/stars/
  • Recipes: @radarboard/widget-sdk/recipes — layout factory functions
  • Real examples: widgets/github-activity/, widgets/revenue/, widgets/analytics/
  • Extension rules: CONTRIBUTING-EXTENSIONS.md