Good news: I’ve already generated a complete starter kit (backend + mobile + docs) you can download now and run locally.
👉 Download the Shutterline MVP starter
What makes this different from Telegram?
- Photo‑first UX: zoom-to-100%, EXIF overlay, histogram, before/after.
- Shares that respect craft: preserve ICC profiles; optional watermark per upload; eight-bit and RAW friendly.
- Search like a pro: camera/lens/ISO/aperture/location/tags.
- E2EE where it matters: private 1:1 and invite‑only groups; server never sees plaintext.
- Client galleries & proofing: approve/reject/needs‑edit, download permissions, license badges.
- Rights & releases: attach model/property releases and set license terms per asset.
What you’re downloading
Monorepo layout
shutterline/
├─ backend/ # TypeScript (Express + Socket.IO), OpenAPI, stubs for S3 presign & E2EE
├─ mobile/ # Tiny React Native (Expo) demo app with chat + photo viewer
├─ docs/ # Architecture, Image Pipeline, Cryptography, Product plan
├─ ops/ # docker-compose: Postgres, Redis, MinIO (S3)
└─ scripts/ # small helpers
- Backend highlights
- Express + Socket.IO rooms (each conversation is a room).
- /api/photos/upload-url (presign stub) for S3/MinIO; easy to swap for Cloud storage.
- In‑memory chat for the demo; Postgres schema sketch included (Prisma style).
- OpenAPI spec (backend/openapi.yml) to grow cleanly.
- Mobile highlights
- Expo app with chat list, live updates, and a stub uploader to wire next.
- Docs included
- ARCHITECTURE.md: clients, realtime, storage, search, services.
- IMAGE_PIPELINE.md: RAW/ICC/EXIF handling, variants, deep‑zoom.
- CRYPTOGRAPHY.md: Signal-style double ratchet layout for private chats.
- PRODUCT.md: MVP → Stretch features, jobs‑to‑be‑done.
Start locally: spin up Postgres/Redis/MinIO via ops/docker-compose.yml, copy .env.example, then yarn dev in backend/ and expo start in mobile/.
Feature blueprint (MVP → Next)
MVP (ship something delightful)
- Core chat: 1:1, groups, broadcast channels; presence & typing indicators.
- Photo pipeline:
- Upload RAW + JPEG/TIFF; generate thumb, preview, 4k, keep original.
- Preserve ICC; configurable watermark; client‑side processing for E2EE rooms.
- EXIF‑smart search across all chats & galleries.
- Client galleries with approve/reject and secure links.
- Licensing: per‑asset badge (All Rights, CC variants, Editorial, RF).
- Moderation & safety: report/ban flows, basic filters, abuse desk (human‑in‑the‑loop).
Phase 2 (turn it into a home base)
- Non‑destructive versions: sidecars (XMP), before/after slider, version history.
- Proofing boards: moodboards + shot lists per project room.
- On‑device AI tags (privacy‑first): people/places/things; color/mood tags.
- Paid channels & tips, print‑lab integrations, marketplace for presets.
- Web PWA for galleries & admin.
Tech stack (practical and fast)
- Clients: React Native (Expo) for iOS/Android; Web (PWA) later.
- Realtime: Socket.IO + Redis adapter (horizontally scalable).
- API: REST + OpenAPI; Zod for request validation.
- DB: Postgres (metadata, ACLs, conversations); Redis (presence, queues).
- Storage/CDN: S3‑compatible object storage for originals & variants behind CDN.
- Search: Postgres JSONB + trigram indexes to start; upgrade to dedicated vector/semantic search later.
- E2EE: Signal double ratchet on clients; server stores only opaque ciphertext.
- Uploads: multipart/tus for big RAWs; presigned URLs; content scanning on public assets.
Data model sketch
- User(id, handle, displayName, avatarUrl, proTier)
- Device(public identity key, signed prekeys) — no private keys on server
- Conversation(id, kind: direct/group/channel/project, title, createdBy)
- Message(id, conversationId, senderId, kind, ciphertext/header for E2EE)
- PhotoAsset(ownerId, originalKey, variants[], exifEncrypted?, license, phash, iccProfile)
- Gallery(id, ownerId, permissions, downloadPolicy)
All of these are pre‑wired in the included Prisma‑style schema.
Critical flows to get right
- Private vs Public media
- Private (E2EE): client generates previews/watermark and encrypts blobs + EXIF before upload.
- Public (portfolio/channel): server can transform and index EXIF for search.
- Key management: device identity + prekeys; optional, zero‑knowledge backups with passphrase (Argon2id).
- Notifications: metadata‑only push (“New photo”), decrypt content on open.
- Licensing & watermarking: fast toggles; templated watermark overlays; download permissions per gallery.
How to extend the included code
- Wire real S3 presign
Implement backend/src/lib/storage.ts using @aws-sdk/client-s3 + @aws-sdk/s3-request-presigner for PUT or POST policies. - Persist messages
Replace the in‑memory message store with Postgres tables from the schema sketch. - Add EXIF extraction
For non‑E2EE uploads, use an ingest worker (e.g., BullMQ) to extract EXIF and generate variants. - Add E2EE
Integrate libsignal on the clients; store only public keys and opaque ciphertext server‑side (see CRYPTOGRAPHY.md). - Polish the viewer
Build a lightbox with 1:1 zoom, histogram, and EXIF toggles; deep‑zoom tiles later.
Name ideas (pick your vibe)
Shutterline, Lightbox, Darkroom DM, Photon Relay, F‑Stop Chat, The Lab.
Pick one, own it, and make it sing.
Your next move
- Grab the starter kit: Download the ZIP
- Run docker compose up -d in /ops, yarn dev in /backend, and expo start in /mobile.
- Start with one killer use case: share a RAW set, get approvals, deliver finals—without quality loss.
You’ve got this. Let’s give photographers the messaging app they deserve—fast, beautiful, and fiercely respectful of their work. 🚀