https://github.com/cacao-research/cacao
π« Cacao is a reactive Python web framework for building real-time apps with a decorator-based API, component state management, JSON UIs, and WebSocket-powered updates. Ideal for dashboards, internal tools, and hybrid apps (web & desktop).
https://github.com/cacao-research/cacao
cacao framework interfaces pwa python python-gui pythonic toolkit web-framework webapp
Last synced: 3 months ago
JSON representation
π« Cacao is a reactive Python web framework for building real-time apps with a decorator-based API, component state management, JSON UIs, and WebSocket-powered updates. Ideal for dashboards, internal tools, and hybrid apps (web & desktop).
- Host: GitHub
- URL: https://github.com/cacao-research/cacao
- Owner: cacao-research
- Created: 2025-03-26T05:28:29.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-03-05T07:10:30.000Z (3 months ago)
- Last Synced: 2026-03-05T09:58:53.764Z (3 months ago)
- Topics: cacao, framework, interfaces, pwa, python, python-gui, pythonic, toolkit, web-framework, webapp
- Language: Python
- Homepage: https://pypi.org/project/cacao/
- Size: 2.5 MB
- Stars: 14
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README

# Cacao
**High-performance reactive web framework for Python.**
Build dashboards, internal tools, and data apps with a simple API β real WebSocket reactivity, not full-page reruns.
[](https://pypi.org/project/cacao/)
[](https://pepy.tech/project/cacao)
[](https://pypi.org/project/cacao/)
[](https://github.com/cacao-research/Cacao/blob/main/LICENSE)
[](https://github.com/cacao-research/Cacao/actions/workflows/ci.yml)
[](https://github.com/cacao-research/Cacao/actions/workflows/pages.yml)



[](https://github.com/cacao-research/Cacao/stargazers)
[Features](#-features) Β· [Quick Start](#-quick-start) Β· [Examples](#-examples) Β· [Components](#-components) Β· [Architecture](#-architecture) Β· [Static Builds](#-static-builds) Β· [Contributing](#-contributing)
---
> **v2.0** β Complete rewrite with signal-based reactivity, session-scoped state, plugin hooks, and a Streamlit-like API that doesn't re-run your entire script.
## Quick Start
```bash
pip install cacao
```
```python
import cacao as c
c.title("Hello, Cacao!")
c.text("Welcome to the simplest Python web framework")
```
```bash
cacao run app.py
```
That's it β 3 lines of Python and you have a live web app with hot reload.
---
## Why Cacao?
| Feature | Cacao | Streamlit |
|---------|-------|-----------|
| **Reactivity** | Signal-based (only changed values update) | Full script re-run on every interaction |
| **State** | Session-scoped by design | `st.session_state` bolt-on |
| **Updates** | WebSocket streaming (instant) | HTTP polling (laggy) |
| **Multi-user** | Isolated sessions built-in | Shared state issues |
| **API** | Context managers + decorators | Magic globals |
| **Static export** | `cacao build` β no server needed | Not supported |
---
## Features
### Reactive Signals
```python
count = c.signal(0, name="count")
@c.on("increment")
async def increment(session, event):
count.set(session, count.get(session) + 1)
```
Signals are the core of Cacao. When a value changes, only the affected components update β no full-page reruns, no diffing your entire tree.
### 60+ Built-in Components
Layouts, forms, charts, display elements, navigation β everything you need out of the box.
### Multi-Page Apps
```python
with c.page("/"):
c.title("Home")
with c.page("/settings"):
c.title("Settings")
```
Hash-based routing works both in server mode and static builds.
### Static Builds
```bash
cacao build app.py
```
Export your app to a static site (HTML + JS + CSS) that runs entirely in the browser. Deploy to GitHub Pages, Netlify, or any static host β no Python server required.
### Plugin Hooks & Auth
Extensible architecture with plugin registration, authentication hooks, and notification toasts.
### Dark & Light Themes
```python
c.config(theme="dark") # or "light"
```
---
## Examples
### Interactive Counter
```python
import cacao as c
c.config(title="Counter")
count = c.signal(0, name="count")
@c.on("increment")
async def increment(session, event):
count.set(session, count.get(session) + 1)
@c.on("decrement")
async def decrement(session, event):
count.set(session, count.get(session) - 1)
c.title("Counter")
with c.card():
c.metric("Count", count)
with c.row():
c.button("-", on_click="decrement", variant="secondary")
c.button("+", on_click="increment")
```
### Dashboard with Charts
```python
import cacao as c
c.config(title="Sales Dashboard", theme="dark")
sales = c.sample_sales_data()
c.title("Sales Dashboard")
with c.row():
c.metric("Revenue", "$45,231", trend="+20.1%", trend_direction="up")
c.metric("Orders", "1,247", trend="+12.5%", trend_direction="up")
c.metric("Customers", "842", trend="+5.3%", trend_direction="up")
with c.row():
with c.col(span=8):
with c.card("Revenue Trend"):
c.line(sales, x="date", y="revenue", area=True)
with c.col(span=4):
with c.card("By Category"):
c.pie(sales[:5], values="revenue", names="category", donut=True)
with c.card("Recent Transactions"):
c.table(sales[:10], columns=["date", "category", "revenue", "orders"])
```
More examples in the [`examples/`](examples/) directory:
| Example | Description |
|---------|-------------|
| [`simple/hello.py`](examples/simple/hello.py) | Minimal hello world |
| [`simple/counter.py`](examples/simple/counter.py) | Interactive counter with signals |
| [`simple/metrics.py`](examples/simple/metrics.py) | KPI dashboard |
| [`simple/dashboard.py`](examples/simple/dashboard.py) | Full dashboard with charts |
| [`chat/app.py`](examples/chat/app.py) | Chat application |
| [`todo/server.py`](examples/todo/server.py) | Todo list app |
| [`analytics_dashboard/`](examples/analytics_dashboard/) | Analytics dashboard |
---
## Components
### Layout
| Component | Description |
|-----------|-------------|
| `row()` | Horizontal flex layout |
| `col(span=N)` | Column with 12-grid span |
| `grid()` | CSS grid layout |
| `container()` | Centered container |
| `stack()` | Vertical stack |
| `split()` | Side-by-side split |
| `hero()` | Hero section |
| `card()` | Card container |
| `tabs()` / `tab()` | Tabbed content |
| `accordion()` | Collapsible sections |
| `modal()` | Modal dialog |
| `panel()` | Sliding panel |
| `app_shell()` | Full app layout with sidebar |
### Display
| Component | Description |
|-----------|-------------|
| `title()` / `text()` | Typography |
| `markdown()` | Markdown with optional TOC |
| `code()` | Syntax-highlighted code |
| `metric()` | KPI metric with trend |
| `table()` | Data table |
| `json_view()` | Interactive JSON viewer |
| `badge()` / `alert()` | Status indicators |
| `progress()` | Progress bar |
| `image()` / `video()` | Media |
| `timeline()` | Timeline display |
| `diff()` | Side-by-side diff viewer |
| `breadcrumb()` | Navigation breadcrumb |
### Form
| Component | Description |
|-----------|-------------|
| `button()` | Button with variants |
| `input_field()` | Text input |
| `textarea()` | Multi-line input |
| `select()` | Dropdown select |
| `checkbox()` / `switch()` | Toggle inputs |
| `slider()` | Range slider |
| `date_picker()` | Date picker |
| `search_input()` | Search with suggestions |
| `file_upload()` | File upload |
| `chat()` | Chat input interface |
### Charts
| Component | Description |
|-----------|-------------|
| `line()` / `area()` | Line and area charts |
| `bar()` | Bar chart |
| `pie()` / `donut()` | Pie and donut charts |
| `scatter()` | Scatter plot |
| `gauge()` | Gauge meter |
| `heatmap()` | Heatmap |
| `radar()` | Radar chart |
| `funnel()` | Funnel chart |
| `treemap()` | Treemap |
---
## Architecture
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PYTHON SERVER β
β ββββββββββββ ββββββββββββ ββββββββββββ βββββββββββββββββ β
β β Signals β β Sessions β β Events β β WebSocket/HTTPβ β
β β (state) ββββ (per- ββββ (typed ββββ Server β β
β β β β client) β β async) β β (Starlette) β β
β ββββββββββββ ββββββββββββ ββββββββββββ βββββββββ¬ββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββ
β JSON
β WebSocket
ββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββ
β REACT CLIENT β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββ΄βββββββ β
β β Hooks β βComponentsβ β Event β β State β β
β βuseCacao()ββββ (60+ UI) ββββDispatcherββββ Store β β
β ββββββββββββ ββββββββββββ ββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
**Data flow:**
```
Python API β JSON definition β WebSocket β React renders
β β
Signal.set() βββ Event handler βββ User action
```
---
## CLI
```bash
cacao run app.py # Run with hot reload
cacao run app.py --port 3000 # Custom port
cacao run app.py --no-reload # Disable hot reload
cacao create my-dashboard # Scaffold a new project
cacao build app.py # Build static site
cacao build app.py --base-path /repo # For GitHub Pages subdirectory
```
---
## Static Builds
Cacao generates static sites that run entirely in the browser β no Python server required.
```bash
cacao build app.py
```
Output:
```
dist/
βββ index.html # Your app
βββ cacao.js # Runtime + built-in handlers
βββ cacao.css # Styles
```
**Built-in client-side handlers** for common operations:
- **Encoders** β Base64, URL, HTML entities, JWT decode
- **Generators** β UUID, passwords, Lorem Ipsum
- **Converters** β JSON/YAML, case conversion, number bases
- **Text** β Statistics, regex testing
- **Crypto** β Hash generation, HMAC
Deploy to GitHub Pages:
```yaml
# .github/workflows/deploy.yml
- run: pip install cacao
- run: cacao build app.py --base-path /${{ github.event.repository.name }}
```
See [cacao-tools](https://github.com/cacao-research/cacao-tools) for a full static site example.
---
## Tech Stack
| Layer | Technology |
|-------|------------|
| Backend | Python 3.10+, Starlette, Uvicorn, WebSocket |
| Frontend | React 18, Chart.js, LESS |
| Build | esbuild, hatchling |
| State | Signal-based reactivity with session scoping |
| Deployment | Static export, GitHub Pages, any ASGI server |
---
## Project Structure
```
cacao/
βββ __init__.py # Package exports
βββ simple.py # Streamlit-like API (import cacao as c)
βββ server/ # Core server
β βββ ui.py # 60+ UI components
β βββ chart.py # Chart components
β βββ signal.py # Signal & Computed reactivity
β βββ session.py # Session management
β βββ events.py # Event handling
β βββ server.py # HTTP + WebSocket server
β βββ data.py # Data utilities
βββ cli/ # CLI (run, build, create)
βββ frontend/ # Frontend source (devs only)
β βββ src/components/ # React components
β βββ src/styles/ # LESS styles
β βββ src/handlers/ # Static build handlers
β βββ dist/ # Build output
βββ examples/ # Example apps
```
---
## Contributing
Contributions are welcome! See the repo issues for ideas.
```
fork β feature branch β commit β push β pull request
```
---
**Cacao** β Reactive Python UIs, made simple.
[Report Bug](https://github.com/cacao-research/Cacao/issues) Β· [Request Feature](https://github.com/cacao-research/Cacao/issues)
Made with care by [Juan Denis](https://juandenis.com)