A tiny bilingual (English / 中文) seedling shop you can host on a Raspberry Pi or any small Linux box. Share the link with friends, let them browse seedlings with photos and descriptions, add to cart, and check out — orders land in your admin console (and your inbox).
Built as a single Node.js + Express + SQLite app, no build step, no framework lock-in.
- 🌐 Bilingual —
/English,/cn中文. Every product field is stored in both languages. - 🛒 Cart + checkout — atomic stock decrement (no overselling), polling-based real-time stock display.
- 🤖 AI-assisted product entry — paste a product URL and Claude scrapes name/description/image and translates everything; or paste a free-form blurb in any language and let Claude fill the form.
- 📧 Email notifications — get an SMTP email the moment a friend checks out, with the full item list.
- 🔗 Customer order lookup — every checkout returns a unique link + 6-digit password the buyer can use to view their order anytime.
- 🔁 Live name updates — rename a seedling in admin and existing orders display the new name automatically (joined live, snapshot kept as fallback if deleted).
- 📱 Mobile-friendly — responsive grid + slide-in cart drawer.
- 💾 Persistent — SQLite file on disk; survives restarts.
- Node.js 20+ / Express
better-sqlite3for storagemulterfor image upload,nodemailerfor SMTP- Vanilla HTML/CSS/JS frontend (no React, no build)
- Anthropic Claude API for the AI helpers
git clone https://github.com/quake0day/seedinlings4All.git
cd seedinlings4All
npm install
ADMIN_PASSWORD=changeme \
ANTHROPIC_API_KEY=sk-ant-... \
npm startThen open:
- Shop (English): http://localhost:3000/
- Shop (中文): http://localhost:3000/cn
- Admin: http://localhost:3000/admin
| Variable | Required | Description |
|---|---|---|
PORT |
no | Default 3000 |
ADMIN_PASSWORD |
yes | Password for the admin console |
ANTHROPIC_API_KEY |
optional | Enables URL scrape + blurb fill (uses Claude) |
SMTP_HOST / SMTP_PORT / SMTP_SECURE |
optional | SMTP server (Gmail: smtp.gmail.com / 465 / true) |
SMTP_USER / SMTP_PASS |
optional | SMTP login (Gmail needs an App Password) |
SMTP_FROM |
optional | From address (defaults to SMTP_USER) |
NOTIFY_EMAIL |
optional | Where to deliver order notifications |
PUBLIC_URL |
optional | Base URL used in admin links inside notification emails |
Email notifications activate only when SMTP_HOST, SMTP_USER, and NOTIFY_EMAIL are all set.
/etc/systemd/system/seedlings.service:
[Unit]
Description=Seedlings4All
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser/seedinlings4All
Environment=PORT=3000
Environment=ADMIN_PASSWORD=changeme
Environment=ANTHROPIC_API_KEY=sk-ant-...
Environment=SMTP_HOST=smtp.gmail.com
Environment=SMTP_PORT=465
Environment=SMTP_SECURE=true
Environment=SMTP_USER=you@gmail.com
Environment=SMTP_PASS=app-password-here
Environment=NOTIFY_EMAIL=you@gmail.com
ExecStart=/usr/bin/node /home/youruser/seedinlings4All/server.js
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now seedlings
sudo journalctl -u seedlings -f- Open
/admin, enter yourADMIN_PASSWORD(cached in browser). - Add seedlings — fill English + Chinese fields by hand, or:
- Paste a product URL into Auto-fill from URL → Claude fetches & translates everything.
- Paste a description blurb into Fill from blurb → Claude analyzes & translates.
- Upload an image, or use the URL Claude found, or skip and a 🌱 placeholder shows.
- Click Add. Click Edit on any row to update later — renames propagate to existing orders automatically.
- Watch new orders appear at the bottom of the page, also delivered to your inbox.
- You share
http://your-host:3000/(or/cn) with friends. - They browse, add to cart, check out with their name + contact + optional note.
- The success modal gives them a personal order link (
/order?t=<token>) and a 6-digit password. They can revisit anytime. - You see the order in
/adminand in your email.
Two folders hold all state:
data/app.db— SQLite database (seedlings + orders + tokens)uploads/— uploaded images
Both are gitignored. Back them up:
scp user@host:~/seedinlings4All/data/app.db ~/seedlings-backup-$(date +%F).dbMIT