Dash is an Electron-based dashboard application framework built with React. It provides a Widget system with dependency injection, theming, and a provider system for managing external service integrations.
Dash enables you to:
- Build customizable dashboards with a widget-based architecture
- Create reusable widgets with hot reload support during development
- Manage external service credentials securely through the provider system
- Use dependency injection to pass context and functionality through component hierarchy
- Distribute widgets as npm packages to other Dash projects
Example dashboards you can build:
- Algolia Search Interface
- Google Drive Explorer
- Contentful Content Manager
- Slack Integration Dashboard
- AI/ChatGPT Interface
- Node.js: v18, v20, or v22 (LTS versions recommended)
- Note: Node.js v24+ has breaking changes and is not compatible
- Recommendation: Use nvm for version management
- Python 3: Required for node-gyp native module compilation
- XCode: Required for packaging Electron applications (Electron Forge)
- npm: For installing dependencies and running scripts
Dash uses the @trops/dash-react library for UI components.
Verify you have a compatible Node.js version:
node -v # Should show v18.x, v20.x, or v22.xIf needed, install/switch Node.js versions:
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.zshrc
# Install and use Node.js v20
nvm install 20
nvm use 20
nvm alias default 20-
Create a
.envfile in the project root (copy from.env.default):cp .env.default .env
-
Edit
.envand set any environment variables needed (e.g., Apple signing credentials for packaging).
npm run setupThis installs the main application and dash-react dependencies.
Start the development environment with hot reload:
npm run devThis launches:
- React dev server at http://localhost:3000 with hot module reloading
- Electron application connected to the dev server
- DevTools for debugging
Any file changes automatically reload without restarting the app.
Create an optimized production build:
npm run buildFor comprehensive guides, see docs/INDEX.md:
Getting Started:
- Quick Start - Commands, workflows, and troubleshooting
- Development Workflow - Development workflow and best practices
Core Framework (widget system, providers, MCP):
For complete widget system, provider architecture, and widget API documentation, see @trops/dash-core:
- Widget System - Architecture and how Dash works
- Widget Development - Create and test widgets
- Provider Architecture - Provider system architecture
UI Library:
- dash-react README - Component library documentation
Essential npm commands for development and distribution:
| Command | Description |
|---|---|
npm run setup |
Install dependencies and dash-react |
npm run dev |
Start dev server with hot reload and Electron |
npm run build |
Create production build |
npm run package-widgets |
Bundle widgets for distribution |
npm run package |
Create Mac .dmg distributable (requires XCode & Apple Developer account) |
npm run widgetize <WidgetName> |
Generate widget scaffold in src/Widgets |
Widgets are the core building blocks of Dash dashboards. Each widget consists of:
- Widget Component - React component that renders the widget UI
- Widget Configuration -
.dash.jsfile describing the widget metadata - Contexts (optional) - Shared state and functionality for sub-components
The easiest way to create a widget:
node ./scripts/widgetize MyWidgetThis creates:
src/Widgets/MyWidget/
├── widgets/
│ ├── MyWidget.js # Widget component
│ └── MyWidget.dash.js # Widget configuration
├── contexts/ # Optional context for DI
│ └── MyWidgetContext.js
└── index.js # Exports
The fastest way to build a Dash widget is with Claude Code. This project includes a built-in skill that guides you through the entire widget development process.
- Create a new repo — On GitHub, click Use this template → Create a new repository from trops/dash-electron
- Clone your repo —
git clone https://github.com/your-org/your-dashboard.git && cd your-dashboard - Run setup —
npm run setup - Install Claude Code — If you don't have it yet, install from claude.ai/claude-code
- Open Claude Code in your project directory and describe what you want to build:
> I want to build a widget for Slack
> Build me an Algolia search widget
> Create a widget that shows Google Drive files
The skill automatically activates and walks you through a 5-phase workflow:
- Scaffold — Generate the widget file structure
- MCP Research — Identify MCP servers and map their tools to widget features
- Build — Write the widget code with dash-react components and MCP integration
- Test — Run
npm run devand verify the widget works end-to-end - Package & Distribute — Bundle, publish to npm, and submit to the Dash Registry
The skill includes reference docs for dash-react components, widget patterns, and MCP integration — located in .claude/skills/dash-widget-builder/.
Define widget metadata and user-configurable options:
// MyWidget.dash.js
import { MyWidget } from "./MyWidget";
export default {
component: MyWidget,
canHaveChildren: false,
workspace: "my-cool-workspace-name",
type: "widget",
userConfig: {
title: {
type: "text",
defaultValue: "My Widget",
instructions: "Widget title displayed to user",
displayName: "Title",
required: true,
},
subtitle: {
type: "text",
defaultValue: "Subtitle",
displayName: "Subtitle",
},
},
};A simple widget that uses user configuration and the widget API:
// MyWidget.js
import { Widget, Panel, Heading, SubHeading } from "@trops/dash-react";
export const MyWidget = ({
title = "Hello",
subtitle = "I'm a widget",
api,
...props
}) => {
const handleSaveData = () => {
const data = { timestamp: Date.now(), title };
api.storeData(data);
};
return (
<Widget {...props}>
<Panel>
<Heading text={title} />
<SubHeading text={subtitle} />
<button onClick={handleSaveData}>Save Data</button>
</Panel>
</Widget>
);
};Widgets communicate via publish/subscribe:
// Publish an event
api.publishEvent("user-searched", { query: "my search" });Set up listeners in workspace configuration or in the widget:
// Register event listeners
api.registerListeners(
["user-searched"], // Events to listen for
{
"user-searched": (payload) => {
console.log("User searched:", payload.query);
},
}
);Store and retrieve data using the widget API:
// Store data (auto-saved to Electron app)
api.storeData({
searchHistory: ["query1", "query2"],
preferences: { theme: "dark" },
});
// Read data
api.readData({
callbackComplete: (data) => {
console.log("Loaded data:", data);
},
callbackError: (error) => {
console.error("Failed to load data:", error);
},
});Use React Context inside a widget to share functionality between its sub-components:
// MyWidgetContext.js
import { createContext } from "react";
export const MyWidgetContext = createContext({});
// MyWidget.js — Context wraps sub-components inside the widget
import { Widget, Panel } from "@trops/dash-react";
import { MyWidgetContext } from "./MyWidgetContext";
import { useGoogleMaps } from "./hooks/useGoogleMaps";
import { MapView } from "./components/MapView";
import { SearchPanel } from "./components/SearchPanel";
export const MyWidget = ({ ...props }) => {
const googleMaps = useGoogleMaps();
return (
<MyWidgetContext.Provider value={{ googleMaps }}>
<Widget {...props}>
<Panel>
<SearchPanel />
<MapView />
</Panel>
</Widget>
</MyWidgetContext.Provider>
);
};
// components/MapView.js — Sub-component consumes context
import { useContext } from "react";
import { MyWidgetContext } from "../MyWidgetContext";
export const MapView = () => {
const { googleMaps } = useContext(MyWidgetContext);
return <div>{/* Use googleMaps client */}</div>;
};The dash-react library provides UI components:
Layout Components:
Panel,DashPanel- Card/container componentsContainer,LayoutContainer- Layout helpersHeader,SubHeader,FooterMainLayout,MainSection,MainContentWidget- Widget container
Interactive Components:
Button,ButtonIcon- Action buttonsMenu,MenuItem- Menus and navigationToggle- Toggle switchesModal- Modal dialogsNotification- Alert notificationsSlidePanelOverlay- Side panel overlayTag- Labels and tags
Form & Input:
Form- Form utilitiesCodeEditor,CodeRenderer- Code input/display
Utilities:
ErrorBoundary,ErrorMessage- Error handlingText- Typography helpersDraggable- Drag-and-drop support
See dash-react documentation for full reference.
- Update
package.jsonwith widget name and version - Bundle widgets:
npm run package-widgets
- Version bump:
npm version patch
- Push to repository:
git push origin master
A GitHub workflow automatically publishes the package.
In your main Dash component, import and register external widgets:
import * as MyWidgets from "@your-org/my-widgets-package/dist";
Object.keys(MyWidgets).forEach((widgetName) => {
ComponentManager.registerWidget(MyWidgets[widgetName], widgetName);
});Create a distributable Mac application:
-
Set up Apple Developer account with code signing certificates
-
Create Application-Specific Password in Apple website
-
Install and configure XCode
-
Set environment variables in
.env -
Build the package:
npm run package
This creates an
/out/make/[YourApp].dmgfile -
Notarize with Apple (required for distribution):
npm run apple-notarize npm run apple-staple
To merge updates from the official dash-electron template:
# Add remote if not exists
git remote add template https://github.com/trops/dash-electron
# Fetch and verify
git remote -v
git fetch template
# Merge changes
git checkout master
git merge template/masterFor detailed information on advanced topics, see the documentation:
- Hot Module Reloading - See DEVELOPMENT_WORKFLOW.md
- Widget Registry - See WIDGET_REGISTRY.md
- Provider System - See PROVIDER_API_SETUP.md
- Web-based Dashboards - The @trops/dash-react package can be used in React web apps with minimal adaptation
For common issues and solutions, see QUICK_START.md.
For questions or support, please open an issue on GitHub.
Planned improvements:
- Pre-compiled dashboard configurations for distribution
- Streamlined Apple notarization process
- GitHub Actions for automated widget package creation
- Web-based (non-Electron) dashboard support
Learn more: Full Documentation Index | dash-react Library