Skip to content

Field manual

Getting Started
GuidePage01

Getting Started

Install Sol, connect the compiler, and mount a first reactive component.

Sol is an experimental JSX framework whose compiler turns components into static HTML templates plus narrowly scoped DOM operations. Component setup runs once per mounted instance; reactive changes patch only the work that depends on them.

Install the packages

Add the browser runtime, compiler, and Vite:

example.sh
bun add solbun add --dev @sol/compiler vite

Enable the compiler before Vite transforms JSX:

example.ts
import { sol } from "@sol/compiler/vite";import { defineConfig } from "vite";export default defineConfig({ plugins: [sol()] });

Set TypeScript's jsxImportSource to sol, then mount a compiled component into a real DOM element. Validate that mount boundary instead of assuming it exists.

First light

This source is both the code-panel content and the component running beside it.

Live Sol / compiled

Your first reactive component

FirstCounter.tsx
import { $component } from "sol";const FirstCounter = $component(function FirstCounter() {  let count = 0;  const doubled = count * 2;  return (    <section class="border-[3px] border-ink bg-paper p-6 shadow-block-sm">      <p class="font-mono text-xs font-bold uppercase text-cobalt">Reactive output</p>      <output class="mt-4 block font-display text-6xl" aria-live="polite">{count}</output>      <p class="mt-2 font-mono text-sm">Doubled: {doubled}</p>      <button class="mt-6 border-[3px] border-ink bg-solar px-4 py-3 font-mono text-xs font-bold uppercase shadow-block-sm" onClick={() => count++}>Add one</button>    </section>  );});

Reactive output

0

Doubled: 0

Writable declarations become signals and directly derived constants become computed values. Inside a compiled component, reads and assignments stay ordinary—there is no .value ceremony.

Mount the application

example.tsx
import { mount } from "sol";import { App } from "./App.tsx";const target = document.querySelector("#app");if (!target) throw new Error("The #app mount target is missing");mount(App, target);

Continue with the mental model before reaching for manual reactive primitives. Most application state belongs directly inside a compiled component.

Sol

Experimental JSX framework / Sunblock system

Static blocks + precise motion