cardamom
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v62View latest version
A mobile-friendly web application that captures, parses, and stores recipes from multiple sources including URLs, PDFs, images, and plain text.
- Multi-source Recipe Input: Accept recipes from:
- Web URLs (recipe websites)
- PDF files
- Images (photos of recipes)
- Plain text input
- Intelligent Parsing: Automatically extracts:
- Dish title and description
- Ingredients with precise quantities and units
- Step-by-step cooking instructions
- Cooking metadata (prep time, cook time, servings, difficulty)
- Recipe tags and source information
- Mobile-Friendly: Responsive design optimized for mobile devices
- Recipe Storage: Persistent SQLite storage with full CRUD operations
- Recipe Management: View, edit, delete, and organize saved recipes
- Advanced Features:
- Recipe filtering and search
- Fraction-to-decimal conversion for precise measurements
- Comprehensive error handling and validation
- Real-time parsing feedback
- Frontend: React 18.2.0 with TypeScript, TailwindCSS
- Backend: Hono API framework with TypeScript
- Database: SQLite with normalized schema (recipes + ingredients tables)
- AI: OpenAI GPT-4o-mini for intelligent recipe parsing
- File Processing:
- PDF parsing via
unpdf
library - Image OCR via OpenAI Vision API
- URL content extraction
- PDF parsing via
├── backend/
│ ├── database/
│ │ ├── migrations.ts # Database schema
│ │ └── queries.ts # Database operations
│ ├── routes/
│ │ ├── recipes.ts # Recipe CRUD operations
│ │ └── parse.ts # Recipe parsing endpoints
│ └── index.ts # Main API entry point
├── frontend/
│ ├── components/
│ │ ├── App.tsx # Main app component
│ │ ├── RecipeForm.tsx # Recipe input form
│ │ ├── RecipeList.tsx # Recipe listing
│ │ └── RecipeView.tsx # Individual recipe display
│ ├── index.html # Main HTML template
│ └── index.tsx # Frontend entry point
└── shared/
└── types.ts # Shared TypeScript types
GET /api/recipes
- Get all recipes (supports filtering via query params)?search=term
- Search in recipe titles and descriptions?difficulty=easy|medium|hard
- Filter by difficulty?maxPrepTime=minutes
- Filter by maximum prep time?maxCookTime=minutes
- Filter by maximum cook time?tags=tag1,tag2
- Filter by tags
POST /api/recipes
- Save a new recipeGET /api/recipes/:id
- Get specific recipe by IDPUT /api/recipes/:id
- Update existing recipeDELETE /api/recipes/:id
- Delete recipe
POST /api/parse/url
- Parse recipe from web URLPOST /api/parse/pdf
- Parse recipe from PDF file (base64)POST /api/parse/image
- Parse recipe from image (base64)POST /api/parse/text
- Parse recipe from plain text
GET /api/health
- Health check endpointGET /api/test-delete
- Test endpoint for debugging delete operations
- Open the app in your browser
- Choose input method (URL, PDF, or image)
- Submit your recipe source
- Review and edit the parsed recipe
- Save to your recipe collection