A full-stack web app for creating and managing personal meal plans, searching recipes via the Spoonacular API, and storing user preferences and meal plans in MongoDB.
This repo contains a Svelte (Vite) frontend and a Node.js/Express backend with JWT-based authentication and a MongoDB Atlas database.
svelte-routing, Axios, Bootstrap (CDN), Font Awesome (CDN)jsonwebtoken), Node crypto (scrypt) for password hashing, Axios, CORS, dotenvrecipes/complexSearchclient/ # Svelte + Vite frontend
src/
pages/
LoginRegister.svelte
Profile.svelte
components/
MealPlan.svelte
styles/
app.css
index.html
package.json
Server/ # Express + Mongoose backend
app.js
.env # Environment variables (do NOT commit secrets)
api/
routes/ # Express routers (users, meals, mealplans)
controllers/ # Route handlers
models/ # Mongoose schemas (User, MealPlan)
middleware/ # JWT auth verification
util/ # Auth helpers (hash/compare/sign/verify)
db/
connection.js # MongoDB connection via Mongoose
package.json
thunder-collection_MealPlannerApp.json # Thunder Client requests
crypto scrypt (salted)Create Server/.env with the following keys. Use your own secrets and do not commit them.
# Spoonacular
SPOONACULAR_API_KEY=your_spoonacular_api_key
SPOONACULAR_API_URL=https://api.spoonacular.com/recipes/complexSearch
# Auth
JWT_SECRET=your_long_random_hex_secret
# MongoDB Atlas
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_ADDRESS=cluster0.xxxxx.mongodb.net
DB_NAME=MealPlannerApp
Tip: Generate a strong JWT secret in PowerShell
powershell -Command "$([BitConverter]::ToString((New-Object byte[] 32 | %{[void](New-Object Random).NextBytes($_);$_} ) ).Replace('-', '')).ToLower()"
Prerequisites
Install and run the backend
# From repo root
cd Server
npm install
npm run dev
http://localhost:8080Server/.envInstall and run the frontend
# From repo root
cd client
npm install
npm run dev
http://localhost:5173)http://localhost:8080JWT_SECRET and 24h expiry.{ _id, header_token } in localStorage under key Users.Authorization: Bearer <token>.verifyUsers validates the token and attaches req.verified = { username, user_id }.User (Server/api/models/user.js)
username: String (unique, lowercase, required)
password: String (hashed with scrypt, required)
preferences: [String] (default: [])
virtual mealplans: refs MealPlan by user_id
MealPlan (Server/api/models/mealplan.js)
user_id: ObjectId -> User (required)
week: Number (required)
meals: [
{
mealId: Number,
name: String,
diets: [String],
image: String
}
]
Base URL: http://localhost:8080
Auth header where noted: Authorization: Bearer <token>
POST /users/register
{ "username": string, "password": string, "preferences": string[] }{ _id, username, preferences }POST /users/login
{ "username": string, "password": string }{ _id, username, preferences, token_type: "Bearer", access_token }GET /users/:id (protected)
mealplans.PUT /users/:id (protected)
{ "preferences": string[] }GET /meals/search (protected)
meal=<query>&diets=comma,separated,dietscomplexSearch with addRecipeInformation=true.results[] from Spoonacular.POST /mealplans (protected)
{ week: number, mealId: number, name: string, diets: string[], image: string }week; max 3 meals.DELETE /mealplans/:id (protected)
:id is the user’s id. Deletes that user’s meal plan document./profile/:id.Note: A navigation link for “Search” exists, but a dedicated search page is not included. Use the API/Thunder Client to search and add meals to plans, or extend the UI as needed.
A ready-to-use collection is included: thunder-collection_MealPlannerApp.json.
Authorization header to the client.8080.5173.Authorization: Bearer <token> and the user id in the URL matches the token’s user_id.DB_USER, DB_PASSWORD, DB_ADDRESS, and DB_NAME in Server/.env.SPOONACULAR_API_KEY, usage limits, and SPOONACULAR_API_URL.crypto scrypt with per-user salt. Do not store plaintext passwords..env with secrets. Keep a local copy per developer/environment.Backend (in Server/)
npm run dev: Start Express with Nodemon.Frontend (in client/)
npm run dev: Start Vite dev server.npm run build: Production build.npm run preview: Preview production build.PORT env var.Made with Svelte, Express, and MongoDB.