A showcase for vibecoded projects — built entirely with LLMs.
Live site: https://slop.haus
- Frontend: Next.js 15, React 19, SWR
- Backend: Hono, better-auth
- Database: PostgreSQL, Drizzle ORM
- Worker: Custom job queue (Postgres-based)
- External: Firecrawl (scraping), Claude (LLM)
apps/
api/ # Hono API server (port 3001)
web/ # Next.js frontend (port 3000)
worker/ # Background job processor
packages/
db/ # Drizzle schema & migrations
shared/ # Shared types & utilities
- Node.js 20+
- pnpm 9+
- PostgreSQL 15+
# Install dependencies
pnpm install
# Copy env file and fill in values
cp .env.example .env
# Push database schema
pnpm db:push
# Reset and seed local database (destructive)
pnpm db:reset
# Seed without reset (non-destructive)
pnpm --filter @slop/db seed# Required
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/slophaus
AUTH_SECRET=generate-a-random-string
# OAuth (at least one)
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# External services
FIRECRAWL_API_KEY= # For URL scraping
ANTHROPIC_API_KEY= # For LLM analysis & moderation
# Storage (MVP)
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=./uploads
STORAGE_PUBLIC_URL=http://localhost:3001/uploads
# URLs
APP_URL=http://localhost:3000
API_URL=http://localhost:3001
NEXT_PUBLIC_GA_MEASUREMENT_ID= # Optional, format: G-XXXXXXXXXX
# Cookie consent banner
NEXT_PUBLIC_COOKIE_BANNER_ENABLED=true # Optional, default true
NEXT_PUBLIC_COOKIE_BANNER_FORCE_GLOBAL=false # Optional emergency kill switch
NEXT_PUBLIC_COOKIE_BANNER_POLICY_VERSION=2026-02-27 # Optional consent/policy version# Run all services (api, web, worker)
pnpm dev
# Launch Chrome with the repo's dedicated profile
pnpm chrome:project
# Database commands
pnpm db:generate # Generate migrations
pnpm db:migrate # Run migrations
pnpm db:push # Push schema (dev)
pnpm db:studio # Open Drizzle Studio
pnpm db:reset # Reset + seed local DB (destructive)db:reset is guarded to local DB hosts by default.
Set ALLOW_DB_RESET=1 to bypass the host check.
For local performance work, use the repo-managed Chrome launcher instead of a personal browser profile:
pnpm chrome:project
pnpm chrome:measure:mobile
pnpm chrome:measure:mobile -- --dismiss-introThis uses the env vars in .env / .env.example:
CHROME_BIN=/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
CHROME_USER_DATA_DIR=.chrome/slop-haus
CHROME_REMOTE_DEBUGGING_PORT=9222
CHROME_START_URL=http://localhost:3000/CHROME_USER_DATA_DIR is intentionally project-local and should stay separate from any existing Chrome profile.
pnpm chrome:measure:mobile writes artifacts to .chrome/measurements/. Use -- --dismiss-intro to compare the default feed against a fresh-profile run with slop:feedIntroDismissed=true.
| Service | Port |
|---|---|
| Web | 3000 |
| API | 3001 |
| Worker | N/A |
