A simple self-hosted shopping list.
  • Python 41.3%
  • HTML 28.5%
  • JavaScript 16.4%
  • CSS 13.1%
  • Shell 0.4%
  • Other 0.3%
Find a file
2026-03-23 18:36:38 +00:00
.gitea/workflows fix: match expression 2026-03-23 19:35:29 +01:00
data Initial commit 2026-02-14 22:24:09 +01:00
routes feat: drag and drop items to other lists 2026-03-23 12:26:08 +01:00
static chore: bump SW cache version [skip ci] 2026-03-23 18:36:38 +00:00
templates fix: security and GDPR issues 2026-02-22 22:20:58 +01:00
translations fix: security and GDPR issues 2026-02-22 22:20:58 +01:00
.env.example Initial commit 2026-02-14 22:24:09 +01:00
.gitignore Initial commit 2026-02-14 22:24:09 +01:00
__init__.py fix: merge issues 2026-02-15 11:38:43 +01:00
auth.py fix: Fixed #27 2026-02-17 20:38:55 +01:00
config.py fix: security and GDPR issues 2026-02-22 22:20:58 +01:00
config.yaml fix: Fixed #26 2026-02-17 20:56:14 +01:00
database.py fix: Fixed #37 and flickering issues 2026-02-21 14:38:41 +01:00
docker-compose.yml fix: interface 2026-02-15 21:45:55 +01:00
Dockerfile fix: ratelimit 2026-03-21 06:39:05 +01:00
LICENSE Initial commit 2026-02-14 16:23:37 +01:00
main.py feat: rate limiting 2026-03-21 06:33:53 +01:00
pyproject.toml chore: version number 2026-02-21 14:39:30 +01:00
ratelimit.py feat: rate limiting 2026-03-21 06:33:53 +01:00
README.md fix: readme 2026-02-22 22:22:21 +01:00
requirements.txt feat: rate limiting 2026-03-21 06:33:53 +01:00
start.sh fix: port 2026-02-15 13:54:55 +01:00
websocket.py refactored responsibilities 2026-02-15 08:03:33 +01:00

🛒 Einkaufsliste

A self-hosted, very simple shopping list app.

No "schnickschnack".

Features

  • Multiple Lists: For different shopping locaionts, there are different lists.
  • Multiple Users: Several users share lists when they belong to a household.
  • Sync: Sync in real-time with serverx
  • Proposal List: Fill the shopping list from a proposal list what is availble in the store
  • Shopping Mode: A simple list where it is possible to cross off items

What it is not

  • If you are looking for managing your groceries at home, have a look at Grocy
  • If you want to copy items from recipes to a shopping list, visit Tandoor or Mealie.
  • If you are looking for managing lists in General, have a look at Jotty.

Note

I am a software engineer (currently in the role as a Software Architect) with more than 25 years of experience in software development. Still, with this project I wanted to experience how I can utilize an AI agent. I am learning with this project about the usage of automated coding and also on web development with Python (which I have not yet done in my career). Therefore, if you like the approach and want to contribute to make things better, you are very welcome. Otherwise you may have a look at other projects on Codeberg.

Have fun!

Docker

git clone https://codeberg.org/deinname/einkaufsliste.git
cd einkaufsliste

# create .env and generate secret key
cp .env.example .env
echo "SECRET_KEY=$(openssl rand -hex 32)" >> .env

# start
docker compose up -d

Check the terminal or log for the admin link:

docker compose logs app

→ Open the link in browser, set a password. Done.
Add additional users via the admin page.

Reverse Proxy (nginx)

The app is running under 127.0.0.1:7953 und using a reverse proxy is recommended. WebSocket support is mandatory (Upgrade-Header).

Example configuration for nginx:

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data:;" always;


# Never cache the service worker
location = /sw.js {
    proxy_pass http://<host>:7953;
    add_header Cache-Control "no-cache, no-store, must-revalidate";
}

limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location /login {
    limit_req zone=login burst=3 nodelay;
    proxy_pass http://<host>:7953;
}


Without Docker

Run directly on the host.

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

export SECRET_KEY=$(openssl rand -hex 32)
uvicorn main:app --host 127.0.0.1 --port 7953

or with the start script:

chmod +x start.sh && ./start.sh

Configuration

config.yaml contains households, market types and proposal lists.

Backup

The database can be found under data/shopping.db (SQLite).

To perform a simple backup:

cp data/shopping.db data/shopping.db.bak

Tech Stack

  • Backend: Python, FastAPI, uvicorn
  • Datenbank: SQLite via aiosqlite
  • Echtzeit: WebSockets
  • Auth: JWT-Cookies, bcrypt, Einladungstoken
  • Frontend: Vanilla JS, kein Framework