Violit: a Streamlit-style Python framework that swaps full script reruns for signals
Pure Python Web Framework. Streamlit simplicity, no reruns.
At a glance
- What is it?
- Violit keeps the top-down Python authoring style of Streamlit but replaces the full script rerun with fine-grained reactive updates, and adds an ORM, auth, Tailwind-like styling and desktop packaging on top of FastAPI. The README positions it for data apps that grow past the dashboard stage; the trade-off is a framework that asks you to learn its signal model instead of a callback model.
- Who is it for?
- Adopt Violit if your Streamlit app has grown into something where every click re-executes code you did not want to re-execute, and you are willing to learn a signal-based update model in exchange. Do not adopt it if you need a large third-party widget ecosystem today, or if you have no way to absorb breaking changes from a young project.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 98 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The rerun tax Violit is trying to remove
Streamlit's model is simple to describe: a user interacts, the whole script re-executes from the top, and the UI is rebuilt from the resulting state. That is why the README's Streamlit example is three lines and works. It is also why the README claims developers end up, in its words, constantly architecting around the full-rerun behavior. Caching decorators, session state guards and careful placement of expensive calls all exist to make the rerun affordable rather than to make it unnecessary.
Violit's pitch is that the rerun is unnecessary. The README states the framework preserves the top-down Python authoring style Streamlit users already know, but eliminates the full script rerun by using a fine-grained reactive architecture. In its own comparison table, the interaction cost for Streamlit is that the entire script may re-execute, while for Violit only explicitly dependent UI components update.
The intended audience is not someone writing their first dashboard. It is someone whose dashboard has accumulated enough interaction that the rerun model is now the thing they design around. The README also names admin tools, internal platforms, CRUD systems and user-facing product UIs as targets, which is a broader claim than data apps alone.
Signals instead of callbacks: the actual update mechanism
The README describes the engine as signal-based and compares the result to React-like reactivity. The mechanism it claims is dependency tracking: when a user clicks, types or drags, the framework identifies which UI components depend on the changed value and updates those, rather than re-running the script that produced them.
That is a different mental model from the callback frameworks in the README's own feature matrix. Dash and Panel are listed as no-full-rerun but callback-based, which means you wire up functions that fire on specific events and return what should change. Violit instead asks you to write code that reads state, and the framework works out what to re-render. The README's framing is that this removes the optimization burden, because you do not hand-manage which parts update.
What the supplied material does not give is the concrete signal API. There is no example of declaring a signal, reading one, or deriving a computed value in the excerpt provided. The README shows a NiceGUI binding example and a Streamlit example but no equivalent Violit snippet, so the exact syntax for the reactive core is something you would need to confirm in the docs rather than infer from this page. Treat the architecture description as a design claim, not as something you can pattern-match from the README alone.
Getting it running and the keys that configure it
The install line in the README is a single command:
pip install violit
Python 3.10 or newer is required, per the badge in the README. The framework is built on FastAPI, which the README lists as a badge and which matters for deployment: your app is a FastAPI application underneath, so the usual ASGI serving story applies.
Configuration surfaces named in the README:
vl.App(db=...) attaches a database through the built-in ORM. cls is the parameter used for Tailwind-like utility styling on components. app.background(...) registers a background task. app.interval(...) registers a recurring task.
The README lists three runtime modes: a WebSocket mode, an HTMX Lite mode described as being for higher concurrency, and a desktop native mode. It also states desktop packaging is built in via pywebview, which is what the feature matrix means by Desktop Native (exe/app).
The README does not include a complete runnable app in the excerpt supplied, so the exact call that starts the server, and how you select between the WebSocket, Lite and desktop runtimes, are not visible here. The docs link is https://doc.violit.cloud and the demo showcase is at https://demo-showcase.violit.cloud; both are where you would confirm the entry point before writing anything real.
Where the fine-grained model does not save you
Fine-grained reactivity solves one class of problem: unnecessary work triggered by a state change. It does not solve the other class, which is work you genuinely asked for. If a button click is supposed to run a query over a million rows, Violit will run it, and the fact that only three widgets re-render afterwards does not make the query faster. The README's performance language is about update granularity, not about making your own code cheap.
The second limitation is ecosystem. Streamlit has years of community components; the README's Violit section advertises out-of-the-box widgets, themes and animations, but does not claim parity with what has accumulated around Streamlit. If your app depends on a specific third-party Streamlit component, that dependency does not transfer.
The third is the learning curve that the README is honest about for other frameworks but quieter about for its own. The feature matrix credits Reflex with a steeper learning curve for people unfamiliar with React concepts. Violit's signal model is a React-adjacent concept. A developer who has only ever written Streamlit scripts is learning a new mental model, not just a new import. The README's own syntax section makes this point about NiceGUI, that explicit binding is excellent for component-driven design, and the same observation applies to signals: the model rewards people who think in components and asks something of people who do not.
Violit against NiceGUI, the closest structural match
Of the frameworks in the README's matrix, NiceGUI is the nearest neighbour: no full rerun, pure Python with zero JS or HTML, and desktop native support. Both target the same developer, someone who wants to stay in Python and still ship something interactive.
The difference is in how you bind state to UI. The README's NiceGUI example creates an input object, creates a label object, then calls bind_text_from on the label, passing the input and a lambda that formats the value. The binding is explicit and directional: you name the source, the target and the transformation. Violit's claim is that the signal architecture handles this naturally, so the dependency is inferred rather than declared.
That is a real difference in approach, not a cosmetic one. Explicit binding is easier to trace, because the connection between two widgets is a line of code you can read. Inferred dependency is less code to write and, in the README's framing, less workaround logic as the app grows. Which one is better depends on whether you would rather debug a graph you declared or a graph the framework derived.
The matrix also places Violit and Reflex on opposite sides of the SEO and SSR question, with Violit marked ready and Reflex marked ready as well, but Reflex flagged as requiring the React paradigm. Violit's bet is that you can have server-rendered output and a reactive front end without writing React.
Maintenance cost and the MIT licence
Violit is MIT licensed, which is permissive: you can use it commercially, modify it and redistribute it, provided the licence notice is preserved. That is the standard reading of MIT and it is not legal advice; check the LICENSE file in the repository for the exact text that governs your use.
The maintenance picture is harder to assess from the material supplied. There are no releases retrieved for this analysis, so there is no changelog to read for breaking-change frequency, and no version history to judge how the API has moved. The repository is not archived and the last push date is 2026-06-09, which indicates active work, but activity is not the same as stability.
What that means in practice: the cost of adopting Violit is not the licence, it is the upgrade path. A framework that is still adding runtimes, an ORM and desktop packaging is a framework whose internals are still moving. If you pin a version and never move, you inherit whatever bugs that version has. If you track main, you inherit whatever the next commit changes. Neither is free, and the README does not give you the release cadence you would need to pick between them. Budget for reading the changelog before each upgrade, and for the possibility that a minor bump touches the signal or App API.
Who this is for, and what to confirm before you migrate anything
The clearest fit is a team that already has a Streamlit app, has hit the point where reruns are the constraint, and wants to keep writing Python in a top-down style rather than move to React or to a callback framework. The built-in ORM and auth mean a single-file data app can grow into something with users and persistence without bolting on a separate backend, and the pywebview path means the same code can ship as a desktop binary.
The poor fit is anyone whose app depends on a specific Streamlit ecosystem component, anyone who needs a large catalogue of pre-built widgets today, and anyone who cannot afford to absorb API churn in a framework that is still expanding its surface area. If your app is a handful of charts and a table, the rerun model is probably not your bottleneck and you gain little by switching.
Before migrating, confirm the run command and runtime selection in the docs, since the README excerpt does not show them. Confirm the signal API by writing one small app that reads and updates a single value, because that is the concept everything else rests on. And confirm the desktop build works on your target OS, since pywebview packaging is the claim in the README that depends most on platform specifics you cannot check from the README alone.
Editorial conclusion
Adopt Violit if your Streamlit app has grown into something where every click re-executes code you did not want to re-execute, and you are willing to learn a signal-based update model in exchange. Do not adopt it if you need a large third-party widget ecosystem today, or if you have no way to absorb breaking changes from a young project. Before committing, verify three things against the live docs at doc.violit.cloud: the install and run commands on your Python version, the exact App and signal API surface you plan to use, and whether the desktop packaging path works for your target OS.
Community notes