A modern, performant photography website built with Vue 3 and Cloudflare Workers.
🌐 Live Demo: https://captured.yyin.me
| 📌 | 🚀 | 📝 |
|---|---|---|
| 🎨 Frontend | Vue + tailwindcss v4 | |
| ⚡ Backend | tRPC | End-to-end type-safe API |
| ☁️ Runtime | Cloudflare Workers | Serverless backend |
| 🗄 Database | D1 + Drizzle | Cloudflare's SQLite + type-safe ORM |
| 📦 Object Storage | R2 | Cloudflare's S3 bucket to store images |
| 🔐 Authentication | WebAuthn | Passkey authentication |
| 🖼 Image Handling | Responsive Images + Blurhash | Optimized delivery with low-bandwidth previews |
| 🎊 Animations | View Transition API | Smooth page transitions powered by the View Transition API |
This project uses a monorepo setup. All commands should be run from the project root.
- Install dependencies:
bun install- Configure environment:
Create
server/.dev.varswith:
secret="local"
allowCors=1
proxyR2=1
accountId=<your-cloudflare-account-id>
databaseId=<your-d1-database-id>
token=<your-cloudflare-api-token>- Start development server:
bun dev- Run database migrations:
bun migrate- Auto fix issues with ESLint and Prettier:
bun lint-
Select
esbenp.prettier-vscodeas the default formatter to avoid conflicts with other formatters -
Check for issues without auto-fixing:
bun lint:check-
Verify Cloudflare credentials in
server/.dev.vars -
Run production database migrations:
bun prod:migrate- Deploy:
bun prod:deploy- (Optional) Update secret key:
bun run wrangler secret --name <project> put secretWhen modifying wrangler.jsonc, regenerate types with:
bun types