Household management web app that updates in real-time
  • Python 53.4%
  • HTML 38.8%
  • JavaScript 7.4%
  • Dockerfile 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Camila 944179e5bd
All checks were successful
Push Docker Image / push (push) Successful in -40s
settings: Refresh the session cookie on every request
SESSION_COOKIE_AGE is applied at login time and only re-applied when the
session is saved, so an active user was still logged out 14 days after
logging in. Saving the session on every request makes the cookie age a
sliding window that refreshes on use.
2026-10-10 16:06:09 +02:00
.forgejo/workflows ci: Build only AMD64 image 2026-10-03 12:32:12 +02:00
.impeccable Initialize project 2026-07-21 19:04:10 +02:00
core views: Refactor templates/views for less code duplication 2026-10-03 13:00:57 +02:00
docker docker: Set proper entrypoint path/command 2026-07-22 12:37:00 +02:00
hearth settings: Refresh the session cookie on every request 2026-10-10 16:06:09 +02:00
locale/pl/LC_MESSAGES fix: limit recipe planning to today and future dates 2026-09-11 22:56:20 +02:00
static views: Refactor templates/views for less code duplication 2026-10-03 13:00:57 +02:00
templates views: Refactor templates/views for less code duplication 2026-10-03 13:00:57 +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 build(docker): Simplify the Dockerfile to a single stage 2026-10-03 12:55:00 +02:00
manage.py project: Rename config directory to hearth 2026-07-21 20:34:55 +02:00
package.json docs: Update README.md with up-to-date information 2026-10-03 12:58:13 +02:00
PRODUCT.md Initialize project 2026-07-21 19:04:10 +02:00
pyproject.toml settings: Clean up settings 2026-10-03 13:00:11 +02:00
README.md docs: Update README.md with up-to-date information 2026-10-03 12:58:13 +02:00
uv.lock settings: Clean up settings 2026-10-03 13:00:11 +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 Bun
  • SQLite database, Redis/Valkey channel layer, S3-compatible (RustFS) media storage
  • Docker 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), Bun, a Redis/Valkey and an S3-compatible store (docker compose up valkey rustfs), configured via .env (see .env.example).

uv sync                          # Python deps
bun install                      # front-end toolchain
bun run build                    # 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.

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

bun run watch

Production (Docker)

cp .env.example .env             # set DJANGO_SECRET_KEY, DJANGO_ALLOWED_HOSTS, AWS_*…
docker compose up --build

Compose runs three services — web (Daphne on :8000), valkey (channel layer), rustfs (S3-compatible media) — and the entrypoint migrates on start. Static files are collected at image build time; seed with manage.py seed_hearth if needed. 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
  websockets/      HouseholdConsumer (HTML over ws), broadcast() → group_send, routing
  constants.py     12 categories, 4 meal rows, item catalog
  management/      seed_hearth command (recipes + demo data)
templates/         base shell, per-view pages, partials/ (fragments + modals)
static/css/        app.tailwind (Tailwind input) → app.css (build output)
static/            vendored HTMX, fonts, images (served by WhiteNoise)