Build real apps
in Pure Python
Streamlit-like authoring, without the rerun ceiling.
Violit gives you fine-grained reactivity for data apps, internal tools, admin panels, and user-facing products, with built-in ORM and auth, Tailwind-first design, background workflows, interval timers, and desktop mode in one Python stack.
pip install violit
Built for the apps people actually ship
Violit keeps the top-down Python flow people love, then adds the app stack needed for real products: fast reactivity, data, access control, design, and long-running workflows.
Fine-Grained Reactivity
Keep the Streamlit-like authoring style, but update only the widgets that actually depend on changed State instead of rerunning the whole script.
Pure Python Flow
Build interfaces, state, data flow, and page logic in Python without switching into a separate frontend stack for common app work.
Built-in App Stack
Use built-in ORM and auth together: define SQLModel models, run CRUD with app.db, register users once, and protect pages with auth and roles.
Tailwind-First Styling
Use cls first for fast, expressive design, then go deeper with configure_widget(), add_css(), and part_cls.
Background + Interval Workflows
Handle long-running jobs, polling loops, live dashboards, timers, and progress feedback with app.background() and app.interval().
Browser, Lite, Desktop
Ship the same Python app to the browser, lower-overhead lite mode, or a native desktop window without rewriting the app model.
Data Apps to Product UIs
Start with dashboards and data tools, then keep going into CRUD screens, internal platforms, admin panels, and more general web applications.
Widgets, Themes, and Design Surface
Combine rich widgets, built-in themes, utility classes, gradients, and CSS variables to make polished interfaces without leaving Python.
Prototype to Production
Start with a quick Python prototype, then keep the same Violit app as it grows into an internal tool, customer portal, or shipped product UI.
Try it yourself
Reactive state, instant updates, no page reload.
CURRENT COUNT
0
count = app.state(0)
app.text(count) # Auto-updates!
def inc(): count.set(count.value + 1)
app.button("+", on_click=inc)
Drag the sliders — the result updates instantly.
TOTAL
30 + 70 = 100
a = app.slider("Value A", 0, 100, 30)
b = app.slider("Value B", 0, 100, 70)
# Combine states and strings directly
app.text(a + " + " + b + " = " + (a + b))
name = app.text_input("Your name", value="Developer")
# Use lambda for complex HTML interpolation
app.html(lambda: f'''
<div style="font-size: 2.5rem; font-weight: 700;">
👋 Hello, <span style="background: linear-gradient(135deg, #ec4899, #f97316);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;">
{name.value}
</span>!
</div>
''')
© 2026 Violit Framework. MIT License.