A coffee brewing journal for dialing in your pour-over, espresso, and everything in between — log your beans and brews, get AI coaching on your last cup, and share your best recipes with the community.
English · 繁體中文
Brew Log is a full-stack web app for coffee enthusiasts who want to brew more deliberately. Record each bag of beans and every brew — grind, dose, water, temperature, time, TDS, extraction yield, and a full taste profile — then let an AI brew master read your notes and tell you what to change next time. Make a brew public to share it on the community feed, where other members can rate it.
It doubles as a reference implementation of a modern Next.js App Router stack: server components and server actions end to end, Better Auth for authentication, Drizzle + Neon for the database, the Vercel AI SDK for AI features, and an editorial design system built on Tailwind and Base UI.
- Beans & brews — Full CRUD for your coffee library and brew log, with detailed metrics (dose, water ratio, temperature, time, TDS, extraction yield) and a five-axis taste profile.
- AI bean scan — Photograph a bag and Gemini auto-fills the roaster, origin, process, roast level, and tasting notes.
- AI brew master — Ask an AI coach to analyze any brew and suggest concrete adjustments for your next cup; advice is cached per brew so re-viewing never re-bills the model.
- Community & sharing — Publish brews to the Explore feed, browse public profiles at
/u/[username], and give other members' brews a 1–5 star rating. - Authentication — Email/password and Google sign-in via Better Auth, with email verification, forgot/reset password, and change-password flows.
- Internationalization — Ships with English and Traditional Chinese (
zh-Hant), switchable per user in Settings. - Guardrails — Per-user record caps and monthly AI usage counters keep token spend in check, with paginated lists throughout. AI features require a verified email, and sign-ups are rate-limited per IP via Better Auth backed by Upstash Redis — so limits hold across serverless instances and cold starts instead of resetting per invocation.
| Area | Technology |
|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript |
| Database | Neon Postgres + Drizzle ORM |
| Auth | Better Auth (email/password, Google, username plugin) |
| AI | Vercel AI SDK + Google Gemini |
| Resend | |
| Rate limit | Upstash Redis (Better Auth secondary storage) |
| Styling | Tailwind CSS v4, Base UI |
| Deployment | Vercel |
- Node.js 20+ and pnpm
- A Neon Postgres database (or any Postgres connection string)
- API keys for the services you want to enable (Google AI, Google OAuth, Resend)
-
Install dependencies:
pnpm install
-
Create a
.envfile in the project root:# Database DATABASE_URL="postgresql://..." # Better Auth BETTER_AUTH_SECRET="a-long-random-string" BETTER_AUTH_URL="http://localhost:3000" # Google OAuth (optional — enables "Sign in with Google") GOOGLE_CLIENT_ID="..." GOOGLE_CLIENT_SECRET="..." # Google Gemini (optional — enables AI bean scan & brew master) GOOGLE_GENERATIVE_AI_API_KEY="..." # Resend (optional — enables verification & password-reset emails) RESEND_API_KEY="..." EMAIL_FROM="onboarding@resend.dev" # Upstash Redis (optional — backs auth rate limiting across instances) UPSTASH_REDIS_REST_URL="..." UPSTASH_REDIS_REST_TOKEN="..."
-
Push the schema to your database:
pnpm db:push
-
(Optional) Seed some sample data:
pnpm db:seed
-
Start the development server:
pnpm dev
Open http://localhost:3000 to see the app.
Note
AI, Google login, and email features are optional. The app runs without their keys — those specific flows are simply unavailable until you provide them.
Warning
With the default onboarding@resend.dev sender, Resend can only deliver to your own account email. To email real users, verify a domain in Resend and set EMAIL_FROM accordingly.
pnpm dev # Start the development server
pnpm build # Build for production
pnpm start # Start the production server (requires build first)
pnpm lint # Run ESLint
pnpm db:push # Sync schema changes directly to the DB (development)
pnpm db:generate # Generate SQL migration files from schema changes
pnpm db:migrate # Apply generated migrations
pnpm db:studio # Open Drizzle Studio to browse data
pnpm db:seed # Seed sample datasrc/
├── app/
│ ├── (app)/ # Authenticated app — beans, brews, explore, journal, settings
│ ├── (auth)/ # Login, signup, forgot/reset password
│ └── api/auth/ # Better Auth route handler
├── components/ # Shared UI (editorial design system)
└── lib/
├── auth.ts # Better Auth configuration
├── db/ # Drizzle schema, client, and seeds
├── i18n/ # Locale config and message catalogs (en, zh-Hant)
├── redis.ts # Upstash Redis client (auth rate-limit storage)
└── ... # Ratings, limits, email, formatting helpers
The app is built to deploy on Vercel. Set the environment variables above in your project settings, point DATABASE_URL at your production Neon database, and set BETTER_AUTH_URL to your production URL. For Google login, add the production redirect URI in the Google Cloud console.