{"id":44055227,"url":"https://github.com/cacao-research/cacao","last_synced_at":"2026-03-07T19:03:41.450Z","repository":{"id":285170816,"uuid":"955099807","full_name":"cacao-research/Cacao","owner":"cacao-research","description":"🍫 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 \u0026 desktop). ","archived":false,"fork":false,"pushed_at":"2026-03-05T07:10:30.000Z","size":2626,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-05T09:58:53.764Z","etag":null,"topics":["cacao","framework","interfaces","pwa","python","python-gui","pythonic","toolkit","web-framework","webapp"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/cacao/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cacao-research.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["jhd3197"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"jhd3197","thanks_dev":null,"custom":null}},"created_at":"2025-03-26T05:28:29.000Z","updated_at":"2026-03-05T07:10:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"59ded613-a037-4460-b5d8-6f17554bfc8d","html_url":"https://github.com/cacao-research/Cacao","commit_stats":null,"previous_names":["jhd3197/cacao","cacao-research/cacao"],"tags_count":55,"template":false,"template_full_name":null,"purl":"pkg:github/cacao-research/Cacao","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cacao-research%2FCacao","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cacao-research%2FCacao/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cacao-research%2FCacao/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cacao-research%2FCacao/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cacao-research","download_url":"https://codeload.github.com/cacao-research/Cacao/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cacao-research%2FCacao/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30226785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cacao","framework","interfaces","pwa","python","python-gui","pythonic","toolkit","web-framework","webapp"],"created_at":"2026-02-08T00:09:27.743Z","updated_at":"2026-03-07T19:03:41.443Z","avatar_url":"https://github.com/cacao-research.png","language":"Python","funding_links":["https://github.com/sponsors/jhd3197","https://buymeacoffee.com/jhd3197"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![image](https://github.com/user-attachments/assets/830a00ca-7948-42ff-9196-adb58357c536)\n\n# Cacao\n\n**High-performance reactive web framework for Python.**\n\nBuild dashboards, internal tools, and data apps with a simple API — real WebSocket reactivity, not full-page reruns.\n\n[![PyPI Version](https://img.shields.io/pypi/v/cacao?style=flat-square\u0026color=f5c542)](https://pypi.org/project/cacao/)\n[![Downloads](https://img.shields.io/pypi/dm/cacao?style=flat-square\u0026color=green)](https://pepy.tech/project/cacao)\n[![Python](https://img.shields.io/badge/python-3.10+-3776AB.svg?style=flat-square\u0026logo=python\u0026logoColor=white)](https://pypi.org/project/cacao/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/cacao-research/Cacao/blob/main/LICENSE)\n[![CI](https://img.shields.io/github/actions/workflow/status/cacao-research/Cacao/ci.yml?branch=dev\u0026style=flat-square\u0026label=CI)](https://github.com/cacao-research/Cacao/actions/workflows/ci.yml)\n[![GitHub Pages](https://img.shields.io/github/actions/workflow/status/cacao-research/Cacao/pages.yml?branch=main\u0026style=flat-square\u0026label=showcase)](https://github.com/cacao-research/Cacao/actions/workflows/pages.yml)\n\n![React](https://img.shields.io/badge/React-18-61DAFB.svg?style=flat-square\u0026logo=react\u0026logoColor=black)\n![WebSocket](https://img.shields.io/badge/WebSocket-realtime-8B5CF6.svg?style=flat-square)\n![Starlette](https://img.shields.io/badge/Starlette-ASGI-009688.svg?style=flat-square)\n[![GitHub Stars](https://img.shields.io/github/stars/cacao-research/Cacao?style=flat-square\u0026color=f5c542)](https://github.com/cacao-research/Cacao/stargazers)\n\n\u003cbr\u003e\n\n[Features](#-features) · [Quick Start](#-quick-start) · [Examples](#-examples) · [Components](#-components) · [Architecture](#-architecture) · [Static Builds](#-static-builds) · [Contributing](#-contributing)\n\n\u003c/div\u003e\n\n---\n\n\u003e **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.\n\n## Quick Start\n\n```bash\npip install cacao\n```\n\n```python\nimport cacao as c\n\nc.title(\"Hello, Cacao!\")\nc.text(\"Welcome to the simplest Python web framework\")\n```\n\n```bash\ncacao run app.py\n```\n\nThat's it — 3 lines of Python and you have a live web app with hot reload.\n\n---\n\n## Why Cacao?\n\n| Feature | Cacao | Streamlit |\n|---------|-------|-----------|\n| **Reactivity** | Signal-based (only changed values update) | Full script re-run on every interaction |\n| **State** | Session-scoped by design | `st.session_state` bolt-on |\n| **Updates** | WebSocket streaming (instant) | HTTP polling (laggy) |\n| **Multi-user** | Isolated sessions built-in | Shared state issues |\n| **API** | Context managers + decorators | Magic globals |\n| **Static export** | `cacao build` — no server needed | Not supported |\n\n---\n\n## Features\n\n### Reactive Signals\n\n```python\ncount = c.signal(0, name=\"count\")\n\n@c.on(\"increment\")\nasync def increment(session, event):\n    count.set(session, count.get(session) + 1)\n```\n\nSignals are the core of Cacao. When a value changes, only the affected components update — no full-page reruns, no diffing your entire tree.\n\n### 60+ Built-in Components\n\nLayouts, forms, charts, display elements, navigation — everything you need out of the box.\n\n### Multi-Page Apps\n\n```python\nwith c.page(\"/\"):\n    c.title(\"Home\")\n\nwith c.page(\"/settings\"):\n    c.title(\"Settings\")\n```\n\nHash-based routing works both in server mode and static builds.\n\n### Static Builds\n\n```bash\ncacao build app.py\n```\n\nExport 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.\n\n### Plugin Hooks \u0026 Auth\n\nExtensible architecture with plugin registration, authentication hooks, and notification toasts.\n\n### Dark \u0026 Light Themes\n\n```python\nc.config(theme=\"dark\")  # or \"light\"\n```\n\n---\n\n## Examples\n\n### Interactive Counter\n\n```python\nimport cacao as c\n\nc.config(title=\"Counter\")\ncount = c.signal(0, name=\"count\")\n\n@c.on(\"increment\")\nasync def increment(session, event):\n    count.set(session, count.get(session) + 1)\n\n@c.on(\"decrement\")\nasync def decrement(session, event):\n    count.set(session, count.get(session) - 1)\n\nc.title(\"Counter\")\n\nwith c.card():\n    c.metric(\"Count\", count)\n    with c.row():\n        c.button(\"-\", on_click=\"decrement\", variant=\"secondary\")\n        c.button(\"+\", on_click=\"increment\")\n```\n\n### Dashboard with Charts\n\n```python\nimport cacao as c\n\nc.config(title=\"Sales Dashboard\", theme=\"dark\")\nsales = c.sample_sales_data()\n\nc.title(\"Sales Dashboard\")\n\nwith c.row():\n    c.metric(\"Revenue\", \"$45,231\", trend=\"+20.1%\", trend_direction=\"up\")\n    c.metric(\"Orders\", \"1,247\", trend=\"+12.5%\", trend_direction=\"up\")\n    c.metric(\"Customers\", \"842\", trend=\"+5.3%\", trend_direction=\"up\")\n\nwith c.row():\n    with c.col(span=8):\n        with c.card(\"Revenue Trend\"):\n            c.line(sales, x=\"date\", y=\"revenue\", area=True)\n    with c.col(span=4):\n        with c.card(\"By Category\"):\n            c.pie(sales[:5], values=\"revenue\", names=\"category\", donut=True)\n\nwith c.card(\"Recent Transactions\"):\n    c.table(sales[:10], columns=[\"date\", \"category\", \"revenue\", \"orders\"])\n```\n\nMore examples in the [`examples/`](examples/) directory:\n\n| Example | Description |\n|---------|-------------|\n| [`simple/hello.py`](examples/simple/hello.py) | Minimal hello world |\n| [`simple/counter.py`](examples/simple/counter.py) | Interactive counter with signals |\n| [`simple/metrics.py`](examples/simple/metrics.py) | KPI dashboard |\n| [`simple/dashboard.py`](examples/simple/dashboard.py) | Full dashboard with charts |\n| [`chat/app.py`](examples/chat/app.py) | Chat application |\n| [`todo/server.py`](examples/todo/server.py) | Todo list app |\n| [`analytics_dashboard/`](examples/analytics_dashboard/) | Analytics dashboard |\n\n---\n\n## Components\n\n### Layout\n\n| Component | Description |\n|-----------|-------------|\n| `row()` | Horizontal flex layout |\n| `col(span=N)` | Column with 12-grid span |\n| `grid()` | CSS grid layout |\n| `container()` | Centered container |\n| `stack()` | Vertical stack |\n| `split()` | Side-by-side split |\n| `hero()` | Hero section |\n| `card()` | Card container |\n| `tabs()` / `tab()` | Tabbed content |\n| `accordion()` | Collapsible sections |\n| `modal()` | Modal dialog |\n| `panel()` | Sliding panel |\n| `app_shell()` | Full app layout with sidebar |\n\n### Display\n\n| Component | Description |\n|-----------|-------------|\n| `title()` / `text()` | Typography |\n| `markdown()` | Markdown with optional TOC |\n| `code()` | Syntax-highlighted code |\n| `metric()` | KPI metric with trend |\n| `table()` | Data table |\n| `json_view()` | Interactive JSON viewer |\n| `badge()` / `alert()` | Status indicators |\n| `progress()` | Progress bar |\n| `image()` / `video()` | Media |\n| `timeline()` | Timeline display |\n| `diff()` | Side-by-side diff viewer |\n| `breadcrumb()` | Navigation breadcrumb |\n\n### Form\n\n| Component | Description |\n|-----------|-------------|\n| `button()` | Button with variants |\n| `input_field()` | Text input |\n| `textarea()` | Multi-line input |\n| `select()` | Dropdown select |\n| `checkbox()` / `switch()` | Toggle inputs |\n| `slider()` | Range slider |\n| `date_picker()` | Date picker |\n| `search_input()` | Search with suggestions |\n| `file_upload()` | File upload |\n| `chat()` | Chat input interface |\n\n### Charts\n\n| Component | Description |\n|-----------|-------------|\n| `line()` / `area()` | Line and area charts |\n| `bar()` | Bar chart |\n| `pie()` / `donut()` | Pie and donut charts |\n| `scatter()` | Scatter plot |\n| `gauge()` | Gauge meter |\n| `heatmap()` | Heatmap |\n| `radar()` | Radar chart |\n| `funnel()` | Funnel chart |\n| `treemap()` | Treemap |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                         PYTHON SERVER                           │\n│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────────┐  │\n│  │ Signals  │  │ Sessions │  │  Events  │  │ WebSocket/HTTP│  │\n│  │ (state)  │──│ (per-    │──│ (typed   │──│    Server     │  │\n│  │          │  │  client) │  │  async)  │  │  (Starlette)  │  │\n│  └──────────┘  └──────────┘  └──────────┘  └───────┬───────┘  │\n└────────────────────────────────────────────────────┼───────────┘\n                                                     │ JSON\n                                                     │ WebSocket\n┌────────────────────────────────────────────────────┼───────────┐\n│                      REACT CLIENT                  │           │\n│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────┴──────┐   │\n│  │  Hooks   │  │Components│  │  Event   │  │   State     │   │\n│  │useCacao()│──│ (60+ UI) │──│Dispatcher│──│   Store     │   │\n│  └──────────┘  └──────────┘  └──────────┘  └─────────────┘   │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n**Data flow:**\n```\nPython API → JSON definition → WebSocket → React renders\n     ↑                                         ↓\nSignal.set() ←── Event handler ←── User action\n```\n\n---\n\n## CLI\n\n```bash\ncacao run app.py                     # Run with hot reload\ncacao run app.py --port 3000         # Custom port\ncacao run app.py --no-reload         # Disable hot reload\ncacao create my-dashboard            # Scaffold a new project\ncacao build app.py                   # Build static site\ncacao build app.py --base-path /repo # For GitHub Pages subdirectory\n```\n\n---\n\n## Static Builds\n\nCacao generates static sites that run entirely in the browser — no Python server required.\n\n```bash\ncacao build app.py\n```\n\nOutput:\n```\ndist/\n├── index.html    # Your app\n├── cacao.js      # Runtime + built-in handlers\n└── cacao.css     # Styles\n```\n\n**Built-in client-side handlers** for common operations:\n- **Encoders** — Base64, URL, HTML entities, JWT decode\n- **Generators** — UUID, passwords, Lorem Ipsum\n- **Converters** — JSON/YAML, case conversion, number bases\n- **Text** — Statistics, regex testing\n- **Crypto** — Hash generation, HMAC\n\nDeploy to GitHub Pages:\n```yaml\n# .github/workflows/deploy.yml\n- run: pip install cacao\n- run: cacao build app.py --base-path /${{ github.event.repository.name }}\n```\n\nSee [cacao-tools](https://github.com/cacao-research/cacao-tools) for a full static site example.\n\n---\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|------------|\n| Backend | Python 3.10+, Starlette, Uvicorn, WebSocket |\n| Frontend | React 18, Chart.js, LESS |\n| Build | esbuild, hatchling |\n| State | Signal-based reactivity with session scoping |\n| Deployment | Static export, GitHub Pages, any ASGI server |\n\n---\n\n## Project Structure\n\n```\ncacao/\n├── __init__.py          # Package exports\n├── simple.py            # Streamlit-like API (import cacao as c)\n├── server/              # Core server\n│   ├── ui.py            # 60+ UI components\n│   ├── chart.py         # Chart components\n│   ├── signal.py        # Signal \u0026 Computed reactivity\n│   ├── session.py       # Session management\n│   ├── events.py        # Event handling\n│   ├── server.py        # HTTP + WebSocket server\n│   └── data.py          # Data utilities\n├── cli/                 # CLI (run, build, create)\n├── frontend/            # Frontend source (devs only)\n│   ├── src/components/  # React components\n│   ├── src/styles/      # LESS styles\n│   ├── src/handlers/    # Static build handlers\n│   └── dist/            # Build output\n└── examples/            # Example apps\n```\n\n---\n\n## Contributing\n\nContributions are welcome! See the repo issues for ideas.\n\n```\nfork → feature branch → commit → push → pull request\n```\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Cacao** — Reactive Python UIs, made simple.\n\n[Report Bug](https://github.com/cacao-research/Cacao/issues) · [Request Feature](https://github.com/cacao-research/Cacao/issues)\n\nMade with care by [Juan Denis](https://juandenis.com)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcacao-research%2Fcacao","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcacao-research%2Fcacao","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcacao-research%2Fcacao/lists"}