Installation

July 20, 2026 · View on GitHub

This guide covers installing Sketchy and creating your first sketch. For a concise feature overview (builtins, snapshots, keyboard shortcuts), see the README.

Installation

Prerequisites

Sketchy needs a recent Go toolchain (see the root go.mod for the minimum version). Ensure go is on your PATH.

On Windows you can use the native Go toolchain; you do not need WSL unless you prefer it.

Install the sketchy CLI

go install github.com/aldernero/sketchy/cmd/sketchy@latest

Put $(go env GOPATH)/bin (or your GOBIN directory) on your PATH so the sketchy command is available in any terminal.

Running the examples

Each program under examples/ is a main package in the same module. From any directory you can run one with a tagged version:

go run github.com/aldernero/sketchy/examples/simple@latest

Change simple to another example folder name as needed.

If you have a local clone of the repository, you can instead:

cd examples/simple
go run .

How a sketch is structured

A sketch is plain Go code—there is no sketch.json for controls.

  1. Call sketchy.New with a sketchy.Config (window title, sketch size, colors, optional defaults for canvas background/foreground/stroke width, etc.).
  2. Set BuildUI to a function that registers controls with sketchy.UI (FloatSlider, IntSlider, Checkbox, ColorPicker, Dropdown, Folder, …).
  3. Set Updater and Drawer.
  4. Call Init (opens sketch.db, builds the control map, applies defaults).
  5. Configure Ebitengine (window size/title from WindowSize, etc.) and run ebiten.RunGame.

Control values are read by folder and name. Use "" for the root folder. Helpers like Slider / Int are shorthand for the root folder only.

Creating a new sketch with the CLI

sketchy init sketch hello_circle
cd hello_circle

Typical layout after init:

hello_circle/
├── go.mod
├── go.sum
├── main.go
└── .gitignore

sketchy init copies the embedded template, runs go mod init and go mod tidy. The template includes a sample buildUI, empty update/draw, and optional icon.png loading if you add that file next to main.go.

The project type is required: sketchy init sketch <name> draws on the CPU canvas with a Drawer, while sketchy init shader <name> renders a GPU Kage fragment shader whose //sketchy: directives auto-generate the control panel — the generated project includes a live-reloading fragment.kage.

Run the project from its directory:

go run .

Or from anywhere above it:

sketchy run hello_circle

Example: “Hello Circle”

We’ll turn the template into a minimal circle demo: two float sliders at the root folder (radius and thickness$), \text{an} 800 \times 800 \text{sketch}, \text{and} \text{a} $draw function that reads those values.

1. Adjust buildUI

Replace the template’s buildUI with two sliders (names must match what you pass to Slider / GetFloat):

func buildUI(_ *sketchy.Sketch, ui *sketchy.UI) {
	ui.FloatSlider("radius", 0, 300, 150, 1)
	ui.FloatSlider("thickness", 0, 10, 2, 0.1)
}

FloatSlider takes name, min, max, initial, step (in pixels, like all canvas units in Sketchy). The value column is a text field (you can type numbers, including forms like 1e-3); the track shows position only.

To group controls under a header, wrap them in ui.Folder("Shape", func() { … }) and then use s.GetFloat("Shape", "radius") instead of s.Slider("radius").

2. Set sketch size in Config

In main, pass the size you want (template defaults are larger):

s := sketchy.New(sketchy.Config{
	Title:        "Hello Circle",
	SketchWidth:  800,
	SketchHeight: 800,
})

You can also set ControlOutlineColor, DefaultBackground, and other fields on Config. The margin around the sketch follows the Builtins Dark/Light theme (grey), not SketchBackgroundColor.

3. Implement draw

Import image/color for explicit stroke color if you like (the framework also sets default stroke from Builtins before Drawer runs):

func draw(s *sketchy.Sketch, c *render.Context) {
	radius := s.Slider("radius")
	thickness := s.Slider("thickness")
	c.SetStrokeColor(color.White)
	c.SetStrokeWidth(thickness)
	c.DrawCircle(c.Width()/2, c.Height()/2, radius)
	c.FillStroke()
}

Slider is equivalent to GetFloat("", "radius"). The second argument to draw is a gaul render.Context; coordinates are pixels with the origin at the top-left (y down). See the render package docs for paths, transforms, and text.

Leave update empty for this example, or use it when you need animation or to react to DidControlsChange.

Run go run . again. You should see the sliders and a centered circle whose radius and stroke you can edit.

hello_circle_blank

simple_example_screenshot

A finished version of this idea (with a Shape folder) lives in examples/simple/main.go.

Saving images and snapshots

Quick saves are not bound to single-letter keys by default. Use the Builtins section of the control panel:

  • Save Image… — PNG and/or SVG under saves/png and saves/svg (relative to the process working directory, usually your project).
  • Take Snapshot… / Load Snapshot… — Store and restore control state in sketch.db, including a builtin_json payload (default colors, stroke width, seed) alongside control_json.

See the README for keyboard shortcuts (seed nudge, panel visibility) and other builtins.