@k8slens/lds
v2.1.0
Published
Lens Design System — React component library for the Lens product portfolio
Maintainers
Keywords
Readme
Lens Design System
A React component library for building any surface — dashboards, admin panels, Electron apps, CLI/TUI tools, and beyond. Originally created for Lens Desktop, LDS is a general-purpose design system for the broader Lens product portfolio and any product that needs a cohesive, dark-theme-optimized UI.
- 🎨 Dark theme optimized for long working sessions
- 📦 42+ components covering navigation, controls, data visualization, layout, and more
- 🎯 Design tokens as CSS custom properties (
--lds-*) - 📐 Density system — one setting sizes a whole page coherently, from a 22px table row to a 64px editorial hero
- 🖥️ Multi-target — Web and Terminal UI (Ink) from a shared codebase
- 🤖 AI-ready — ships
llms.txtand a style guide your coding agent can read
Installation
npm i @k8slens/ldsImport the stylesheet once in your app entry, then use components:
import '@k8slens/lds/style.css';
import { Button } from '@k8slens/lds';
<Button variant="primary" onClick={handleClick}>
Create Resource
</Button>Entry points and optional peer dependencies
The main entry has no heavy dependencies. Components that need one live behind their own entry point, and that dependency is an optional peer dependency — you install it only if you import that entry. So an LDS-powered marketing page or a simple dashboard never downloads a code editor or a graph engine.
| Import | Install alongside it | Component |
|--------|----------------------|-----------|
| @k8slens/lds | nothing | everything below except the four rows here |
| @k8slens/lds/charts | uplot | TimeSeries + TimeSeriesControls |
| @k8slens/lds/resource-map | @xyflow/react dagre | ResourceMap |
| @k8slens/lds/code-editor | @monaco-editor/react | CodeEditor |
| @k8slens/lds/terminal | ink | Terminal (Ink) components |
npm i @k8slens/lds # core components
npm i @k8slens/lds @xyflow/react dagre # + ResourceMapEach of those entries also imports its dependency's stylesheet, which your bundler resolves automatically — no extra CSS import needed.
// Web components (default)
import { Button } from '@k8slens/lds';
// Terminal components
import { ButtonTerminal } from '@k8slens/lds/terminal';Stylesheets
| Import | Size | Contents |
|--------|------|----------|
| @k8slens/lds/style.css | ~211 KB | all --lds-* tokens plus every component's styles |
| @k8slens/lds/tokens.css | ~26 KB | the token layer only — colors, spacing, typography, radii |
Import style.css when you use LDS components. Import tokens.css when you only
need the design tokens — for example a Tailwind theme that maps onto --lds-*
variables, or a marketing site with its own components.
Design tokens
All design tokens are CSS custom properties with the --lds- prefix:
/* Colors */
--lds-color-bg-primary: #181A1C;
--lds-color-text-primary: #aaacae;
--lds-color-primary: #3d90ce;
/* Spacing (4px base unit) */
--lds-space-1: 4px;
--lds-space-2: 8px;
/* Typography */
--lds-font-size-md: 13px;import '@k8slens/lds/tokens.css';Density
Declare a density once and the whole subtree fits together — text, icons, padding, radii, gaps, and nested controls all derive from it:
<DensityProvider density="comfortable">
<Dashboard /> {/* 44px rows holding 36px controls */}
</DensityProvider>or with no React at all, which is all a stylesheet needs:
<div data-density="editorial">…</div>| density | rows | controls | intended for |
|---|---|---|---|
| compact | 22px | 18px | dense desktop: tables, trees, status bars |
| standard | 34px | 26px | Lens Desktop default |
| comfortable | 44px | 36px | web admin dashboards |
| editorial | 64px | 48px | marketing sites |
Within a density there are three rungs — surface ⊃ control ⊃ embedded — so a row
is always sized to carry the controls placed in it, and a control nested inside another
control (the clear button in a search field) is smaller again.
Individual components take a density prop to override their surroundings:
<Toolbar density="compact">
<Button /> {/* 18px: the control rung inside a 22px surface */}
</Toolbar>Components that are not meaningful at every density clamp themselves rather than
render nonsense — a TreeView inside an editorial page becomes standard, not 64px
per row.
Usage examples
Data table
import { DataTable, StatusIndicator, Badge } from '@k8slens/lds';
<DataTable
data={pods}
columns={[
{ key: 'name', header: 'Name', width: '1fr', sortable: true },
{ key: 'namespace', header: 'Namespace', width: '140px',
render: (pod) => <Badge>{pod.namespace}</Badge>
},
{ key: 'status', header: 'Status', width: '120px',
render: (pod) => <StatusIndicator status={pod.status} label={pod.statusLabel} />
},
]}
getRowKey={(pod) => pod.id}
onRowClick={setSelectedPod}
/>Density override on a button
import { Button, RefreshIcon } from '@k8slens/lds';
{/* Density is inherited; pass it only to override the surrounding context. */}
<Button variant="ghost" density="compact" iconOnly icon={<RefreshIcon />} />API reference for humans and agents
Two reference documents ship inside this package:
llms.txt— the full component inventory and API reference, written for coding agents. Point your editor's AI atnode_modules/@k8slens/lds/llms.txtand it knows every component, prop, and token.lens-style-guide.md— what "looks like Lens" means: the visual language and how to compose LDS components to achieve it.
Working from the LDS source repository instead? Start at
docs/CONSUMERS.md.
Changelog
See CHANGELOG.md, shipped with the package.
License
Apache License 2.0 — Copyright 2026 Mirantis, Inc.
