Kwirth's look and feel is fully pluggable. Install themes to change the visual identity of the entire shell, or swap the homepage for one that shows exactly the cluster data you care about.
A theme is a self-contained package — a React component plus a manifest — that overrides the colour palette, typography, and component styling of the entire Kwirth shell. Themes are installed, switched, and removed at runtime with no pod restart.
Open the global menu (top-right) → Themes. The ThemeManager dialog lists all installed themes with a live preview chip. Click the radio button next to a theme and the shell repaints instantly — no page reload, no connection interruption.
The homepage is the first thing you see after login. It is a pluggable React component that receives live cluster data, event streams, and metrics as props — you decide what to show and how.
A theme package contains two files: a manifest and a React component. The component receives a ThemeProvider children prop and wraps it with any MUI or custom style overrides you need.
Add a package.json with kwirth.type = "theme" and a unique kwirth.id.
Export a default React component that satisfies ITheme. Wrap children with an MUI ThemeProvider using your custom palette.
Run npm pack to produce a .tgz. Upload it through the ThemeManager dialog — Kwirth hot-loads it immediately.
// package.json (excerpt) { "name": "my-theme", "kwirth": { "type": "theme", "id": "my-theme", "displayName": "My Theme" } } // src/index.tsx import { createTheme, ThemeProvider } from '@mui/material' import { IThemeProps } from '@kwirthmagnify/kwirth-common-front' const theme = createTheme({ palette: { mode: 'dark', primary: { main: '#your-accent-color' }, } }) export default function MyTheme({ children }: IThemeProps) { return <ThemeProvider theme={theme}>{children}</ThemeProvider> }
A homepage package exports a React component that receives clusters, live metrics, event helpers, and navigation callbacks as props via IHomepageProps. The Kwirth shell handles authentication, data fetching, and prop injection — your component just renders.
Add a package.json with kwirth.type = "homepage" and a unique kwirth.id.
Export a default React component typed as FC<IHomepageProps>. Use props.getClusterMetrics() and props.getClusterEvents() for live data.
Run npm pack and upload the .tgz via the Homepage section of the Kwirth settings panel.
// src/index.tsx import { FC, useEffect, useState } from 'react' import { IHomepageProps, IClusterEvent } from '@kwirthmagnify/kwirth-common-front' const MyHomepage: FC<IHomepageProps> = (props) => { const [metrics, setMetrics] = useState<any>({}) useEffect(() => { props.clusters.forEach(async (c) => { const m = await props.getClusterMetrics?.(c.name) if (m) setMetrics(prev => ({...prev, [c.name]: m})) }) }, [props.clusters]) return ( <div> {props.clusters.map(c => ( <div key={c.name}> <h2>{c.name}</h2> <p>CPU: {metrics[c.name]?.cpu ?? '--'}%</p> </div> ))} </div> ) } export default MyHomepage
clusters — array of connected cluster objects including URL, access string and kwirthDatafrontChannels — Map of installed channel constructors, for rendering channel icons or launching channelsgetClusterMetrics(name) — async, returns CPU%, MEM%, POD%, vCPUs, total RAM, pod countsgetClusterEvents(name, limit?) — async, returns last N cluster events with time, type, reason, messagelastTabs / favTabs — recently used and favourited tabs for restore shortcutsisExtensionLicensed(type, id) — check whether a specific extension is licensed for this instance