Skip to content

Creating a Project

Start an Inertia application from sillohq/starter-inertia. The two development processes, and every task the project ships with.

sillohq/starter-inertia is a working application: session authentication, a persistent layout, server-side validation whose errors render on the form, Record, a queue, and a production asset pipeline. You copy it and make it yours.

Terminal window
sillo-start create-app sillohq/starter-inertia myapp
cd myapp

Install it once if you have not already, uv tool install sillo-start, or pip install sillo-start. See Creating a Project.

Then install dependencies and set the database up:

Terminal window
uv sync
npm install
uv run sillo db:migrate

sillo-start takes the repository as an argument. There is no --inertia flag, because it fetches a real starter rather than rendering a template. It renames the project to yours and writes a .env with fresh secrets.

Node is required here as well as Python, because the front end is compiled. npm install is the one step the standard starter does not have.

Everything on Creating a Project applies here too. The requirements, what sillo-start does to the files, using your own starter. This page covers what is different.

This is the part that catches everyone once.

Terminal window
uvicorn app:app --reload # the application, on :8000
npm run dev # the Vite dev server, on :5173 — second terminal

Then open http://127.0.0.1:8000.

Both are required. The page is served by Sillo, but it loads its JavaScript from Vite, so with only uvicorn app:app running you get a blank page and a console full of failed module requests. With only npm run dev you get nothing at all. Vite serves modules, not your application.

They are kept as two commands rather than one wrapper on purpose: running both under a single process hides which one printed an error, and the HMR output is worth having where you can see it.

Everything the project does is either the sillo command or an npm script. sillo on its own lists what this project can do.

uvicorn app:app --reloadThe application, with reload. Needs npm run dev alongside
npm run devThe Vite dev server
sillo db:migrateApply every pending migration
sillo db:make add_posts --applyWrite a migration and apply it
sillo db:planShow which migrations would run
sillo db:rollback 0001_initialRoll back to a migration
sillo user:admin ada@example.com adaCreate an administrator
sillo user:listList users
sillo queue:workRun the queue worker
npm run buildCompile the front end into static/build
npm run typecheckType-check the front end
uvicorn app:appRun as production would. Needs npm run build and VITE_DEV=false
pytestThe Python suite
ruff check . / ruff format .Lint, checking or fixing

See The Console for what the sillo commands do and how to add your own.

pytest runs the Python suite. The tests drive real requests through the application and assert on the page object, so they cover the handler, the props, and the adapter together.

What CI runs, in this order:

Terminal window
ruff check . && ruff format --check .
npm run typecheck
npm run build
pytest

The build before pytest is not incidental. The production-asset tests skip themselves when there is nothing built, and a check that silently skips its most fragile assertions is not a check.

A blank page with failed module requests. npm run dev is not running, or VITE_DEV=false is set with nothing built.

Every module blocked by CORS. The browser is on the Sillo origin and pulls modules from Vite’s, which is cross-origin. server.cors in vite.config.ts is set for this reason. Removing it renders the page blank with only a console error to say so.

A full page refresh on every save instead of HMR. Vite guesses the HMR host from the page, which is the Sillo origin rather than its own. server.hmr.host states it.