A shoutout to Stario, the Python framework behind 12 of my projects

Card reading One framework, 12 projects, with a single source fanning out to five live clients

Twelve of the projects on my full build list run on the same Python framework - Stario, written by my friend Adam Bobowski. One app deleted four dependencies the day it moved over. Another pushes live updates to every open browser with no Redis and no broker. This is a tour of what I built on it, and a thank-you.

In this post:

What Stario is

Stario is a Python web framework for realtime hypermedia apps by Adam Bobowski. MIT license, source on GitHub.

The PyPI tagline reads "Craft realtime hypermedia apps that are a joy to write and ship." First release was September 2025, and as of 15 October 2026 PyPI is already at 5.0.4 - Adam moves fast.

What a Python dev actually gets:

I've been building on it since January. On my servers today: 2.0.1 on the demos, 2.0.5 on fix-wp, 2.2.1 on TeleChat, 3.4.0 on ShipSwipe, 4.0.1 on kiedy, 4.1.x on Impostor and the quiz, 4.2.0 on the newest project, 4.3.0 on my internal tools. I grew up with this framework, breaking changes and all.

kiedy - date planning without logins

kiedy ("when?" in Polish) answers the question every group chat argues about: which day works for everyone? You create an event, share the link, and each person votes on the proposed dates. The best date lights up live as votes come in. No accounts or logins - the link is the whole thing.

A business-hours twin runs the same code at kiedy-biz.marcindudek.dev.

It started on FastAPI and uvicorn on July 21. A week later I moved it to Stario 4. The commit message from that port:

"Stario runs its own asyncio HTTP server, so uvicorn, starlette, datastar-py and python-multipart all go away; the app is now a bootstrap(app, span) generator with (Context, Writer) handlers."

Four dependencies deleted in one commit - 4 files, +236/-170. Every viewer holds one long GET /e/{slug}/feed stream backed by an asyncio.Queue. A vote is a short POST; the server re-renders #results and broadcasts patch_elements to every queue.

The systemd unit serving it:

ExecStart=/opt/kiedy/.venv/bin/stario serve main:bootstrap

That's the whole process model.

curlship - a launch directory bots can use

curlship is a launch directory where submitting your product is one POST - curl, a script, or an agent all work. Bots are welcome: it ships an MCP endpoint and agent-discovery files, so a bot can list a product without ever opening a browser. A badge on your site earns a dofollow link back, and paid tiers plus a Featured auction run through Dodo Payments.

On 15 October 2026 it listed 5,204 products, 191 of them added in the previous 24 hours. Ahrefs Domain Rating: 48.

The live feed is one Relay. Every write path calls publish("update"), and every open browser gets the new listing over SSE. A single process handles the whole directory and the realtime.

My agent dashboard

Not everything on Stario is public. My main internal tool is Manage Claude, a control panel for the multi-agent setup I work with - projects, products, tasks, blog posts, reports, and a live /work graph showing what each agent session is doing at any moment. It binds to my tailnet only, so there's no link to share.

On 13 October it moved from Stario 2.1 to 4.3. My frozen smoke suite went from 13 failures - one of them a real 500 - to 101/101 passing. The /work graph is fed by one long-lived SSE stream - no polling.

Product Hub

Same day, same migration. Product Hub is my registry of marketing assets - promo images, screenshots, OG images, descriptions - organized per product and sharing a database with the dashboard. It made the same jump, from Stario 2.1 to 4.3.

Impostor - a party game

Impostor is a real-time social-deduction word game. Everyone at the table gets a private card - most see the same secret word, and the rest drew blanks. You give clues, then vote out the blanks. 3 to 16 players, private rooms, chat, play-again, word packs in Polish and English.

Every room is a Relay topic. A player's stream subscribes to the room and re-renders the view on every publish, with a heartbeat that catches dead connections:

async with self.relay.subscribe(topic) as subscription, c.alive():
    while not c.closing:
        ...
        sse.patch_elements(views.room_view(view, session.csrf))
        await asyncio.wait_for(subscription.receive(), HEARTBEAT_SECONDS)

The whole game state lives in that one process. Idle seats are freed after 10 minutes.

TeleChat - live chat routed through Telegram

TeleChat is a self-hosted live-chat widget for websites. A visitor's message opens a thread in your Telegram group, you reply from your phone, and the answer streams back into their browser.

One ~30KB script tag on the site, one deploy per site, and the data stays on your server. It runs on a 256MB VPS and takes about 15 minutes to install.

Stario connects the two ends through a Relay[dict]: the Telegram webhook publishes, the visitor's GET /subscribe stream receives. The landing page puts it plainly: "No polling - replies stream over SSE and land instantly."

The Perfect World quiz

The Perfect World quiz asks you 12 questions about your moral intuitions across 8 axes. Then one LLM call turns the answers into a portrait of the world aligned with your values - including what that world had to give up.

Generation takes anywhere from 18 seconds to almost five minutes. On a request-response stack that's a long spinner. Here the portrait streams in over SSE while the model works, and you watch it arrive piece by piece.

ShipSwipe - co-founder matching

ShipSwipe is Tinder for co-founders. Builders swipe on marketers, marketers swipe on builders, and a mutual like becomes a match - then you connect or send an intro.

It's the largest of my Stario codebases - 24 files import it - and it sits on a proper stack: Postgres, SQLAlchemy async, Alembic, Redis, magic-link auth.

fix-wp - WordPress emergency repair

fix-wp is my emergency repair service for broken WordPress sites. The price is a flat $100, held escrow-style through Stripe manual capture - captured when the repair succeeds, refunded automatically when it doesn't. The first ten repairs are free while the launch promo runs. A worker runs a Claude CLI agent against the site, and you watch the whole thing live on the status page.

The status page is an SSE stream fed by Redis pub/sub. The worker is a separate process, so Redis carries the job events and Stario pushes them to the browser.

The Datastar demos

datastar.byst.re hosts my Datastar teaching demos: progressive page assembly, a typewriter stream, a live stock ticker, dictionary search across 235,976 words, and an RSVP speed reader.

This is the oldest of the bunch - the Stario version replaced the original FastAPI code back in January. It's pinned to 2.0.1 because later releases dropped the tracer it uses.

Still cooking

NPC Engine is an LLM-driven dialogue game on a knowledge-graph world - places, characters, items - with NPC replies streamed word by word. It's offline at the moment, so no link.

And grill, a localhost-only toy: a game master that interrogates me about my own game design one closed question at a time - contradictions first - and files the answers into a design vault.

There's a thirteenth deployment I can't show: a Stario reverse proxy in front of a client's internal tools.

The rough edges

Worth knowing before you start. Stario ships no form parser - parse_qsl covered everything kiedy needed. It exposes no peer address, so behind nginx I read X-Real-IP. And if you're hunting for benchmark numbers against FastAPI, I have none - I wrote a comparison script in the demos repo but never kept the results.

Thanks, Adam

The common shape across all of this: one Python process that serves pages and pushes live UI, with no ASGI server under it and usually no broker next to it. That shape is Adam's design.

So - thanks, Adam. For building the thing I keep reaching for, and for the pace: 0.1.0 shipped in September 2025, PyPI is on 5.0.4, and my oldest code still runs on 2.0.x.

If you write Python and your app wants live UI - a dashboard, a game, a feed, a status page - give it a look. Docs at stario.dev, source at github.com/bobowski/stario.

If you write it with Claude Code, my Stario skill is public. The framework is new enough that models guess at its API - they reach for keyword arguments where markup attributes take positional dicts, and for a decorator where routes come from the bootstrap(app, span) generator - so the skill hands them the real one: the Stario skill in claude-multitool.

Whatever I build next probably starts with bootstrap(app, span) too.