Tutorial: Before you start

Tutorial

Before you start

This tutorial builds a small reading list: a page of books you can add to and tick off, a page per book, and a server that keeps them in SQLite. Each step adds one idea, and every step ends with something that runs.

By the end you'll have used:

  • $state and $derived for values that update the page when they change
  • components with props and scoped styles
  • file-based routes, layouts, and URL parameters
  • load functions that fetch data on the server
  • form actions that work with and without JavaScript
  • a production build you can run in Docker

The whole thing is under 200 lines. Each step shows the complete files it changes, so you can copy them as they are.

What you need

  • Bun 1.2 or newer. Sigil runs on Bun everywhere: the dev server, the build, and production.
  • An editor that understands TypeScript. Sigil components are .tsx files.

You don't need to know React or Svelte, but if you do, most of the syntax will look familiar: it's JSX, with reactivity borrowed from Svelte's runes.

Create the project

bunx @sigil-dev/cli create reading-list
cd reading-list
bun run dev

create writes the project, installs dependencies, and makes a first git commit. bun run dev starts the dev server on http://127.0.0.1:3000. Open it and you'll see the starter page with a counter.

Leave the dev server running for the rest of the tutorial. It rebuilds on save and reloads the page.

What's in it

reading-list/
  package.json        scripts: dev, build, start, routes
  sigil.config.ts     port and routes directory
  tsconfig.json       editor settings for Sigil's JSX
  public/
    style.css         served as /style.css
  src/routes/
    +layout.tsx       wraps every page
    index.tsx         the page at /
    about.tsx         the page at /about

Everything under src/routes is a page or part of one. The file name decides the URL: index.tsx is /, about.tsx is /about. Step 4 covers the rest of the naming rules.

Files in public/ are served as they are, before any route is matched.

The build writes to .grimoire/ and public/__grimoire__/. Both are generated, and both are in .gitignore.

Start with step 1: state and events.

Edit this page