Skip to content
omaris

Foundations

Charts and maps

Both are opt-in, behind their own entry points.

Charts and maps ship in the same package but behind their own entry points, because layerchart and maplibre-gl together are tens of megabytes and nobody importing a Button should pay for them.

import { Button, Card } from 'omaris'; // no heavy dependenciesimport { LineChart } from 'omaris/chart'; // needs layerchart + d3-shapeimport { Map, Marker } from 'omaris/map'; // needs maplibre-gl

All three are optional peer dependencies, so a package manager installs them only if you ask:

bun add layerchart d3-shape   # for omaris/chartbun add maplibre-gl           # for omaris/map

TreemapChart also reads d3-hierarchy and ComboChart d3-scale; both arrive with layerchart, so add them explicitly only if your package manager refuses to hoist (pnpm's default).

Charts

Twelve types and a sparkline:

AreaChart LineChart BarChart ScatterChartthe cartesian four
ComboChartbars and lines together, with a second axis
PieChart TreemapChart FunnelChartpart of a whole
RadarChart RadialBarChart Gaugeradial
CandlestickChartopen, high, low, close
Sparklinea trend with no axes, for a table cell

They read the theme's chart colours, so they re-skin with everything else, and ChartFrame is the shared shell if you are dropping down to layerchart directly.

What every chart takes

Beyond the data, the props that matter across the set:

  • references — lines and bands at fixed values: a target, a threshold, the window something was broken.
  • annotations — a note pinned to one point, with an optional leader line.
  • brush — drag across the plot to select a range, and zoom to it.
  • zoom — wheel or pinch to zoom, drag to pan. Both rescale the axes rather than the pixels, so the tick labels stay true.
  • legend="isolate" — a click shows that series alone, a second brings the rest back.
  • csv — a download in the corner that hands the plotted rows back as a file. toCsv and downloadCsv are exported for doing it yourself.
  • error — a request that failed is not the same as no data, and shouldn't look like it. Pass a string, an Error, or true; add onRetry for a button.
<LineChart	data={rows}	x="date"	y="latency"	legend="isolate"	brush	csv="latency"	error={loadError}	onRetry={reload}	references={[{ y: 400, label: 'SLO', color: 'var(--warning)' }]}	annotations={[{ x: shipped, y: 820, label: 'v2 rollout', leader: true }]}/>

See Charts for the API.

Maps and the tile worker

MapLibre parses tiles in a web worker it finds by URL, and the URL is built at runtime — no bundler can follow it, so a production build used to ship the library and 404 the worker: an attribution line over an empty box. Map now asks Vite for the worker as an asset of its own and points MapLibre at it, so a built app draws tiles with no configuration.

In vite dev, one line still helps: pre-bundling rewrites MapLibre's imports in a way its worker chunk doesn't survive, and excluding it keeps the dev server serving the real module.

vite.config.ts TypeScript
export default defineConfig({	plugins: [tailwindcss(), sveltekit()],	optimizeDeps: {		exclude: ['maplibre-gl']	}});

The map family is declarative — sources, layers, clustering, routes, heatmaps, drawing and geofences are components rather than imperative calls. See Maps.