Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Plan meals, track groceries, and manage your budget with ease
LifestyleTypeScript · ShellGitHub @ervenderrOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A mobile-first PWA that helps you see what is in your kitchen, decide what to cook, and shop without overspending.
Screenshots are 390x844 phone captures of the real app running against a local demo database with sample data. AI suggestions are disabled in the captures (no provider key configured).
meal_plan_created, item_expiring, budget_exceeded, shopping_list_created and weekly_summary. Configure with ZAPIER_WEBHOOK_URL or the /zapier API.The UI is designed for phones first and scales up to a desktop sidebar layout.
app/manifest.ts.Recipe suggestions, ingredient substitutions and AI meal plans use one OpenAI-compatible chat endpoint chosen entirely by environment variables.
https://inference.dahl.global/v1), model MiniMaxAI/MiniMax-M2.7. Point AI_BASE_URL and AI_MODEL at any compatible provider to switch. There is no Gemini dependency.AI_API_KEY). With no key the API still starts, /health stays green, and the AI screens show that suggestions are unavailable.AI_USER_DAILY_LIMIT, AI_GLOBAL_DAILY_LIMIT), plus a short burst limiter.OFF_CONTACT so requests carry a proper User-Agent.USDA_API_KEY; without it, nutrition lookups are unavailable.| Layer | Technology |
|---|---|
| Frontend | Next.js 16.4 (App Router), React 19.3, TypeScript, Tailwind CSS 4, TanStack Query 5, React Hook Form + Zod, Radix UI, Framer Motion, Recharts, Zustand, Axios |
| Backend | Node.js 22, Express 4, TypeScript, Prisma 5.22, PostgreSQL, JWT, bcryptjs, express-validator, Zod (env), Winston |
| AI | OpenAI-compatible provider via env (default Dahl Inference, MiniMaxAI/MiniMax-M2.7) |
| Tests | Jest + Supertest (backend), Vitest (frontend) |
| Hosting | Railway (API + Postgres), Vercel (frontend) |
.
├── backend/ Express API, Prisma schema and migrations, Dockerfile (see backend/README.md)
├── frontend/ Next.js app (see frontend/README.md)
├── scripts/ smoke-prod.sh, a curl-based production smoke test
├── docs/ README screenshots
└── .github/ CI workflow
Requirements: Node.js 22, npm, and PostgreSQL 15+ (Docker or a local install).
1. Database. Either start the Postgres service from the backend compose file:
cd backend
docker compose up -d postgres
# DATABASE_URL=postgresql://smart_user:smart_password@localhost:5432/smart_grocery_db?schema=public
or create an empty database in your own Postgres and use its URL.
2. Backend (http://localhost:3001):
cd backend
npm install
cp .env.example .env
# edit .env: set DATABASE_URL and a JWT_SECRET (openssl rand -hex 32)
npx prisma migrate deploy # apply migrations (use `npm run prisma:migrate` while changing the schema)
npm run prisma:seed # optional: [email protected] / Demo1234! plus sample recipes
npm run dev
The seed refuses to run when NODE_ENV=production or when DATABASE_URL does not look local. JWT_SECRET must be at least 32 characters and must not contain words like secret or default. Leave AI_API_KEY empty to run without AI.
3. Frontend (http://localhost:3000):
cd frontend
npm install
cp .env.example .env.local # NEXT_PUBLIC_API_URL=http://localhost:3001
npm run dev
Open http://localhost:3000 and sign in with the demo user, or sign up. To preview the mobile layout, use your browser's device toolbar at 390x844 or open the dev server from a phone on the same network (add that origin to CORS_ORIGIN).
cd backend && npm test # Jest with coverage
cd backend && npm run type-check && npm run lint
cd frontend && npm test # Vitest
cd frontend && npm run type-check && npm run lint
CI (.github/workflows/ci.yml) runs lint, type-check, tests and a build for both packages, plus a Docker build of the API, against a Postgres 16 service. After a deploy, API=https://<your-api-host> scripts/smoke-prod.sh runs a curl-based smoke test against the live API (needs curl and jq; it creates a throwaway smoke+<epoch>@example.com user).
backend/Dockerfile) and Postgres.backend/: railway up --service kitcha-api --detach.prisma migrate deploy (retrying while the database comes up) and then starts node dist/index.js as PID 1, so migrations run on every deploy./health (does not touch the database).PORT is injected by Railway, never set it. DATABASE_URL is the reference variable ${{Postgres.DATABASE_URL}}.openssl rand -hex 32 | railway variable set JWT_SECRET --stdin.frontend.NEXT_PUBLIC_API_URL to the Railway API origin (no trailing slash) for both Production and Preview. It is inlined at build time, so redeploy after changing it.CORS_ORIGIN (and optionally FRONTEND_URL). Preview URLs of your project are allowed through VERCEL_PREVIEW_SCOPE and VERCEL_PREVIEW_PROJECT.Validated at startup by backend/src/config/env.schema.ts; the process exits with a clear message if a required value is missing or weak. Template: backend/.env.example.
| Variable | Required | Default | Notes |
|---|---|---|---|
DATABASE_URL | yes | postgres:// or postgresql:// URL. On Railway: ${{Postgres.DATABASE_URL}} | |
JWT_SECRET | yes | 32+ characters, must not look like a default value | |
CORS_ORIGIN | set in production | http://localhost:3000 | Comma-separated bare origins, no trailing slash. In production they must be https and not localhost |
NODE_ENV | no | development | development, test or production |
PORT | required in production | 3001 in .env.example | Provided by the platform (Railway injects it), only set it yourself locally |
FRONTEND_URL | no | Extra frontend origin merged into the CORS allowlist | |
VERCEL_PREVIEW_SCOPE, VERCEL_PREVIEW_PROJECT | no | project kitcha | Allow this project's Vercel preview URLs |
JWT_EXPIRES_IN, API_VERSION, LOG_LEVEL | no | 7d, v1, info | |
AI_API_KEY | no | Server-side secret. Empty disables AI without breaking the API | |
AI_PROVIDER | no | dahl | Label for the provider |
AI_BASE_URL | no | https://inference.dahl.global/v1 | Any OpenAI-compatible base URL |
AI_MODEL | no | MiniMaxAI/MiniMax-M2.7 | |
AI_TIMEOUT_MS | no | 40000 | Per-call timeout (1000 to 110000) |
AI_MAX_TOKENS |
| Variable | Required | Notes |
|---|---|---|
NEXT_PUBLIC_API_URL | yes for production builds | Backend origin, inlined at build time. Public, never put secrets here |
Base URL /api/v1. All routes except auth/* and /health need Authorization: Bearer <jwt>.
| Area | Prefix |
|---|---|
| Auth | /auth (/signup, /login, /logout, /me) |
| Users and preferences | /users (profile, preferences incl. currency, onboarding/complete, password) |
| Pantry | /pantry (CRUD, /stats, /expiring-soon) |
| Recipes | /recipes |
| Meal plans | /mealplans |
| Shopping list | /shopping (/list, /items, /generate, /finish, /history) |
| Analytics, alerts, notifications | /analytics, /alerts, /notifications |
| AI | /ai (/status, /suggest-recipes, /suggest-substitutions, /generate-meal-plan) |
| Food data | /food (/barcode/:code, /nutrition) |
| Zapier | /zapier |
Routes, validators and controllers live under backend/src/modules/. See backend/README.md for details.
git checkout -b feat/my-change).feat:, fix:, docs:, refactor:, test:, chore:).| no |
8000 |
| Reasoning models emit a think block first |
AI_JSON_MODE | no | off | off or json_object |
AI_USER_DAILY_LIMIT, AI_GLOBAL_DAILY_LIMIT | no | 20, 100 | Requests per UTC day |
USDA_API_KEY | no | Enables USDA nutrition lookups |
OFF_CONTACT | no | this repository URL | URL or email in the Open Food Facts User-Agent |
ZAPIER_WEBHOOK_URL | no | Default Zapier catch-hook URL |
SPOONACULAR_API_KEY | no | Optional, legacy |
PUBLIC_HOST | no | RAILWAY_PUBLIC_DOMAIN | Canonical host for the production HTTP to HTTPS redirect |