# zuzu

Build personal apps in Python. Define records, get a full app.

```python
import zuzu

# Define your data
contacts = zuzu.record("Contacts",
    name="",
    email="",
    company="",
    status=zuzu.Choice(["Lead", "Active", "Churned"]),
)

# Build the UI
zuzu.app("My CRM", records=[contacts], accent="purple", theme="dark")
zuzu.page("People", record=contacts, layout="cards")

zuzu.page("Dashboard")
zuzu.metric("Total", contacts.count())
zuzu.metric("Active", contacts.where(status="Active").count())
zuzu.chart(contacts, x="status", y="name", kind="donut", aggregate="count")
```

```bash
pip install zuzu
python my_app.py
# → opens at http://localhost:8899
```

## What you get

- **Records** — Define data models with types, choices, computed fields, and relations
- **Views** — List, cards, kanban, grid, tiles, calendar, checklist layouts
- **Components** — 37+ UI components: metrics, charts, forms, buttons, badges, progress bars, and more
- **Theming** — 9 accent colors, light/dark/auto mode, configurable radius, density, and card style
- **Local-first** — SQLite database, no external dependencies, runs anywhere Python runs

## Install

```bash
pip install zuzu
```

Requires Python 3.10+.

## Documentation

See [zuzu.codes/docs](https://zuzu.codes/docs) for the full SDK reference.

## Examples

Check the `examples/` directory:

- **personal-crm** — Contact manager with status tracking and dashboards

## Development

```bash
git clone https://github.com/zuzucodes/zuzu.git
cd zuzu
pip install -e ".[dev]"
pytest
```

### Frontend development

The renderer is a Preact + Vite app with Storybook:

```bash
cd frontend
npm install
npm run dev          # Dev server (proxies to Python on :8899)
npx storybook dev    # Component docs
npx vite build       # Production build → zuzu/runtime/static/
```

### Schema-driven codegen

Components are defined as JSON schemas in `schemas/` and generated into Python functions + TypeScript types:

```bash
python scripts/codegen.py           # Regenerate all
python scripts/codegen.py --check   # CI: exit 1 if stale
```

## License

MIT
