Skip to content
brianramseyauPublic

About

Every list you'll ever need

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

345 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Important

📱 The Android app is in closed beta — email beta@everylist.dev with the Google account email you want added as a Play tester.

EveryList icon

EveryList

AnyList meets Google Tasks — one list app for shopping, to-dos, chores, packing, and planning, free and self-hosted with no premium tier.

GHCR License: MIT Node


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.

Screenshots

Lists screen List detail screen, grouped by category List sharing / members screen Settings screen

Lists screen, dark mode List detail screen, dark mode List sharing / members screen, dark mode Settings screen, dark mode

Features

Lists & items

  • 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.

Sync & collaboration

  • Real-time sharing — SSE-based live updates across everyone on a shared list, with granular owner/editor/viewer roles 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.

Everywhere you are

  • 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-setup screen, 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 from Settings → 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 & automation

  • 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 everylist CLI 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.

Self-hosted

  • 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.

Tech stack

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.

Monorepo layout

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.

Getting started

Running the production image

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/everylist

No 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.

Home Assistant

Add repository to my Home Assistant

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.

Native apps (iOS/Android)

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.

Desktop app (Electron)

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.

Voice control & integrations

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.md for 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 native todo.* 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 everylist CLI that talks to your server over the REST API, for terminals and scripts. See Command-line client below.

AI assistants (MCP)

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.

Command-line client

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.

Personal Access Tokens

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.

Development

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.

API docs

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.

Known issues

  • 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 from localStorage, 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.

Contributing

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.

License

MIT © Brian Ramsey

About

Every list you'll ever need

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages