Getting Started
Install the Kosmesis CLI and add your first component.
Prerequisites
Kosmesis expects a create-praxisjs-scaffolded project (the minimal,
full, or router template all work) using Vite. If you don't have one yet:
npm create praxisjs@latest my-projectcd my-projectpnpm create praxisjs my-projectcd my-projectyarn create praxisjs my-projectcd my-projectbun create praxisjs my-projectcd my-projectSetup
Run init
From the root of your PraxisJS project:
npx kosmesis initpnpm dlx kosmesis inityarn dlx kosmesis initbunx kosmesis initThis will:
- Write a
components.jsonconfig file. - Add
@import "tailwindcss";plus Kosmesis's theme tokens (--background,--foreground,--primary, ...) to your global stylesheet. - Wire the
@tailwindcss/viteplugin into yourvite.config.ts. - Create
src/lib/utils.tsexporting acn()helper (clsx+tailwind-merge).
Add a component
npx kosmesis add buttonpnpm dlx kosmesis add buttonyarn dlx kosmesis add buttonbunx kosmesis add buttonThis copies button.tsx into src/components/ui/button.tsx. If the component wraps a Morphos
primitive, its package (e.g. @morphos/inputs) is installed automatically.
Use it
import { Button } from "@/components/ui/button";
@Component()
class MyPage extends StatefulComponent {
render() {
return <Button variant="outline">Click me</Button>;
}
}@/components/ui/... assumes a @/* → ./src/* path alias in tsconfig.json. Add one if your
create-praxisjs template doesn't already have it, or adjust the aliases in components.json
to use relative imports instead.
Non-interactive setup
Every init question has a flag. With --yes (or --defaults) nothing is asked: each choice you
don't pass takes its default. Handy for scripts, CI and other CLIs.
npx kosmesis init --yes --style-system praxisjs-css --icon-library none| Flag | Answers | Default with --yes |
|---|---|---|
--style-system <tailwind|praxisjs-css> | Which styling system to use | tailwind |
--icon-library <lucide|none> | Which icon library to wire | lucide |
--css <path> | Global stylesheet (Tailwind) or theme module (@praxisjs/css) | src/style.css / src/lib/kosmesis-theme.ts |
--root-component <path> | Root component that gets @Themed(...) / @IconProvider(...) | src/app.tsx |
--erase / --no-erase | Erase what the stylesheet or theme module already has, instead of keeping it below Kosmesis's tokens (with Tailwind, inside @layer base) | keep it |
--overwrite / --no-overwrite | Replace an existing components.json | stop |
--force | Continue in a project without @praxisjs/core | stop |
-y, --yes, -d, --defaults | Don't prompt |
With --yes, nothing is erased or overwritten unless its flag says so. When a run needs an
answer only --overwrite or --force can give, it stops with exit code 1 and names the flag.
Without --yes, flags still answer their question and init asks only the rest.
kosmesis init --help prints the list.
New PraxisJS projects can start with Kosmesis already set up: create-praxisjs asks for it (or
takes --kosmesis), and praxisjs add kosmesis adds it to a project you already have. Both run
kosmesis init with these flags. See the PraxisJS quickstart.
Fetching from another registry
Every component so far came from components.json's default registry field
(https://kosmesis.praxisjs.org/r). There are two ways to pull from somewhere else:
One-off, for a single add:
npx kosmesis add button --registry ./packages/registry/dist/rPersistent, addressed by name: register a namespace once, then reference it directly whenever
you add a component — no flag needed, and it works alongside the default registry in the same
add call.
npx kosmesis registry add acme https://ui.acme.internal/r
npx kosmesis add @acme/button
npx kosmesis add @acme/button badge # mixes a namespaced and a default-registry component| Command | What it does |
|---|---|
kosmesis registry add <namespace> <url> | Saves <url> under @<namespace> in components.json, so @<namespace>/<component> resolves there from now on. |
kosmesis registry list | Prints the default registry and every configured namespace. |
kosmesis registry remove <namespace> | Forgets a namespace. |
<url> (for both --registry and kosmesis registry add) can be a local directory (handy while
developing components) or an http(s):// base serving the same <styleSystem>/<name>.json shape.
Whichever registry resolves a component is trusted at install time: its files are written to
disk as-is and its dependencies are installed automatically. Only add a namespace, or pass
--registry, for a registry you trust — the same way you'd only add an npm registry mirror you
trust.
Want to serve your own components this way? See Custom Registry.
Updating a component
kosmesis add records each component's version, and a hash of every file it wrote, in
components.lock.json (commit it). When a registry publishes a newer version:
npx kosmesis outdated # what has an update, and which of your copies you edited
npx kosmesis update button # shows the diff and asks before writing anythingFiles you edited are never replaced without asking. See Updating Components.