VisorVisor
Guides

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 nextjs

That single command scaffolds a complete, runnable Next.js App Router project pre-wired with Visor — no second setup step:

What you getWhy it matters
Full package.json with next, react, TypeScriptRun npm run dev immediately
@loworbitstudio/visor-core + @loworbitstudio/visor-theme-engine installedTokens and FOWT helpers are already there
.visor.yamlYour theme — edit colors, typography, radius, shadows
app/globals.cssGenerated from .visor.yaml by the Next.js adapter
app/layout.tsx with FOWT script + globals.css importedNo flash of wrong theme on hard reload
.lo/borealis.jsonStamp recording the Visor version that initialized the project

Then start the dev server:

cd my-app && npm run dev

Heads up: visor init --template nextjs only scaffolds into empty directories — it refuses if package.json already 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 nextjs

The 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 form

Components 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-dashboard

Dark 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-run

Manual Setup (non-Next.js)

If you are not using Next.js:

  1. Install the token package:
npm install @loworbitstudio/visor-core
  1. Import tokens in your global CSS:
@import "@loworbitstudio/visor-core";
  1. 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.

  1. Initialize the CLI config:
npx @loworbitstudio/visor init
  1. Add components as usual:
npx visor add button

The 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 ./src

The 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