Baltimore Design System
React components, design tokens, and an app shell for City of Baltimore civic
applications — one visual and interaction language across the city's digital
services, built on MUI and React 19. Exact supported peer
ranges live in this package's peerDependencies.
Component catalog / Storybook: https://bromo-design-system.fly.dev
Install
npm install @city-of-baltimore/bromo
No registry configuration or tokens required.
Quick start
Wrap your app once, import the stylesheet once, and use the shell:
// main.tsx
import "@city-of-baltimore/bromo/styles.css"; // network-free resets and tokens
import { BromoProvider } from "@city-of-baltimore/bromo";
createRoot(document.getElementById("root")!).render(
<BromoProvider config={{ productTitle: "311 Explorer" }}>
<App />
</BromoProvider>,
);
import { PageShell, Surface, Button } from "@city-of-baltimore/bromo";
export function HomePage() {
return (
<PageShell eyebrow="Operations" title="Service requests" subtitle="Citywide view">
<Surface>
<Button>Export</Button>
</Surface>
</PageShell>
);
}
BromoProvider wires the theme, CssBaseline, light/dark color mode,
and the --bromo-* design tokens — don't add your own ThemeProvider around it.
No router is required: shell links render plain anchors by default. A router
integration can supply the public linkComponent seam with an implementation
that accepts href; this does not transfer navigation policy to the kit.
Bromo's typography stacks prefer the approved City families and include
complete system fallbacks. The package itself declares no @font-face, ships
no font binary, and contacts no font host — so a licence question can never
contaminate this tarball.
Font delivery lives in the separately governed adapter,
@city-of-baltimore/bromo-fonts, which is published from the same release
event and carries the same version as this package. Install it only if you want
the branded faces; omit it and the browser uses the system fallback stack without a font request. See
the typography contract.
For instance-local appearance configuration, share one BromoColorModeOptions
object between initializeBromoColorMode (called before createRoot) and the
provider's colorMode prop. The initializer stamps the resolved appearance preference before rendering; the
stylesheet cascade supplies the token values and returns the resolved mode plus reduced-motion
state for app-owned document tokens. themeOverrides may remain a static MUI
options object or become a factory receiving that mode/reduced-motion context.
Primary- and error-palette overrides provide a readable main /
contrastText pair. Bromo derives visibly distinct hover and pressed fills
while leaving MUI's general dark shade independent, and rejects an unsafe
enabled Button state rather than letting it ship.
See docs/use/toolkit_consumer_setup.md in the repository for the full example.
Entry points
Heavy optional dependencies never ride along with a button: chart and map components live on their own subpaths, each behind optional peer dependencies.
| Import | Contents | Optional peer |
|---|---|---|
@city-of-baltimore/bromo | components, providers, theme/color-mode helpers, systems token layer | — |
…/tokens | theme, color-mode, and typography contracts | — |
…/charts | Chart (+ DataTable re-export) | @mui/x-charts |
…/map | GeoMap, MapFrame, MapLegend, MapA11ySummary | maplibre-gl |
…/styles.css | network-free resets and CSS tokens | — |
Required peers include React, MUI, and Emotion (React Router is an optional
integration via linkComponent). Install the exact ranges declared by the
released package's peerDependencies. API transport,
auth, and runtime helpers belong to @city-of-baltimore/patapsco; Bromo has no
./api export.
Versioning
Semantic versioning over a frozen public API: every export of the root entry,
the subpath layout, and the --bromo-* CSS custom property names. Deprecations
ship at least one minor release before removal, with migration notes in the
CHANGELOG.
Accessibility
Components target WCAG 2.2 AA: two-tone focus indicators, reviewed status inks in both color modes, and selection states that do not rely on color alone. Storybook's accessibility addon supports explicit interactive review in manual mode. Playwright alone owns automated axe execution in the release gate, where it scans every indexed story in both light and dark mode, runs keyboard interaction checks, and verifies representative visual snapshots. Manual and consumer-flow testing remain required for conformance.
License
MIT — the same license as the GOV.UK Design System. This design system is public infrastructure: any government, civic organization, or vendor is welcome to use, adapt, and build on it — that's the point. The "City of Baltimore" name, seal, and brand assets identify official city services and remain protected by trademark law; don't use them to imply endorsement.
Built by the City of Baltimore.