[App Name] · Phoenix LiveView
A LiveView app. Server-rendered HTML over WebSocket. Realtime updates without a JS framework.
Source of truth
Production runs as a Phoenix release on Fly.io (BEAM clusters across Fly regions). Postgres in the same primary region with read replicas elsewhere. The Phoenix release tarball is canonical.
Tech stack
Elixir 1.18 + Phoenix 1.8 + LiveView 1.0 + Phoenix.PubSub for cross-process messaging. Ecto + Postgres. Tailwind v4 (built via esbuild + tailwind ports). Oban for background jobs. ExUnit for tests. Deployed via Fly's Elixir launcher.
Deploy
fly deploy from local. Releases are built via mix release inside the Fly builder. Postgres on Fly.
File map
lib/myapp/business domain (Ecto schemas, contexts)lib/myapp_web/web layer (LiveView modules, controllers, components)lib/myapp_web/live/LiveView modules, one per major surfacelib/myapp_web/components/reusable function componentslib/myapp/repo.exEcto repolib/myapp/application.exsupervision tree (PubSub, Repo, Endpoint, Oban)priv/repo/migrations/Ecto migrationsassets/Tailwind + esbuild entrypointsmix.exsdeps + release configfly.toml
.env keys
DATABASE_URLSECRET_KEY_BASE(generate withmix phx.gen.secret)PHX_HOSTyour prod hostnamePOOL_SIZEEcto pool, default 10
Hard rules
- Business logic in contexts, NOT in LiveView modules. LiveView is the UI layer.
assigneverything you read in the template intosocket.assigns. NEVER read from sockets implicitly.- For lists with thousands of items, use streams (
stream/4). Don't put 10k items into assigns. - Phoenix.PubSub for any cross-LiveView communication. Don't hand-roll Channels.
- Migrations are reversible (
upANDdown). Tested withmix ecto.rollback. - Use Oban for anything async. Don't
Task.startin handlers; restarts will leak.
Recent significant changes
- 2026-05-13: Scaffolded. Locked: LiveView 1.0 (stable now), Oban over Quantum (better persistence), Fly over Render (BEAM clustering across regions matters).
Next session: start here
mix phx.new myapp --liveto scaffold (or apply this CLAUDE.md over an existing scaffold).- Create the first context with
mix phx.gen.live. Run it, click around. - Set up Tailwind v4 via the
tailwindmix task. - Add Oban. Define one worker. Confirm it processes.
fly launch+fly deploy. Confirm/liveheartbeat survives a deploy.