A mobile-first packing list web app for travel with all-items management, trip planning, and bag organization. Built with Astro, Solid.js, Tailwind CSS, Cloudflare D1, and Clerk Auth.
- Frontend: Astro.js + Solid.js + Tailwind CSS + TypeScript
- Backend: Cloudflare Workers (TypeScript)
- Database: Cloudflare D1 (SQLite at the edge)
- ORM: Drizzle ORM
- Auth: Clerk
- Deployment: Cloudflare Pages
- π All items list with categories for your packing items
- π§³ Trip-specific packing lists
- π Bag organization (carry-on, checked, personal item)
- β Pack/unpack tracking
- π± Mobile-first design with large touch targets
- π Multi-device sync via Cloudflare D1
- π Secure authentication with Clerk
- Bun installed
- Cloudflare account
- Clerk account
bun install- Go to Clerk Dashboard
- Create a new application
- Copy your Publishable Key and Secret Key
- Create a
.envfile:
cp .env.example .env- Update
.envwith your Clerk keys:
PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here
CLERK_SECRET_KEY=sk_test_your_key_here# Login to Cloudflare (if you haven't already)
npx wrangler login
# Create D1 database
npx wrangler d1 create packzen-dbThis will output something like:
β
Successfully created DB 'packzen-db' in region WEUR
Created your database using D1's new storage backend.
[[d1_databases]]
binding = "DB"
database_name = "packzen-db"
database_id = "your-database-id-here"
Copy the database_id and update wrangler.jsonc:
# Generate migrations from schema
bun run db:generate
# Apply migrations to local D1 database
bun run db:migratebun run devThe app will be available at http://localhost:4321
# Start dev server
bun run dev
# Build for production
bun run build
# Preview production build
bun run preview
# Format code with Prettier
bun run format
# Generate database migrations
bun run db:generate
# Apply migrations (local)
bun run db:migrate
# Apply migrations (production)
bun run db:migrate:prod
# Open Drizzle Studio (database GUI)
bun run db:studioβββ db/ # Database schema & migrations
β βββ schema.ts # Drizzle schema definitions
β βββ migrations/ # Generated SQL migrations
βββ src/
β βββ components/ # Solid.js components
β βββ layouts/ # Astro layouts
β βββ lib/ # Utilities
β βββ middleware.ts # Astro middleware for auth
β βββ pages/ # Astro routes & API endpoints
β βββ stores/ # Solid stores
β βββ styles/ # Global CSS
βββ public/ # Static assets
βββ astro.config.mjs # Astro configuration
βββ drizzle.config.ts # Drizzle ORM configuration
βββ wrangler.jsonc # Cloudflare configuration
βββ package.json
# Build the project
bun run build
# Deploy to Cloudflare Workers (includes static assets)
npx wrangler deployThe first deployment will create a new Worker in your Cloudflare account.
# Set Clerk secret key
npx wrangler secret put CLERK_SECRET_KEY
# Paste your Clerk secret key when promptedUpdate wrangler.jsonc with your production values:
{
"vars": {
"PUBLIC_CLERK_PUBLISHABLE_KEY": "pk_live_your_production_key",
},
}Then redeploy: npx wrangler deploy
bun run db:migrate:prod- β Phase 1: Project Setup
- β Phase 2: Database Schema & Auth
- β Phase 3: All Items Management
- β Phase 4: Trip Management
- β Phase 5: Bag Management
- β Phase 6: Trip Items & Packing
- β Phase 7: Layout & Navigation
- β³ Phase 8: Polish & Optimization
- Minimum 44x44px touch targets
- 16px base font size (prevents iOS zoom)
- Bottom navigation for easy thumb access
- Large, clear tap targets for checkboxes
- Generous spacing (16px minimum)
- Smooth animations and transitions
- Cloudflare Pages: Unlimited sites, 500 builds/month
- Cloudflare Workers: 100K requests/day
- Cloudflare D1: 5GB storage, 5M reads/day, 100K writes/day
- Clerk: 10K monthly active users
MIT
{ "d1_databases": [ { "binding": "DB", "database_name": "packzen-db", "database_id": "paste-your-database-id-here", }, ], }