For developers.
@dashfi/svelte is an internal Nx-workspace library — not published to npm. This page documents how to consume it from another package inside the dash monorepo, how to theme it, and the contract every component honors.
Inside the dash monorepo: declare the workspace dependency, install, run. The lib is symlinked — no publish step.
// packages/your-app/package.json
{
"dependencies": {
"@dashfi/svelte": "workspace:*"
}
}# inside the dash monorepo
pnpm install # picks up the workspace symlink
nx serve dashfi-ui # OR pnpm --filter dashfi-ui dev
# the lib is live-symlinked — edits in libs/svelte-components/lib/ hot-reloadThe lib ships a Tailwind preset (jade brand color, ink primary, cobalt secondary, orange destructive). Extend it from your app config.
// packages/your-app/tailwind.config.ts
import type { Config } from 'tailwindcss';
import { tailwindPreset } from '@dashfi/svelte/design-system/tailwind/config';
const config: Config = {
presets: [tailwindPreset],
content: [
'./src/**/*.{html,js,svelte,ts}',
// Scan the lib source so Tailwind generates classes used by its components
'../../libs/svelte-components/lib/src/lib/**/*.{html,js,svelte,ts}',
]
};
export default config;SSR needs the lib bundled (Svelte 5 component compilation). Add @dashfi/svelte to ssr.noExternal.
// packages/your-app/vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
// Required — bundle lib code in SSR so Svelte 5 components compile correctly
ssr: {
noExternal: ['@dashfi/svelte']
}
});Import the lib's stylesheet once at the top of your app.css. Then layer your own @theme overrides on top.
/* packages/your-app/src/app.css */
@import 'tailwindcss';
@import '@dashfi/svelte/styles/global.css'; /* HSL token layer + base resets */
/* Optional — scoped overrides for your app surface */
@theme {
--color-brand: #2b605c;
--color-brand-foreground: #ffffff;
}A working component in 10 lines. Drop this into any Svelte 5 route once the four config steps above are done.
<script lang="ts">
import { Button } from '@dashfi/svelte/ui/button';
import { Card, CardHeader, CardTitle, CardContent } from '@dashfi/svelte/ui/card';
</script>
<Card>
<CardHeader>
<CardTitle>First card</CardTitle>
</CardHeader>
<CardContent>
<Button variant="brand">Hello, Dash</Button>
</CardContent>
</Card>Three layered tiers: base primitives → product semantic → marketing aliases. The full taxonomy is documented at /foundations/color. To override, redeclare the semantic layer.
13 brand primitives — --dash-jade, --dash-cobalt, --dash-ink, etc. Single source of every hex.
Component-facing — --bg, --fg, --brand, --border. Two modes (light + dark). What you override.
--m-* tokens. Reference the base palette directly. Used by marketing surfaces.
/* app.css · override a single semantic token */
:root {
--brand: #1a8a78;
--color-brand: #1a8a78;
}
html.dark {
--brand: #6dd0c6;
--color-brand: #6dd0c6;
}
/* The lib's components read --color-brand via Tailwind utilities (bg-brand,
text-brand). The portal chrome reads --brand directly. Keep both in sync. */62 components shipped — 28 stable, 34 beta, 0 deprecated. Beta APIs may shift; stable APIs are frozen until a major version cut.
@dashfi/svelte/ui/button@dashfi/svelte/ui/input@dashfi/svelte/ui/textarea@dashfi/svelte/ui/label@dashfi/svelte/ui/checkbox@dashfi/svelte/ui/switch@dashfi/svelte/ui/radio-group@dashfi/svelte/ui/select@dashfi/svelte/ui/toggle@dashfi/svelte/ui/toggle-group@dashfi/svelte/ui/calendar@dashfi/svelte/ui/badge@dashfi/svelte/ui/avatar@dashfi/svelte/ui/pill@dashfi/svelte/ui/empty@dashfi/svelte/ui/separator@dashfi/svelte/ui/skeleton@dashfi/svelte/ui/code-block@dashfi/svelte/ui/alert@dashfi/svelte/ui/alert-dialog@dashfi/svelte/ui/dialog@dashfi/svelte/ui/sheet@dashfi/svelte/ui/popover@dashfi/svelte/ui/tooltip@dashfi/svelte/ui/progress@dashfi/svelte/ui/linear-loader@dashfi/svelte/ui/loader@dashfi/svelte/ui/spinner@dashfi/svelte/ui/tabs@dashfi/svelte/ui/accordion@dashfi/svelte/ui/collapsible@dashfi/svelte/ui/breadcrumb@dashfi/svelte/ui/pagination@dashfi/svelte/ui/pagination-wrapper@dashfi/svelte/ui/sidebar@dashfi/svelte/ui/dropdown-menu@dashfi/svelte/ui/scroll-area@dashfi/svelte/ui/card@dashfi/svelte/ui/multi-select@dashfi/svelte/ui/phone-input@dashfi/svelte/ui/tel-input@dashfi/svelte/ui/date-range-selector@dashfi/svelte/ui/range-calendar@dashfi/svelte/ui/form@dashfi/svelte/ui/alert-error@dashfi/svelte/ui/indicator@dashfi/svelte/ui/item@dashfi/svelte/ui/logo@dashfi/svelte/ui/merchant-logo@dashfi/svelte/ui/flow-lines@dashfi/svelte/ui/magnetic-hover@dashfi/svelte/ui/drawer@dashfi/svelte/ui/fullscreen-dialog@dashfi/svelte/ui/hover-card@dashfi/svelte/ui/sonner@dashfi/svelte/ui/support-modal@dashfi/svelte/ui/command@dashfi/svelte/ui/navigation@dashfi/svelte/ui/table@dashfi/svelte/ui/enhanced-table@dashfi/svelte/ui/data-table@dashfi/svelte/ui/table-filtersThe lib is the source of truth. Add the component in libs/svelte-components/lib first, then document it here in dashbook.
# Add a new component to @dashfi/svelte
cd libs/svelte-components/lib
# Generate the directory: src/lib/ui/your-component/
# your-component.svelte
# your-component.stories.svelte
# index.ts
# Re-export
echo "export { default as YourComponent } from './your-component.svelte';" \
>> src/lib/ui/your-component/index.ts
# Build the lib (dashbook hot-reloads because of link: protocol)
pnpm build
# Open a stories file alongside — Storybook picks it up automatically- Match existing patterns — Svelte 5 runes (
$props,$state,$derived),tailwind-variantsfor variants,bits-uifor keyboard / focus semantics. - Always forward
classthroughcn(...)from$lib/utils.js. - Make
refbindable for surfaces consumers will want to attach to. - Add the new slug + metadata to
dashbook/src/lib/content/components.ts. - Generate a route page at
dashbook/src/routes/components/{slug}/+page.sveltewith the canonical Preview / Code / Docs / Anatomy / Accessibility / Changelog tabs.
Internal-only. Issues and PRs land in the dash monorepo. Voice and chrome conventions live in PLAN.md §13.
Open a PR against github.com/FunnelDash/core touching libs/svelte-components/lib/. CI runs visual regression via Storybook
Chromatic and svelte-check. Dashbook will hot-reload via the link: symlink — no extra step.
Documentation, new patterns, foundations content — PR against FunnelDash/core under packages/brand-book/. Match the existing chrome
(InnerPage, PageHeader, Section) and tone
(sentence case, no exclamation marks, no emoji). See PLAN.md §13 in the repo root.
New components without a real consumer in dashfi-ui or another internal
package. New patterns without a documented Dash.fi use case. Visual reskins of the
portal that drift from the canonical handoff.
Storybook is the engineering deep-dive; the Figma library is the design source of truth and ships in a parallel track.
Source for @dashfi/svelte, dashfi-ui, this portal (packages/brand-book/), and all internal packages.
Component variants, text styles, and token variables. See FIGMA_HANDOFF.md.
Per-component stories — isolated states, controls, a11y inspector.