The perfect gin & tonic pairing algorithm. A web application that helps you discover the ideal tonic water and garnish for your favorite gin.
- 🔍 Search through 50+ gin brands
- 🎯 Smart pairing algorithm with detailed reasoning
- ❤️ Save favorites (persisted in localStorage)
- 🕐 Recently viewed history
- 📤 Shareable pairing links
- 🍸 Cocktail recipe with ratios and glass recommendations
- 🎲 "Surprise Me" random selection
- 🌊 Mood-based discovery (Refreshing, Bold, Sweet, Herbal, Exotic)
- 🛒 Amazon links for tonic water
- 🎨 Beautiful glassmorphic UI with animated bubbles
- Alpine.js - Lightweight reactive framework
- Tailwind CSS - Utility-first styling
- Custom CSS - Glassmorphism effects and animations
- Cloudflare Pages - Static site hosting with edge functions
- Cloudflare Workers - Serverless API endpoints
- Durable Objects - Persistent, globally distributed data storage
- Node.js/Express - Local development server
- JSON file storage - Local data persistence
- A Cloudflare account
- Node.js 18+ installed
- Wrangler CLI (
npm install -g wrangler)
- Clone and install dependencies:
git clone <your-repo-url>
cd Tonicwater_io
npm install- Login to Cloudflare:
wrangler login- Create a new Pages project:
wrangler pages project create tonicwater-io- Deploy:
npm run deployAfter deploying, you need to configure the Durable Object binding:
-
Go to Cloudflare Dashboard → Pages → tonicwater-io
-
Click Settings → Functions
-
Under Durable Object bindings, add:
- Variable name:
GIN_DATA - Durable Object namespace: Create new →
GinDataDO
- Variable name:
-
Redeploy for changes to take effect:
npm run deploy- In Cloudflare Dashboard → Pages → tonicwater-io → Custom domains
- Add your domain (e.g.,
tonicwater.io) - Follow DNS configuration instructions
npm install
npm start
# Visit http://localhost:3000npm run devnpm run dev:cf
# Visit http://localhost:8788Tonicwater_io/
├── public/
│ └── index.html # Frontend SPA
├── functions/
│ ├── _middleware.ts # CORS middleware
│ └── api/
│ ├── _gin-data.ts # Durable Object class
│ ├── gins.ts # GET/POST /api/gins
│ ├── gins/[name].ts # GET /api/gins/:name
│ └── categories.ts # GET /api/categories
├── server/
│ └── server.js # Local Express server
├── data/
│ ├── gins.json # Gin database (local)
│ └── tonic-links.json # Amazon links mapping
├── wrangler.toml # Cloudflare configuration
├── package.json
└── README.md
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/gins |
Get all gins |
| GET | /api/gins?search=query |
Search gins by name or profile |
| GET | /api/gins/:name |
Get specific gin by name |
| GET | /api/categories |
Get quick-select categories |
| POST | /api/gins |
Add a new gin (requires body) |
{
"name": "Monkey 47",
"profile": "Complex Herbal",
"tonic": "Mediterranean Tonic",
"garnish": "Sage leaf or Grapefruit zest",
"why": "The herbal sage bridges the 47 distinct botanicals...",
"amazonLink": "https://www.amazon.com/s?k=fever+tree+mediterranean+tonic"
}curl -X POST https://tonicwater.io/api/gins \
-H "Content-Type: application/json" \
-d '{
"name": "Your Gin",
"profile": "Flavor Profile",
"tonic": "Recommended Tonic",
"garnish": "Garnish",
"why": "Pairing explanation"
}'Edit data/gins.json directly and restart the server.
| Variable | Description | Default |
|---|---|---|
PORT |
Local server port | 3000 |
ENVIRONMENT |
Deployment environment | production |
MIT