crumbs#
dev#
prereqs: bun, docker, ios simulator (or device + ngrok)
bun install
cp api/.env.example api/.env
cp mobile/.env.example mobile/.env
# fill
bun run infra:up
bun run db:migrate
bun run db:seed # optional: a stockholm-flavoured dev dataset for me@seed.crumbs.test
bun run api:dev
bun run mobile:start
physical device: run bun run api:tunnel and set both PUBLIC_API_URL (api) and EXPO_PUBLIC_API_URL (mobile) to the ngrok url so magic-link emails resolve.
avatars / media storage#
user avatars are processed server-side (re-encoded to a 512px webp, exif stripped) and stored in object storage. the client pre-crops + downscales for upload bandwidth; the server is the security boundary.
STORAGE_DRIVER selects the backend:
disk(default) — writes underUPLOADS_DIRand serves them atPUBLIC_API_URL/static. zero setup, used for local dev + tests.r2— cloudflare r2. create a bucket, an api token (access key id + secret), and expose the bucket publicly via a custom domain (or ther2.devurl). setR2_ENDPOINT,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_BUCKET, andR2_PUBLIC_BASE_URL. objects are content-addressed and immutable, so a long edge cache rule is safe.
scripts#
bun run ok— tsck + lint + format check + testsbun run db:generate --name <change>— generate a migration fromcore/db/schema.ts; always pass--nameso it gets a descriptive filename (e.g.crumb_images), never the random defaultbun run db:seed— seed a local dev dataset (idempotent); log in asme@seed.crumbs.testbun run db:studio— drizzle studiobun run infra:down— stop docker servicesbun run infra:teardown— stop services + drop volumes (wipes db)