@lostgradient/cinder
v0.19.1
Published
A Svelte 5 component library and design system focused on accessibility, theming, and per-component tree-shaking.
Maintainers
Readme
@lostgradient/cinder
Svelte 5 components for product interfaces: accessible primitives, design-system tokens, per-component CSS, generated prop schemas, and examples that can be read by people or tooling.
Use cinder when you want UI building blocks without adopting a framework-level router, form-state manager, data fetching layer, global state provider, or theme provider. The package is SSR-safe and targets Svelte >=5.56.0 <6.
Install
bun add @lostgradient/cinder sveltesvelte is a required peer dependency. Cinder uses Lucide (lucide-svelte) for
its own component chrome, but bundles its own pinned copy as a regular
dependency rather than a peer, so Cinder's own server-rendered icon markup
stays consistent with its own client build without depending on which
lucide-svelte version — if any — your application installs for its own
icons. (If your bundler's deduplication collapses Cinder's pinned copy onto a
different version your app requests, the two can still diverge; see the
@lostgradient/cinder changeset for that edge case.) Cinder does not provide
a general icon library for your application-specific icons. The Chat domain
suite is published separately as @lostgradient/chat.
As of this release, cinder no longer exposes any ./markdown/*, ./editor/*, or
./commentary/* subpath — that surface moved to two published sibling packages during the
package-boundaries extraction. If your app imports
one of the removed subpaths, install the package that now owns it and update the import
specifier:
| Removed cinder subpath | New home |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| @lostgradient/cinder/markdown, ./markdown/* (pipeline, diff, rendering, utilities) | @lostgradient/markdown — same subpath shape, e.g. ./markdown/pipeline → @lostgradient/markdown/pipeline |
| @lostgradient/cinder/editor, ./editor/component-runtime, ./editor/test-utilities | @lostgradient/editor/editor, @lostgradient/editor/editor/component-runtime, @lostgradient/editor/editor/test-utilities |
| @lostgradient/cinder/editor/sanitize-html, /template-placeholders, /template-render | @lostgradient/markdown/templates/sanitize-html, /template-placeholders, /template-render |
| @lostgradient/cinder/commentary, ./commentary/* | @lostgradient/editor root barrel and its matching subpath, e.g. ./commentary/anchor-decorations → @lostgradient/editor/anchor-decorations |
| @lostgradient/cinder/markdown-editor, /review-editor, /diff-viewer | @lostgradient/editor/markdown-editor, /review-editor, /diff-viewer (moved in an earlier release — see @lostgradient/editor's README) |
bun add @lostgradient/markdown
# and, if you use the MarkdownEditor / ReviewEditor / DiffViewer components:
bun add @lostgradient/editorSyntax-highlighting (CodeBlock automatic highlighting via shiki, @shikijs/engine-oniguruma,
and @shikijs/types) needs no separate install — they are regular dependencies of cinder and
install automatically.
Quickstart
Load the base stylesheet once at your app entry:
import '@lostgradient/cinder/styles';
import '@lostgradient/cinder/styles/guard';@lostgradient/cinder/styles is the base stylesheet. Import it once at your app entry before importing any cinder component. It declares cinder's cascade-layer order, design tokens, foundation rules, utilities, and shared internal chrome.
@lostgradient/cinder/styles/guard is development-only. It warns if the base stylesheet is missing or loaded too late.
Then import the components you use. In browser/Svelte-aware builds, component entry points automatically include their co-located CSS; no matching /styles import is required:
<script lang="ts">
import Button from '@lostgradient/cinder/button';
</script>
<Button variant="primary" label="Save changes" />The same applies to other components:
<script lang="ts">
import Modal from '@lostgradient/cinder/modal';
</script>
<Modal open title="Edit project" />You can also import the component module from TypeScript:
import Modal from '@lostgradient/cinder/modal';Compound components include their leaf styles from the parent entry. For example, importing @lostgradient/cinder/tabs covers Tabs, Tabs.List, Tabs.Trigger, and Tabs.Panel.
The /styles subpaths remain published for explicit CSS composition and advanced bundler setups. Use @lostgradient/cinder/styles/all when you want one stylesheet with every component, or the base stylesheet plus specific /styles sidecars when you intentionally manage CSS imports yourself.
If you want one stylesheet with everything, use:
import '@lostgradient/cinder/styles/all';That bundle includes the base stylesheet plus every component stylesheet. It is convenient, but it is not tree-shaken.
Import Shapes
Prefer subpath imports in browser applications:
import Button from '@lostgradient/cinder/button';
import Modal from '@lostgradient/cinder/modal';The root barrel is available when convenience matters more than keeping the import graph narrow:
import { Button, Modal } from '@lostgradient/cinder';Finding the Right Component
For agents and local tooling, prefer the published cinder command:
cinder search modal
cinder show button --json
cinder compare modal drawer --json
cinder best-practices stylesUse cinder mcp to start the read-only stdio MCP server. It exposes the same
component search, detail, comparison, best-practice guidance, and generated
artifact resources without requiring agents to parse package files directly.
Cinder also ships a machine-readable manifest for environments where the CLI or MCP server is unavailable:
import manifest from '@lostgradient/cinder/manifest' with { type: 'json' };manifest.components[] lists each public component with its id, category, tags, purpose, useWhen, avoidWhen, related components, and artifact subpaths.
Every component also ships generated sidecars:
import buttonSchema from '@lostgradient/cinder/button/schema';
import buttonVariables from '@lostgradient/cinder/button/variables';
import buttonConstraints from '@lostgradient/cinder/button/constraints' with { type: 'json' };
import buttonExamples from '@lostgradient/cinder/button/examples' with { type: 'json' };schema: JSON Schema for props.variables: public CSS custom properties for the component.constraints: cross-prop rules that JSON Schema cannot express cleanly.examples: canonical runnable usage snippets.
Not every component has constraints or examples; check the manifest's hasConstraints and hasExamples flags before importing those subpaths.
Theming
Cinder uses CSS custom properties and color-scheme; there is no provider to mount.
html {
color-scheme: light;
}
html[data-theme='dark'] {
color-scheme: dark;
}
[data-theme='light'] {
color-scheme: light;
}
[data-theme='dark'] {
color-scheme: dark;
}Use [data-theme='dark'] or [data-theme='light'] on a subtree for scoped theme islands. Cinder pins the core semantic surface, text, border, overlay, interaction, status, and control tokens inside those scopes so components inherit local values without app-level token overrides. If your app replaces Cinder's public tokens for custom branding, set those brand overrides in the same scoped theme selector.
Public tokens use the --cinder- prefix. Internal implementation variables use --_cinder-; do not redefine those.
What Cinder Does Not Provide
Cinder is a presentation library, not an application framework.
- No router.
- No form-state manager.
- No application-wide toast singleton; use
ToastRegionfor scoped toast UI. - No data fetching layer.
- No global state provider.
- No general-purpose icon library for product-specific icons.
Wire those pieces with your application stack and pass the resulting state, callbacks, links, icons, and data into cinder components.
Development
This package lives in the cinder monorepository under packages/components.
bun install
bun run --filter=@lostgradient/cinder validateUseful package commands:
bun run --filter=@lostgradient/cinder build
bun run --filter=@lostgradient/cinder components:check
bun run --filter=@lostgradient/cinder exports:check
bun run --filter=@lostgradient/cinder validate:consumerWhen adding or changing components, update the source files under src/components/<component-id>/, then run:
bun run --filter=@lostgradient/cinder components:generateThat regenerates schemas, variables, the manifest, generated README sections, and related artifacts.
