Skip to content

keanucz/cook-dis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cook-Dis 🍳

Transform any recipe into a guided, step-by-step cooking experience with AI-generated images and voice narration.

✨ Features

  • Recipe Import: Paste any recipe URL with multi-fallback scraping (direct fetch β†’ Firecrawl β†’ Perplexity)
  • Recipe Search: Search recipes from TheMealDB (free) or Spoonacular (API key required)
  • AI Step Images: Beautiful AI-generated images for each cooking step using Runware's official SDK (FLUX.2 models)
  • Voice Narration: On-demand text-to-speech using ElevenLabs with audio preloading
  • Cooking Mode: Immersive full-screen experience with full-bleed images and overlaid instruction cards
  • Progress Tracking: Pick up where you left off, track completed recipes
  • Recipe Library: Save, organize, and manage your recipe collection
  • Celebration: Confetti party when you complete a dish! πŸŽ‰

πŸ›  Tech Stack

  • Frontend: Next.js 16+ (App Router), React 19, TypeScript, TailwindCSS 4
  • Auth & Database: Supabase (Auth + Postgres with Row Level Security)
  • Image Generation: Runware SDK (@runware/sdk-js) with FLUX.2 models
  • Text-to-Speech: ElevenLabs API
  • LLM: OpenAI GPT-4o (for recipe normalization and parsing)
  • Recipe Scraping: Firecrawl + Perplexity AI as fallbacks for protected sites
  • Storage: Pluggable backend (Local filesystem / Supabase Storage / S3-compatible)

πŸ“ Project Structure

cook-dis/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/                    # Next.js App Router pages
β”‚   β”‚   β”œβ”€β”€ api/               # API routes
β”‚   β”‚   β”‚   β”œβ”€β”€ jobs/          # Background job worker + trigger
β”‚   β”‚   β”‚   β”œβ”€β”€ media/         # Local file serving
β”‚   β”‚   β”‚   β”œβ”€β”€ recipes/       # Recipe CRUD + import
β”‚   β”‚   β”‚   β”œβ”€β”€ steps/         # Step media retry
β”‚   β”‚   β”‚   β”œβ”€β”€ tts/           # On-demand text-to-speech
β”‚   β”‚   β”‚   └── search/        # Recipe search API
β”‚   β”‚   β”œβ”€β”€ auth/              # Auth callback
β”‚   β”‚   β”œβ”€β”€ cook/[id]/         # Cooking mode (full-screen guided experience)
β”‚   β”‚   β”œβ”€β”€ import/            # Recipe import page
β”‚   β”‚   β”œβ”€β”€ library/           # Recipe library
β”‚   β”‚   β”œβ”€β”€ login/             # Authentication
β”‚   β”‚   β”œβ”€β”€ profile/           # User profile & settings
β”‚   β”‚   └── search/            # Recipe search
β”‚   β”œβ”€β”€ components/            # React components
β”‚   β”‚   β”œβ”€β”€ layout/           # Navbar, etc.
β”‚   β”‚   └── ui/               # Button, Card, Input, Toaster, etc.
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ services/         # External API integrations
β”‚   β”‚   β”‚   β”œβ”€β”€ elevenlabs.ts # TTS service
β”‚   β”‚   β”‚   β”œβ”€β”€ openai.ts     # Recipe normalization
β”‚   β”‚   β”‚   β”œβ”€β”€ recipe-parser.ts # Multi-fallback URL scraping
β”‚   β”‚   β”‚   β”œβ”€β”€ recipe-search.ts # TheMealDB + Spoonacular
β”‚   β”‚   β”‚   └── runware.ts    # Image generation (official SDK)
β”‚   β”‚   β”œβ”€β”€ storage/          # Media storage abstraction
β”‚   β”‚   β”‚   β”œβ”€β”€ base.ts       # Abstract base class
β”‚   β”‚   β”‚   β”œβ”€β”€ local.ts      # Local filesystem
β”‚   β”‚   β”‚   β”œβ”€β”€ s3.ts         # S3-compatible (AWS/R2/MinIO)
β”‚   β”‚   β”‚   β”œβ”€β”€ supabase.ts   # Supabase Storage
β”‚   β”‚   β”‚   └── index.ts      # Factory function
β”‚   β”‚   └── supabase/         # Supabase client utilities
β”‚   └── types/                # TypeScript types
β”œβ”€β”€ supabase/
β”‚   └── migrations/           # Database migrations
└── data/
    └── media/               # Local storage directory (gitignored)

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • npm
  • Supabase account (free tier works)
  • API keys for:
    • OpenAI (required - recipe normalization)
    • Runware (required - image generation)
    • ElevenLabs (required - voice narration)
    • Firecrawl (optional - enhanced recipe scraping)
    • Perplexity (optional - AI-powered scraping fallback)
    • Spoonacular (optional - recipe search)

1. Clone and Install

git clone https://github.com/keanucz/cook-dis.git
cd cook-dis
npm install

2. Set Up Supabase

  1. Create a new Supabase project at supabase.com
  2. Go to SQL Editor and run the migration file:
    • supabase/migrations/001_initial_schema.sql
  3. Enable Email Auth in Authentication β†’ Providers
  4. (Optional) Enable Google OAuth for social login
  5. If using Supabase Storage, create two private buckets:
    • recipe-step-images
    • recipe-step-audio

3. Configure Environment

Create .env.local with your values:

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# Media Storage (choose: local, supabase, or s3)
MEDIA_STORAGE_BACKEND=local
LOCAL_STORAGE_PATH=./data/media

# OpenAI (required)
OPENAI_API_KEY=sk-...

# Runware (required)
RUNWARE_API_KEY=...

# ElevenLabs (required)
ELEVENLABS_API_KEY=...

# Firecrawl (optional - for protected recipe sites)
FIRECRAWL_API_KEY=...

# Perplexity (optional - AI scraping fallback)
PERPLEXITY_API_KEY=...

# Spoonacular (optional - recipe search)
SPOONACULAR_API_KEY=...

# Worker Auth
CRON_SECRET=your-random-secret

# App URL
NEXT_PUBLIC_APP_URL=http://localhost:3000

4. Run Development Server

npm run dev

Open http://localhost:3000

πŸ–Ό Image Generation

Cook-Dis uses Runware's official SDK (@runware/sdk-js) for AI image generation:

  • WebSocket connection with auto-reconnect for reliability
  • Consistent visual style - all images use the same cookware (stainless steel pan, marble countertop) for continuity
  • Professional food photography prompts optimized for appetizing results
  • Base64 output for direct storage without additional downloads

Available Models

Model ID Description
FLUX.2 Dev flux2dev Fast generation, great quality (default)
FLUX.2 Max flux_2_max Highest quality, slower

Model preference is set per-user in Profile settings and persisted with each recipe.

πŸŽ™ Voice Narration

Text-to-speech is generated on-demand when the user taps play:

  1. First tap generates audio via ElevenLabs API
  2. Audio is cached in browser memory
  3. After all images complete, audio is preloaded for all steps in the background
  4. Subsequent plays are instant

This approach minimizes API costs while providing a smooth experience.

πŸ“¦ Media Storage Backends

Local Filesystem (Default)

MEDIA_STORAGE_BACKEND=local
LOCAL_STORAGE_PATH=./data/media
  • Files stored in ./data/media/ directory
  • Served via authenticated API route (/api/media/[...path])
  • Best for development and self-hosted deployments

Supabase Storage

MEDIA_STORAGE_BACKEND=supabase
  • Create private buckets: recipe-step-images, recipe-step-audio
  • Files served via signed URLs (1 hour expiry)

S3-Compatible (AWS S3, Cloudflare R2, MinIO)

MEDIA_STORAGE_BACKEND=s3
S3_ENDPOINT=https://your-account.r2.cloudflarestorage.com
S3_REGION=auto
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_BUCKET=cook-dis-media
S3_PUBLIC_BASE_URL=https://media.yourdomain.com  # Optional CDN

πŸ”„ Background Jobs

Media generation runs asynchronously via a Postgres-based job queue:

  1. Recipe Import β†’ Creates generate_step_image jobs for each step
  2. Cook Page β†’ Triggers worker automatically while waiting
  3. Worker processes jobs with retry logic (up to 3 attempts)
  4. Failed media can be manually retried from the cooking interface

Development

The cook page automatically triggers the worker every 15 seconds while images are generating.

Production (Vercel Cron)

{
  "crons": [{
    "path": "/api/jobs/worker",
    "schedule": "* * * * *"
  }]
}

Self-Hosted Cron

* * * * * curl -X POST https://your-domain.com/api/jobs/worker -H "Authorization: Bearer $CRON_SECRET"

πŸ”’ Security

  • All API keys are server-side only (never exposed to client)
  • Row Level Security (RLS) on all Supabase tables
  • Users can only access their own recipes and media
  • Signed URLs for private media access
  • CRON_SECRET protects the worker endpoint

πŸ“± Recipe Import Sources

URL Import (Multi-Fallback)

  1. Direct Fetch - Standard HTTP request with cheerio parsing
  2. Firecrawl - Handles Cloudflare, JavaScript rendering
  3. Perplexity AI - Uses AI to extract recipe from any page

Supports most recipe websites via:

  • Schema.org JSON-LD (preferred)
  • Microdata markup
  • OpenAI-powered content extraction

Recipe Search

  • TheMealDB: Free, no API key required
  • Spoonacular: Requires API key, more comprehensive database

πŸš€ Deployment

Vercel (Recommended)

  1. Push to GitHub
  2. Import project in Vercel
  3. Add environment variables
  4. Deploy!

Vercel automatically handles the cron job for background processing.

Docker

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
docker build -t cook-dis .
docker run -p 3000:3000 --env-file .env.local cook-dis

πŸ”‘ Getting API Keys

Service URL Notes
OpenAI platform.openai.com Required - GPT-4o for recipe parsing
Runware runware.ai Required - FLUX.2 image generation
ElevenLabs elevenlabs.io Required - Free tier available
Firecrawl firecrawl.dev Optional - Enhanced scraping
Perplexity perplexity.ai Optional - AI fallback
Spoonacular spoonacular.com/food-api Optional - Recipe search

🀝 Contributing

Contributions are welcome! Please open an issue or PR.

πŸ“„ License

MIT License - see LICENSE


Built with ❀️ for home cooks everywhere. Happy cooking! 🍳

About

cook dis: for people with dyslexia or otherwise who just want to make any long online recipe into a step-by-step thing

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors