MEDAApache-2.0 · TypeScript-first
The UI shell Medal is built with.
Meda is the shared UI shell and runtime primitives behind Medal’s apps — navigation chrome, panels, auth controls, recipes, theme bridges, a command palette and the workbench layout. Published as @medalsocial/meda.
Install, theme, render the shell.
bashInstallpnpm add @medalsocial/meda lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities @xyflow/react
Peer dependencies
Meda expects react 19 or newer and react-dom 19 or newer, plus the required peers lucide-react, @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities and @xyflow/react in your project (next-themes, react-markdown and @react-three/fiber are optional). It ships a styles.css with its design tokens; import it once from your entry stylesheet and put your own token overrides after it, so equal-specificity declarations win by source order.
cssTailwind CSS v4 setup@import 'tailwindcss'; @import '@medalsocial/meda/styles.css'; :root { /* Overrides go after the Meda import so they win by source order. */ --color-brand-500: oklch(0.62 0.18 245); }
tsxRender the shellimport { AppShell, MedaShellProvider } from '@medalsocial/meda/shell'; import { Inbox } from 'lucide-react'; export function App() { const workspace = { id: 'workspace', name: 'Workspace' }; const apps = [{ id: 'inbox', label: 'Inbox', icon: Inbox }]; return ( <MedaShellProvider workspace={workspace} apps={apps}> <AppShell variant="workspace" iconRail={{ mainItems: [{ id: 'inbox', label: 'Inbox', icon: Inbox, to: '/inbox' }] }} > {/* your app */} </AppShell> </MedaShellProvider> ); }
The same shell we ship
Meda powers Medal’s own apps, so the navigation rails, command palette and workbench layout you get are the ones we run in production — not a demo kit.