Getting Started
Set up Visor in your project — from zero to first component in under five minutes.
Prerequisites
- Node.js 18+ — required by the Visor CLI
- npm — the CLI runs via npx, no global install needed
Quick Start (Next.js — one command)
In an empty directory, run:
npx @loworbitstudio/visor init --template nextjsThat single command scaffolds a complete, runnable Next.js App Router project pre-wired with Visor — no second setup step:
| What you get | Why it matters |
|---|---|
Full package.json with next, react, TypeScript | Run npm run dev immediately |
@loworbitstudio/visor-core + @loworbitstudio/visor-theme-engine installed | Tokens and FOWT helpers are already there |
.visor.yaml | Your theme — edit colors, typography, radius, shadows |
app/globals.css | Generated from .visor.yaml by the Next.js adapter |
app/layout.tsx with FOWT script + globals.css imported | No flash of wrong theme on hard reload |
.lo/borealis.json | Stamp recording the Visor version that initialized the project |
Then start the dev server:
cd my-app && npm run devHeads up:
visor init --template nextjsonly scaffolds into empty directories — it refuses ifpackage.jsonalready exists. To retrofit an existing app, use the Manual Setup section below.
Customize Your Theme
Edit .visor.yaml with your brand values, then regenerate the CSS:
npx @loworbitstudio/visor theme apply .visor.yaml --adapter nextjsThe generated globals.css contains all CSS custom properties your components need. Every time you change .visor.yaml, re-run theme apply to update.
Add Components
Install components individually or in bulk:
# Single component
npx visor add button
# Multiple components
npx visor add button card input dialog
# Entire category
npx visor add --category formComponents are copied into your project (copy-and-own). You have full edit rights — no lock-in, no runtime dependency.
Add Blocks
Blocks are pre-composed layouts built from Visor components:
npx visor add --block login-form
npx visor add --block admin-dashboardDark Mode
Visor's token system includes light and dark mode out of the box. Add the dark class to your root element:
<html className="dark">Or use a theme provider to toggle dynamically. All components respond to the class automatically — no extra configuration.
Preview Before Installing
Use --dry-run to see what a command would do without writing files:
npx visor add button --dry-runManual Setup (non-Next.js)
If you are not using Next.js:
- Install the token package:
npm install @loworbitstudio/visor-core- Import tokens in your global CSS:
@import "@loworbitstudio/visor-core";- Import the element reset, unless you already ship Tailwind preflight or your own:
@import "@loworbitstudio/visor-core/reset";See The Element Baseline below for why both imports are needed.
- Initialize the CLI config:
npx @loworbitstudio/visor init- Add components as usual:
npx visor add buttonThe Element Baseline
Two independent things must be true before a Visor component renders in your theme's font. Apps that get one but not the other end up with a page in the brand font and buttons in Arial — the most common styling bug in a fresh Visor project.
1. Origination — bind the font to the page
Browsers never apply --font-body on their own; something has to write it onto an element. visor init and visor theme apply --adapter nextjs emit this into your generated globals.css:
@layer visor-base {
body {
font-family: var(--font-body);
font-size: 1rem;
color: var(--text-primary);
background: var(--surface-page, var(--surface-background));
}
}2. Propagation — let form controls opt back in
<input>, <textarea>, <select> and <button> do not inherit font-family from their ancestors — the browser's UA stylesheet pins them to a system font. One import fixes every control at once:
@import "@loworbitstudio/visor-core/reset";Beyond font inheritance, the reset also sets box-sizing: border-box globally (which every sized Visor control assumes), zeroes the UA margin Safari and Firefox apply to form controls, normalises <button> chrome, and strips Safari's search pill and the number-input spinners.
Why it ships in the tokens package
Components are copy-and-own: npx visor add input copies the file into your repo. A fix made inside a component can never reach an app that vendored it earlier, so per-component patches drift permanently. npm is the only channel Visor has that propagates automatically — so the baseline rides @loworbitstudio/visor-core and reaches you on npm update.
Opting out
The reset is a separate export. @loworbitstudio/visor-core, /css, /tokens and /primitives emit no element rules whatsoever, so a project on Tailwind preflight simply deletes the one @import line and is byte-unchanged.
Cascade safety
Everything above lives in @layer visor-base — the lowest-priority Visor layer. Your own unlayered body { … } wins over it, and component .module.css (which uses no @layer at all) beats it unconditionally. Author-origin styles still outrank the browser's UA stylesheet regardless of layer, so the reset does its job without ever competing with your code.
Checking your setup
npx visor check design ./srcThe missing-visor-base-layer warning fires when a project renders Visor form controls but imports neither the reset nor Tailwind preflight — and also when the installed @loworbitstudio/visor-core predates the /reset export, in which case run npm update @loworbitstudio/visor-core. If you have deliberately opted out, silence it in .visorrc.json:
{ "disabledRules": ["missing-visor-base-layer"] }Next Steps
- Migration Guide — Retrofit an existing project to Visor
- Themes — Learn about the 3-tier token architecture
- CLI Reference — Full list of CLI commands
- Components — Browse the full component catalog