Scaffold a Dashfy dashboard with React Router, or add Dashfy to an existing React Router app.
Dashfy runs the React Router app in SPA mode (the dashboard UI is client-only) plus a separate Dashfy Node server that streams data over Socket.IO.
Scaffold a ready-to-run React Router project from the terminal.
Add Dashfy manually to an app you already created.
Use the CLI
Create a new app
Scaffold the minimal React Router starter. You will be prompted to choose extensions, which Dashfy sets up for you:
pnpm dlx dashfy@latest init -t react-router-starterPrefer the full, pre-configured demo? Use the
react-router-app template instead:
pnpm dlx dashfy@latest init -t react-router-appInstall dependencies
If you scaffolded with --no-install, install dependencies inside the new project
directory (cd my-dashfy-app):
pnpm installStart developing
Run the React Router app and the Dashfy server together:
pnpm run dev:allOpen http://localhost:3000 to see your dashboard. The Dashfy server runs on http://localhost:5001.
Existing project
Install Dashfy
Add the Dashfy runtime packages:
pnpm add @dashfy/server @dashfy/uiAnd the dev tooling used to run the server:
pnpm add -D tsx dotenv-cli concurrentlyEnable SPA mode
The Dashfy UI is client-only, so disable SSR in react-router.config.ts:
import type { Config } from '@react-router/dev/config'
export default {
// SPA mode: the Dashfy UI is client-only and talks to a separate Node server.
ssr: false,
} satisfies ConfigAdd a HydrateFallback to app/root.tsx so nothing renders during prerender:
// SPA mode: render nothing during prerender; the client hydrates the dashboard.
export function HydrateFallback() {
return null
}Create the Dashfy server
Add a dashfy.server.ts file at the project root. It loads your dashboard
configuration and starts the Dashfy backend:
import { Dashfy } from '@dashfy/server'
const dashfy = new Dashfy()
await dashfy.configureFromFile('./dashfy.config.yml')
await dashfy.start()Create the dashboard config
Add a dashfy.config.yml file at the project root. This is where you arrange
dashboards and widgets:
port: 5001
apis:
pollInterval: 300000
dashboards:
- title: Dashfy Dashboard
columns: 1
rows: 1
widgets:
- extension: dashfy
widget: Inspector
x: 0
y: 0
columns: 1
rows: 1Create the Dashfy app component
Create app/components/DashfyApp.tsx:
import '@dashfy/ui/styles.css'
import { Dashfy, ThemeRegistry } from '@dashfy/ui'
ThemeRegistry.loadAllThemes()
export default function DashfyApp() {
return <Dashfy />
}Render it from your index route (app/routes/home.tsx):
import DashfyApp from '~/components/DashfyApp'
export function meta() {
return [{ title: 'Dashfy' }]
}
export default function Home() {
return <DashfyApp />
}Proxy the config endpoint
The UI reads its configuration from /config. Proxy it to the Dashfy server in
vite.config.ts:
import { reactRouter } from '@react-router/dev/vite'
import { defineConfig } from 'vite'
export default defineConfig({
resolve: { tsconfigPaths: true },
server: {
port: 3000,
proxy: {
'/config': 'http://localhost:5001',
},
},
plugins: [reactRouter()],
})Add scripts and environment
Add the dev scripts to package.json so the app and server run together, and
create a .env file for extension secrets:
{
"scripts": {
"dev": "react-router dev",
"dev:server": "dotenv -e .env -- tsx watch dashfy.server.ts",
"dev:all": "concurrently \"pnpm dev:server\" \"pnpm dev\""
}
}Add dashfy.json
Add a dashfy.json at the project root so the CLI knows where to apply changes
when you run dashfy add:
{
"$schema": "https://dashfy.dev/schema.json",
"registries": {},
"paths": {
"app": "app/components/DashfyApp.tsx",
"server": "dashfy.server.ts",
"config": "dashfy.config.yml",
"env": ".env"
}
}Start developing
Run everything together and open http://localhost:3000:
pnpm run dev:allAdd extensions
With dashfy.json in place, add extensions (widgets + data sources) from the
registry. The CLI installs the package and sets it up in
app/components/DashfyApp.tsx, dashfy.server.ts, dashfy.config.yml, and .env:
pnpm dlx dashfy@latest add @dashfy/githubSee Extensions and the CLI reference for details.