Adam Bobowski

September 2025

Stario release 0.1.0

Today I'm releasing first version of Stario. It's a very "0.1.0" version but I decided to release it a bit earlier than planned. Available at github.com/Bobowski/stario, and also on pypi as pip install stario.

Stario logo

My main goals with this framework are the following:

  • Code should show as much intent as possible (that's why dedicated Query and Command objects rather than focusing on https methods like get and post or others).
  • Play and joy first experience. Hide SDKs and make this a "playground" first experience. I believe that things done from exploration are much more likely to be successful and enjoyable.
  • Focus on teaching web rather than language frameworks. My hope is that once you know all ins and outs of this (and Datastar) framework you will actually stop using them and realize how much simpler some of the stuff could be. (For me this is a big reason why I'm building this.)
  • I want to learn more myself. And best way to do that is to build something. Stario is my playground.
  • Never obfuscate, don't reinvent the wheel. Stand on the shoulders of giants.

What Stario is 100% not:

  • It's not a performance oriented framework. Python was never meant to be fast. (Consider this a point that relates to ALL python frameworks.)
  • If you don't need exploration and experimentation - probably could be better off with something more mature.

Quick example of how to use Stario:

# main.py
import asyncio
from stario import Stario, Query, Command
from stario.toys import ToyPage


async def home():
    return ToyPage(
        """
        <h2>Realtime responses!</h2>
        <div data-on-load="@get('/online-counter')">
            This shows how long the connection has been open.
        </div>
        <div id="online-counter"></div>
        """
    )


async def online_counter():
    duration = 0
    interval = 0.01
    while True:
        # Yielding strings/patches streams as SSE with DataStar-compatible events
        yield f"<div id='online-counter'>Online since: {duration:.1f}s</div>"
        duration += interval
        await asyncio.sleep(interval)


# Building the app
app = Stario(
    Query("/", home),
    Query("/online-counter", online_counter),
)

Main Stario object is ASGI compatible application, so we can just run it with uvicorn.

uvicorn main:app --reload

From DX perspective developer should focus on how the information flows through the app. When it's an interaction it should probably be represented as a Command object. If that's read-oriented - it should be represented as a Query object.

When we need to stream data to user over time (eg updates / notifications / etc) - we can just yield them.

Next steps

Stario definitely needs standalone documentation and examples. I'm working on it as of writing this, but it's not ready yet. Building a good pallet of examples and references is where's my focus for now.

I'm also thinking about adding more features that would make this more usable. Testing and CI/CD are also on the horizon.

There's just so much to do. But I'm excited to keep working on it and see where it goes.

About Adam Bobowski

Adam is a software engineer with a passion for building products that help people live better lives.