Local development
Hacking on the app from a local checkout. For running GiftWrapt (self-hosted or on a managed platform) see Get started.
Requirements
Section titled “Requirements”- Node.js 22+
- pnpm 10+ (Corepack will pick up the version pinned in
package.json) - Docker (for local Postgres + S3-compatible storage)
1. Install dependencies
Section titled “1. Install dependencies”pnpm install2. Configure environment
Section titled “2. Configure environment”cp env.example .env.localAt minimum, set:
DATABASE_URL- point at your local Postgres (the bundled compose stack listens onlocalhost:54321)BETTER_AUTH_SECRET- any long random stringBETTER_AUTH_URL-http://localhost:3000for devSTORAGE_*- see storage.md for the recipe matching your chosen backend
Optional:
RESEND_API_KEY+RESEND_FROM_EMAIL- enables transactional email. Without these, comment notifications, birthday emails, and the admin “send test email” button silently no-op.
The full annotated reference lives in env.example.
3. Start dependencies
Section titled “3. Start dependencies”The bundled compose file boots Postgres plus exactly one S3-compatible storage backend. Pick one:
# Garage (default; admin-API bootstrap)docker compose --profile garage up -dpnpm storage:init
# OR RustFS (MinIO-compatible, simpler bootstrap)docker compose --profile rustfs up -dpnpm storage:init:rustfsStick with one for the lifetime of the checkout - they share Postgres but bind different storage volumes.
4. Run migrations and seed
Section titled “4. Run migrations and seed”pnpm db:migrateSEED_SAFE=1 pnpm db:seed # optional, populates test users[!WARNING]
db:seedtruncates the database before inserting fixtures. It refuses to run unlessDATABASE_URLpoints at a known-local host ANDSEED_SAFE=1is set, but it absolutely will clobber your local data. See local-dev-admin.md for the seeded credentials.
5. Run the app
Section titled “5. Run the app”pnpm devOther dev servers
Section titled “Other dev servers”| Command | Port | What |
|---|---|---|
pnpm storybook | 6006 | Component explorer + a11y addon |
pnpm dev-email | 3001 | React Email preview |
pnpm db:studio | 4983 | Drizzle Studio |
Resetting
Section titled “Resetting”docker compose --profile garage down -v # nuke Postgres + Garage volumes# (or --profile rustfs)The destructive pnpm db:reset script is intentionally not run automatically. See local-dev-admin.md for the safe break-glass paths.
Next steps
Section titled “Next steps”- Contributing - scripts, conventions, PR workflow
- Storage - swapping backends, env reference
- Scraping - URL scraping pipeline (browserless, AI extractors)