Household management web app that updates in real-time
  • Python 43.1%
  • HTML 31.9%
  • CSS 17.1%
  • JavaScript 7.4%
  • Dockerfile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kamil Marut 041aae924b
All checks were successful
Push Docker Image / push (push) Successful in 5m2s
constants: Update autocomplete list
2026-08-17 00:03:40 +02:00
.forgejo/workflows ci: Add "Push Docker Image" workflow 2026-07-22 11:34:48 +02:00
.impeccable Initialize project 2026-07-21 19:04:10 +02:00
core constants: Update autocomplete list 2026-08-17 00:03:40 +02:00
docker docker: Set proper entrypoint path/command 2026-07-22 12:37:00 +02:00
hearth templates: Add favicons, web manifest and logos 2026-07-22 14:39:50 +02:00
locale/pl/LC_MESSAGES constants: Update autocomplete list 2026-08-17 00:03:40 +02:00
static shopping: Allow item editing 2026-07-27 17:44:52 +02:00
templates shopping: Allow item editing 2026-07-27 17:44:52 +02:00
.dockerignore docker: Fix Dockerfile build stage 2026-07-22 11:45:19 +02:00
.env.example i18n: Change autocomplete list and translations 2026-07-22 10:21:32 +02:00
.gitignore recipes: Add links to recipe 2026-07-22 14:19:50 +02:00
.python-version Initialize project 2026-07-21 19:04:10 +02:00
bun.lock i18n: Change autocomplete list and translations 2026-07-22 10:21:32 +02:00
CLAUDE.md Initialize project 2026-07-21 19:04:10 +02:00
DESIGN.md templates: Add favicons, web manifest and logos 2026-07-22 14:39:50 +02:00
docker-compose.yml project: Improve many project areas 2026-07-21 23:14:07 +02:00
Dockerfile docker: Set proper entrypoint path/command 2026-07-22 12:37:00 +02:00
manage.py project: Rename config directory to hearth 2026-07-21 20:34:55 +02:00
package-lock.json Initialize project 2026-07-21 19:04:10 +02:00
package.json i18n: Change autocomplete list and translations 2026-07-22 10:21:32 +02:00
PRODUCT.md Initialize project 2026-07-21 19:04:10 +02:00
pyproject.toml project: Improve many project areas 2026-07-21 23:14:07 +02:00
README.md templates: Add favicons, web manifest and logos 2026-07-22 14:39:50 +02:00
uv.lock project: Improve many project areas 2026-07-21 23:14:07 +02:00

🔥 Hearth

A real-time household management app: a shared shopping list, a weekly meal planner, and a recipe cookbook — with live sync between household members over WebSockets. Built from the Hearth design prototype.

Charcoal · cream · flame-orange, Archivo type, grain-textured surfaces.

Stack

  • Django 6 (full-stack: templates + forms), managed with uv
  • HTMX for reactivity — mutations swap server-rendered fragments
  • Django Channels (channels + channels-redis + daphne) for WebSocket sync
  • Tailwind CSS 4 (CSS-first @theme), built with the Tailwind CLI via Node
  • Postgres + Redis in production; SQLite + in-memory channel layer for dev
  • Docker (multi-stage) for packaging; Daphne (ASGI) + WhiteNoise for static

How real-time sync works

Every mutation is an HTMX POST that (1) returns the affected region as an hx-swap-oob fragment to update the actor instantly, and (2) broadcasts the same update to the household's Channels group so the partner's browser applies it too. HTML (not JSON) travels over the socket, so HTMX's ws extension swaps it directly.

  • Shopping: the whole board is re-rendered and OOB-swapped. Search + category filtering is client-side over the full board, so a partner's in-progress search is never clobbered by an incoming sync.
  • Planner: a tiny "ping" element is OOB-swapped in and self-fires an HTMX GET, so each client reloads its own week — never yanked to the actor's week.

Local development

Requirements: Python 3.13 (via uv), Node 20+.

uv sync                          # Python deps
npm install                      # front-end toolchain
npm run build                    # vendor HTMX/font + build Tailwind CSS

uv run python manage.py migrate
uv run python manage.py seed_hearth
uv run python manage.py runserver

Open http://127.0.0.1:8000 and sign in as you / ada (password hearth123). runserver serves ASGI (WebSockets included) because daphne is first in INSTALLED_APPS. In dev the channel layer is in-memory (single process), so sync works across tabs without Redis.

While iterating on styles, run the CSS watcher in another terminal:

npm run watch:css

To regenerate the placeholder recipe/hero images:

uv run --with pillow python scripts/gen_assets.py

Production (Docker)

cp .env.example .env             # set SECRET_KEY, ALLOWED_HOSTS, domain…
docker compose up --build

Compose runs three services — web (Daphne on :8000), db (Postgres), redis (channel layer) — and the entrypoint migrates, seeds, and collects static on start. App at http://localhost:8000.

Project layout

hearth/            Django project (settings, asgi with Channels routing, urls)
core/
  models.py        Household, Membership, ShoppingItem, Recipe*, MealEntry
  views.py         HTMX views: mutations return OOB fragments + broadcast
  services.py      household resolution, week math, board/planner view-models
  consumers.py     HouseholdConsumer (AsyncWebsocketConsumer, HTML over ws)
  realtime.py      broadcast() → channel layer group_send
  constants.py     12 categories + 4 meal rows
  seed_data.py     recipes + demo data (from the prototype)
templates/         base shell, per-view pages, partials/ (fragments + modals)
assets/css/        Tailwind input (@theme tokens, keyframes, components)
static/            build output + committed images (served by WhiteNoise)
scripts/           vendor.mjs (HTMX/font), gen_assets.py (images)