Skip to content

What's in the Box

What `uv add sillo-framework` actually installs, which subsystems are extras you opt into, which live in separate packages, and the tools that sit alongside the framework.

Sillo is described as batteries-included, which is true about its surface and misleading about its install. The base install is five packages. Everything that carries a third-party dependency is something you ask for.

This page is the map: what comes with the framework, what is one flag away, what is a separate install, and what is a tool rather than a library.

Terminal window
uv add sillo-framework

Five dependencies: uvicorn, anyio, python-multipart, pydantic, and typing-extensions below Python 3.13. Python 3.10 or newer.

What that gives you, with no further installs:

Note what is not on that list: a database, a Redis client, and a JWT library.

Each of these adds one dependency, for one subsystem.

ExtraBringsFor
recordtortoise-ormThe ORM — models, migrations, factories
jwtpyjwtJWT authentication
cacheredisCaching across processes
eventsredisEvent distribution across processes
cryptocryptographyThe encrypted cast and sillo.helpers.crypto
storage-s3httpxThe S3 storage driver
mailjinja2Templated email bodies
hashing-bcryptbcryptbcrypt password hashing
hashing-argon2argon2-cffiArgon2 password hashing
hashing-scryptscryptscrypt password hashing
hashing-allall three, plus passlibAll of the above
graniangranianAn alternative ASGI server to uvicorn
alleverything aboveNot thinking about it
Terminal window
uv add "sillo-framework[record,jwt,hashing-argon2]"
uv add "sillo-framework[all]"

Two of these are worth a second look. The S3 driver depends on httpx rather than boto3 — request signing is a few dozen lines of HMAC, and boto3 is a very large synchronous dependency to carry for it. And the hashing extras are separate rather than bundled because a project standardises on one algorithm; installing three compiled backends to use one is exactly the imposition the extras exist to avoid.

These are not extras. They are their own distributions, versioned and released on their own cadence, because each has a dependency, a release rhythm, or a scope that the framework should not carry on everybody’s behalf.

PackageInstallImportWhat it is
Wiresillo-wiresillo.wireRooms, presence, replay and fan-out for WebSockets
GraphQLsillo-graphqlsillo.graphqlA production GraphQL endpoint over a Strawberry schema
WarderwarderwarderA declarative admin panel over your models, with a React interface
Inertiasillo-inertiasillo_inertiaServer-driven pages with React or Vue, no API layer
OAuthsillo-oauthsillo_oauthSocial login and OAuth2 providers

Wire and GraphQL extend the framework’s own surface, so they also take a name inside it: from sillo.wire import Hub and from sillo_wire import Hub bind the same class. The others keep their own top-level names — Warder most deliberately of all, because it is not an extension of sillo but an application you mount on yours. The Packages index explains how the aliasing works and why it is not a directory shipped into the framework.

Not libraries you import — programs you run.

ToolInstallWhat it does
silloships with the frameworkMigrations, users, queues, the scheduler, and your own commands
sillo-startuv tool install sillo-startCreates a project by copying a working application, not by generating one
sillo-viseuv add sillo-visevise serve — the development server, with readable logging and the Foreman operations dashboard mounted beside your app
@sillo/atlasnpmThe OpenAPI reference UI and API client, ~79 KB with no runtime dependencies

If you are reading 0.x code or older articles, four things are not where they used to be.

Was, in 0.xIs, in 1.0
Built-in admin panelwarder
HTML templating layer (Jinja)Removed; mail is the one place a template is still rendered
WebSocket rooms, channels and groupssillo-wire
sillo.graphql in the frameworksillo-graphql, claiming the same import name

The same reason applies to all four: each had grown a dependency, a release cadence or a scope of its own. A package that claims a name the framework still uses refuses to load and says so, rather than quietly shadowing it — which is why sillo-graphql works against 1.0 and not against 0.x.

A useful default for a JSON API with users and a database:

Terminal window
uv add "sillo-framework[record,jwt,hashing-argon2]"

Add cache and events when you run more than one process. Add sillo-wire when WebSockets need rooms rather than connections. Add warder when somebody who is not you needs to edit the data. Add nothing else until something asks for it.

If you would rather start from a working application than assemble one, sillo-start copies the official starter — session auth against a real user model, migrations, a JSON API and a queue, all already wired together.