Important
📱 The Android app is in closed beta — email beta@everylist.dev with the Google account email you want added as a Play tester.
AnyList meets Google Tasks — one list app for shopping, to-dos, chores, packing, and planning, free and self-hosted with no premium tier.
EveryList is a general-purpose list app: real-time shared shopping lists with aisle-style auto-categorization, plus due dates, recurring items, sub-items, and notes for Google Tasks-style task management — all in the same lists, so one app covers shopping, to-dos, chores, packing lists, and anything else worth tracking and checking off (the EveryList team dogfoods it for its own feature ideas). It's mobile-first, offline-first, one-tier — no premium tier, ever — and ships as an installable PWA, native iOS/Android apps, and a desktop app (macOS/Windows/Linux), with voice control through Alexa or Home Assistant. EveryList is feature-complete and self-hostable today; see foundational/PLAN_00_FOUNDATIONAL_PLAN.md for the full product plan, architecture, and decision rationale behind everything below.
- Any kind of list — unlimited lists for shopping, to-dos, chores, packing, planning, or anything else; quantities, notes, prices with a running budget total, soft-delete with recent-items recovery.
- Task management — due dates/times, recurring items (daily/weekly/monthly, specific weekdays, "nth weekday of the month," with an end date/count), and checkable sub-items, so a list can be a Google Tasks-style to-do list as easily as a grocery list.
- Auto-categorization — items sort into aisle-style categories (Produce, Dairy, Meat, ...) via keyword matching plus a learned model that remembers each list's explicit category choices (with decay, so stale guesses age out), synced to the device so it keeps working offline, fully customizable per list.
- Store-aware aisle order — pick the store you're shopping at and categories reorder to match its real layout; tag items to a store and filter the list down to just that store's items. Store data and aisle order are shared with everyone the list is shared with.
- Favorites — go-to items for one-tap re-adding to the list they belong to; scoped per list, since a grocery list and a packing list don't share go-to items.
- Paste import — paste a block of text and each line gets parsed and auto-categorized.
- Folders & badges — group lists into folders; an uncompleted-item count badges the installed PWA icon (Web Badging API), with per-list exclusion.
- Real-time sharing — SSE-based live updates across everyone on a shared list, with granular
owner/editor/viewerroles and join-link invites. - Offline-first — every core interaction works with zero network via a local IndexedDB store and syncs when back online, with last-write-wins conflict resolution.
- Passcode lock — a client-side PIN gate on sensitive lists; the server never sees the raw PIN.
- Print & email export — a print-friendly stylesheet plus one-click email export of any list.
- Light/dark/automatic theme + accent palettes — four accent themes on top of a real, flash-free light/dark/automatic mode.
- Installable PWA — add to your home screen on any device, no app store required.
- Native iOS & Android apps — the same app wrapped via Capacitor, with a runtime-configurable server URL (point it at your own instance from a
/server-setupscreen, no rebuild needed), pull-to-refresh, and the same offline-first sync as the PWA. Debug-signed/simulator builds are attached to every GitHub Release — see Native apps below. - Android home-screen widget — a Google-Tasks-style widget (list selector, quick-add
+, tap-a-row to open, tap-a-checkbox to complete, due date/time display, show/hide-completed) backed by a scoped PAT minted fromSettings → Home-screen widget. - Desktop app (macOS/Windows/Linux) — an Electron shell wrapping the same web build, with the same runtime-configurable server URL and offline-first sync as the native apps. Unsigned, "check and link" updates instead of auto-update. See Desktop app below.
- Voice control — a private Alexa custom skill (add/remove/complete items, read a list back, plus an on-screen APL visual list on an Echo Show/Hub) and a Home Assistant HACS integration exposing each list as a native
todo.*entity for Voice Assist — both authenticate via scoped Personal Access Tokens, not your login. - AI assistants (MCP) — a built-in Model Context Protocol server, so Claude, Claude Code, Cursor and other MCP clients can read and edit your lists — discover lists, add/complete/remove items, search, and manage sub-tasks. Runs inside the same container on
/mcp, authenticated by a scoped Personal Access Token. See AI assistants (MCP) below. - Command-line client — a small
everylistCLI for humans and scripts (everylist add Groceries "milk",everylist items Groceries), talking to your server over the REST API with a scoped Personal Access Token. See Command-line client below. - Personal Access Tokens — scoped, per-list, editor/viewer-capped API tokens (
Settings → Access Tokens) for third-party integrations like the four above, independent of your login session.
- Single container — one Docker image, one process, one SQLite file under
/config; trivial to back up. - Automated backups — configurable daily/weekly/monthly schedule with a chosen time of day and retention window, taken via SQLite's native online backup API so it's safe to run while the app is live; also triggerable on demand from
Settings → Backups.
Deliberately out of scope: native Watch apps, Siri voice control, and third-party fulfillment integrations (Instacart, etc.) — see the feature decision matrix in the plan for the full reasoning.
SvelteKit + Flowbite/Tailwind on the frontend, AdonisJS 6 on the backend, SQLite (single file, no external DB service), Capacitor for the native iOS/Android shells, Electron for desktop. Full breakdown and rationale in docs/tech-stack.md.
EveryList/
├── apps/
│ ├── android/ # Capacitor native shell
│ ├── api/ # AdonisJS backend
│ ├── cli/ # command-line client (PAT-authenticated REST)
│ ├── desktop/ # Electron desktop shell
│ ├── ios/ # Capacitor native shell
│ └── web/ # SvelteKit PWA
├── packages/
│ └── shared/ # shared TS types, DTOs, validation contracts
├── docker/ # production + dev Dockerfiles, Unraid template
├── docs/ # detailed reference docs (tech stack, deployment methods, MCP setup, CLI, development/)
├── branding/ # app icon source + generated exports, screenshots
├── alexa/ # Alexa custom skill deployment assets (interaction model, account linking)
└── foundational/
└── PLAN_00_FOUNDATIONAL_PLAN.md # single source of truth for scope & architecture
The Home Assistant app (Supervisor's term for what it used to call an "add-on") lives in its own repo, everylist-ha-app — separate from this monorepo for the same reason as below, plus it lets a release here trigger an automated version bump there instead of a manual PR against this repo's own protected main; see Home Assistant below.
The Home Assistant HACS integration (a separate thing — a todo.* entity client against an existing EveryList server, not a way to run the server itself) lives in its own repo, everylist-hass — separate from this monorepo because HACS requires custom_components/<domain>/ at the repo root and versions the integration via that repo's own GitHub releases.
EveryList ships as a single self-contained container — one process serves both the API and the built static frontend on one port:
docker run -d \
--name everylist \
-p 3000:3000 \
-v /path/to/appdata:/config \
ghcr.io/brianramseyau/everylistNo configuration is required to boot it — an APP_KEY is generated on first run and migrations run automatically against the volume. See docs/docker.md for runtime server settings, image tags, and Unraid details.
EveryList is also available as a Home Assistant app, for anyone already running Home Assistant OS/Supervised — same single-container image as the Docker/Unraid path above, no separate docker run needed. Click the badge, or follow Home Assistant's instructions for installing a third-party app repository (Settings → Apps → Install app → ⋮ → Repositories) with https://github.com/brianramseyau/everylist-ha-app, then install "EveryList" from there. See everylist-ha-app's DOCS.md for the app's options.
The native apps release on their own tags, separate from the server: android-vX.Y.Z builds a debug-signed Android APK (-rc.N pre-release) or publishes the AAB to Play closed testing (stable), and ios-vX.Y.Z builds an unsigned iOS Simulator app — each attached to its own GitHub Release and pointed at your own server via a /server-setup screen with no rebuild needed. See docs/android-ios.md for signing status and the Android home-screen widget.
Every server release (vX.Y.Z) also attaches unsigned macOS, Windows, and Linux desktop builds to the GitHub Release — a client only, pointed at whatever EveryList server you configure on first launch. Unlike the mobile apps it has no native surface of its own, so it rides the server release train rather than having a separate version stream. See docs/desktop.md for unsigned-build workarounds, update behavior, and the fixed loopback port.
EveryList lists can be read and edited by external clients through four paths, all authenticated by a scoped Personal Access Token rather than your login — mint one from Settings → Access Tokens, capped at editor role and scoped to only the list(s) you want an integration to reach.
- Alexa — a private custom skill for your own household (see
alexa/README.mdfor the full setup, including the Authentik account-linking requirement). "Alexa, ask every list to add milk", "tell every list I got eggs", "what's on my list" — plus an interactive, category-grouped APL visual list on screen devices like an Echo Show or Echo Hub, with tap-to-complete. - Home Assistant — a HACS custom integration (
everylist-hass) exposing each list as a nativetodo.*entity, so Voice Assist's built-in add/complete intents work with no custom NLU. Reads, writes, and reorders round-trip live via realtime subscription, with a polling fallback. - AI assistants (MCP) — a built-in Model Context Protocol server at
/mcp, so MCP-capable AI clients can read and edit your lists directly. See AI assistants (MCP) below. - Command-line client — a small
everylistCLI that talks to your server over the REST API, for terminals and scripts. See Command-line client below.
EveryList runs an MCP server inside the same container — no separate service to deploy — so AI clients like Claude, Claude Code or Cursor can work with your lists: discover which lists a token can reach, read them, add/update/complete/remove items, search, and manage sub-tasks. It's authenticated by a scoped Personal Access Token (mint one from Settings → Access Tokens), so an AI client only ever sees the list(s) you grant it, at editor or viewer role, never full access. Point a remote-capable client at https://your-instance/mcp with the token as a bearer header, or bridge a stdio-only desktop client through mcp-remote. Full setup, the tool list, and security notes: docs/mcp.md.
apps/cli is a small everylist command-line client — everylist add Groceries "milk", everylist items Groceries, everylist search coffee, everylist complete Groceries milk. It's a plain REST client (it never opens the database file, and isn't part of the Docker image), authenticated by the same scoped Personal Access Token, so it only ever sees the list(s) you grant it. It resolves list/item names against just those grants, shows a masked token, and writes its config with owner-only permissions. Full command reference and setup: docs/cli.md.
Settings → Access Tokens mints tokens like the ones above by hand, for any other script or integration you want to write against the API — see the self-hosted API docs for the full surface. A token can cover multiple lists, is capped below owner (never full access), and is revocable at any time with immediate effect — no redeploy needed.
No external services are required — SQLite runs off a local file, and pnpm install && pnpm dev gets both the API and web app running with hot reload. See docs/development/environment.md for setup, seed data, useful scripts, and the Docker Compose alternative.
Tests run via pnpm test (Japa for the API, Vitest + Playwright for the web app, Electron/Vitest for the desktop app), gated at 100% coverage in CI; the Android app's Robolectric suite is gated by a line-coverage ratchet, and the iOS app's XCTest target runs on a macOS runner. See docs/development/testing.md for the full breakdown and CI pipeline.
Every instance — including your own self-hosted one — serves its full API reference at /docs (a Scalar UI, vendored so it works offline with no CDN calls), backed by the raw OpenAPI 3.1 document at /openapi. Both are unauthenticated. Generated from the Tuyau route registry, so it's always in sync with the actual API.
- Auth token rehydration race: deep-linking straight to a route that needs auth (e.g.
/lists/[id]/recently-deleted) can fire a couple of API calls (/api/v1/lists,/api/v1/folders) before the bearer token has rehydrated fromlocalStorage, causing brief 401s in the console. Not user-visible (the calls that matter retry/succeed once the token is ready), but worth fixing at the root — likely by gating those early fetches on token rehydration completing.
This is a personal project built against foundational/PLAN_00_FOUNDATIONAL_PLAN.md as the single source of truth — any deviation during implementation should be reflected back into that document first. Issues and PRs are welcome.
MIT © Brian Ramsey







