Skip to main content
Urbicon UI

Getting started — install · tokens · component · theme · agent

Getting started

Five steps from an empty file to a themed app your agent can keep building. The “Your app so far” preview grows with every step — by step 04, you repaint it yourself.

requires svelte 5 · tailwind css 4 · node 18+ or bun 1+ · typescript recommended

No project yet?

Starting from an empty directory, the official sv CLI scaffolds a SvelteKit app — it asks its own questions (TypeScript, Prettier, …), and --add @urbicon-ui hands the rest to our add-on: it pulls in Tailwind, installs the library and the urbicon CLI, and writes the stylesheet import for you.

Create a SvelteKit project

bunx sv create my-app --add @urbicon-ui

That covers steps 01 and 02 — jump straight to your first component, or read on to see what the add-on did. Inside an existing project, start at 01.

Not a SvelteKit project? The components don’t need one — they import neither $app/* nor @sveltejs/kit, so any Svelte 5 project with Vite and Tailwind 4 works. The add-on is the SvelteKit-only piece; steps 01 and 02 below are the whole setup by hand.

Install

Already inside a SvelteKit project? The same add-on runs there too, and does this step and the next one in one go:

Add Urbicon UI to an existing project

bunx sv add @urbicon-ui

By hand it is one package with zero runtime dependencies: compiled Svelte plus a CSS token file. Only what you import ends up in your bundle, and any package manager works.

Install Urbicon UI

bun add @urbicon-ui/blocks

Import the tokens

On the add-on path this is already done — read it to know what is in your project. The design system arrives as CSS, and Tailwind 4 does the plumbing, so if Tailwind isn’t part of your project yet, add the Vite plugin first (already there? skip ahead):

Vite config

// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
// no SvelteKit? swap it for svelte()
// from '@sveltejs/vite-plugin-svelte'
import tailwindcss from '@tailwindcss/vite';

export default {
  plugins: [tailwindcss(), sveltekit()]
};

Then two imports: Tailwind, and the token sheet — OKLCH color ramps, semantic tokens, typography, spacing, and dark mode via light-dark(). The blocks stylesheet brings its own @source directives, so Tailwind finds the components’ classes without extra config. Load the file once, wherever your app loads CSS: import './app.css' in +layout.svelte for SvelteKit, in your entry module src/main.js for plain Vite + Svelte:

Import CSS tokens

/* app.css */
@import 'tailwindcss';
@import '@urbicon-ui/blocks/style/index.css';

Every further @urbicon-ui/* package that ships components ships a stylesheet of its own — import it after blocks. Without it, the classes only that package uses compile to nothing, and nothing reports it. bunx urbicon init prints the import list for what is in node_modules.

Your first component

Import and render — no provider, no context setup. This is the booking widget from Fermata, the quiet hotel group every demo on this site runs on, and it’s three components speaking one grammar: label, bind:value and intent mean the same thing everywhere. The exact same code runs live in the “Your app so far” preview — book yourself a night.

Book a stay

<script>
  import { Badge, Button, Input, Select } from '@urbicon-ui/blocks';

  let name = $state('');
  let room = $state('garden');
  let booked = $state(false);
</script>

<Input label="Your name" bind:value={name} placeholder="Ada" />

<Select
  label="Room"
  options={[
    { label: 'Garden Room — €300', value: 'garden' },
    { label: 'Corner Room — €360', value: 'corner' }
  ]}
  bind:value={room}
/>

<Button intent="primary" onclick={() => (booked = true)} disabled={!name}>
  Reserve
</Button>

{#if booked && name}
  <Badge intent="success">Booked — see you in September, {name}.</Badge>
{/if}

Make it yours

Every component reads semantic tokens, so theming means overriding custom properties in Tailwind’s @theme — no component needs to know. The preview’s four paints are this site’s own room colours, one per component family; flip one and watch every component follow. In your codebase it is a declaration in your own stylesheet:

Custom theme

/* app.css */
@import 'tailwindcss';
@import '@urbicon-ui/blocks/style/index.css';

@theme {
  /* Override the primary ramp — every component follows it */
  --color-primary-500: oklch(0.64 0.16 40); /* warm terracotta */
}

Bring your agent

One command writes the AGENTS.md block: the component grammar, the token rules, where to look things up. With --hook / --ci the design gate arms too, and every file your agent writes is linted against the library’s own rules before it ships. The add-on already installed @urbicon-ui/design; by hand, add it once (bun add -d @urbicon-ui/design) so the knowledge the CLI serves stays pinned to the library version you installed.

Onboard your agent

bunx urbicon init

What the gate checks, and the rest of the toolchain — per-component llms.txt, the urbicon CLI — lives on AI & DX.