A modern web photo booth — capture, edit, and share photo strips directly in the browser. No app download required.
Live: clickstudio.vercel.app
- Live Camera — HD webcam with device switching, grid overlay, mirror toggle, and flash
- Timer & Burst — 3s/5s/10s countdown; burst mode auto-fires all shots; countdown beeps included
- Image Upload — Drop existing photos into the same filter + frame pipeline
- Retake — Thumbnail strip after each shot; delete and reshoot any photo
- 37 Templates across 15 categories: Birthday, Wedding, Graduation, Couple, Friends, Family, Holiday, K-Pop, Vintage, Minimal, Aesthetic, Seasonal, Corporate, Custom — including 9 PNG frame templates (Anniversary, Valentine, Family, Christmas, etc.)
- Template Carousel — Centered horizontal scroll with snap, glassmorphism arrows, floating cards with badges (New/Popular/Trending)
- Template Library Modal — Search, sort (Popular/Newest/A–Z), favorites, responsive grid, snap-scrolling category chips
- Classic & Frame Styles — Toggle between plain layouts and decorative frame templates
- Filters — 13 film presets (Vintage, B&W, Dreamy, etc.) applied per-photo with live preview thumbnails
- Frame Overlays — Clean, Film, Blush, Minimal, Polaroid — applied per-photo at capture or in editor
- Stickers — 10 themed packs (160+ emoji): Coquette, Y2K, Nature, Hearts, Food, Animals, etc.
- Text Overlays — 6 font presets, 15 colors, adjustable size — drag to reposition
- Composite Strip — All photos composited into one PNG with a ClickStudio watermark
- Print-Ready PDF — 300 DPI in 6 sizes: 2×6 strip, 4×6 print, A4, US Letter
- QR Code — Generate a shareable link; public
/share/[sessionId]page for anyone to view & download - Web Share API — Native share on supported devices; falls back to download
- Save to Cloud — Session + photos synced to Supabase Storage
- What's New — Auto-shows once per version with a changelog; dismiss state in localStorage
- Feedback Wall — Community messages displayed on the landing page
- PWA — Installable as a native-like app
- Responsive — Desktop and mobile
- Landing — click Start the Studio
- Camera — pick a template (carousel or library), capture photos with timer/mirror/filters/frames, or upload — auto-redirects to Preview when done
- Preview — see the final composited strip; edit individual photos; retake shots; add Polaroid captions; generate QR code; download as PNG or PDF; save to cloud
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite |
| Styling | Tailwind CSS, Framer Motion |
| State | Zustand |
| Backend | Supabase (Database, Storage) |
| Icons | Lucide React |
| Fonts | Inter, DM Serif Display, Dancing Script |
| Deployment | Vercel |
Prerequisites: Node.js 18+, a modern browser with WebRTC, a Supabase project.
git clone https://github.com/sainttlaurel/ClickStudio.git
cd ClickStudio
npm install
cp .env.example .envAdd your credentials to .env:
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key# Run the database schema in the Supabase SQL Editor
# Open supabase/schema.sql and run it
npm run devRun supabase/schema.sql once in the Supabase SQL Editor. It creates:
sessionstable with anupdated_attriggerphotostable with a cascade delete foreign keyphotosstorage bucket (public, 10 MB limit)- Row Level Security policies (public access, no login required)
src/
├── components/
│ ├── ui/ # Button, Input, Modal, Slider, Toaster, ChangelogModal
│ ├── layout/ # Header, Sidebar, Layout
│ └── templates/ # TemplateLibrary modal
├── constants/
│ ├── filters.ts # 13 film filter presets
│ ├── frames.ts # 5 frame overlay definitions
│ ├── stickers.ts # 10 sticker packs, text presets, colors
│ ├── changelog.ts # Versioned changelog + localStorage helpers
│ ├── templates.ts # 28 template library items, 15 categories
│ └── index.ts # Barrel export (filters, frames)
├── pages/
│ ├── LandingPage.tsx # Landing with feedback wall
│ ├── CameraPage.tsx # Camera, template carousel, filters, frames, mirror, timer
│ ├── PreviewPage.tsx # Composite result, edit, retake, QR, PDF, download
│ ├── EditorPage.tsx # Adjustments, stickers, text, filters, frames (compact layout)
│ ├── AboutPage.tsx # About / tech stack
│ ├── HelpPage.tsx # Help / FAQ
│ ├── SettingsPage.tsx # Settings
│ ├── SharePage.tsx # Public share page /share/[sessionId]
│ ├── GalleryPage.tsx # Placeholder (planned)
│ └── SessionHistoryPage.tsx # Placeholder (planned)
├── store/
│ ├── usePhotoStore.ts # Session, photo, camera state + Supabase sync
│ └── useUIStore.ts # Toast + modal state
├── lib/
│ └── supabase.ts # Typed client, upload/delete helpers
├── types/
│ └── index.ts # Photo, Template, CompositeStyle, CameraError, all shared types
└── utils/
├── camera.ts # CameraManager — capture, upload, filter + frame baking
├── compositor.ts # composeStrip — composites photos into a strip PNG
├── frameOverlay.ts # Shared frame drawing logic
├── pdf.ts # Print-ready PDF export at 300 DPI
├── sounds.ts # Countdown/capture beep sounds
└── cn.ts # Class name utility (clsx + tailwind-merge)
supabase/
└── schema.sql # Database schema and storage setup
docs/
├── BRAINSTORM.md # Feature brainstorm
├── ROADMAP.md # Active roadmap
├── CHANGESLOG.md # Version history
└── UIREVIEW.md # Design review & feedback
npm run dev # Development server
npm run build # Production build (tsc + vite)
npm run preview # Preview production build
npm run lint # ESLint
npm run type-check # TypeScript check
npm run format # PrettierAppend to FILTERS in src/constants/filters.ts:
{ id: 'myfilter', name: 'My Filter', css: 'sepia(30%) contrast(1.1) brightness(1.05)' }Append to FRAMES in src/constants/frames.ts:
{ id: 'myframe', name: 'My Frame', icon: '🖼', style: { /* CSS properties */ } }Add to the TEMPLATE_LIBRARY array in src/constants/templates.ts:
{
id: 'my-template',
name: 'My Template',
description: '4 shots · my custom style',
layout: 'quad',
aspectRatio: '1:1',
compositeStyle: 'blush',
preview: '',
previewEmoji: '🌸',
categories: ['all', 'custom'],
}Vercel (current):
- Import the GitHub repo in Vercel Dashboard
- Set
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYin environment variables - Pushes to
maindeploy automatically
vercel.json handles SPA routing via rewrites. Permissions-Policy: camera=* is set for camera API access.
- Email: clickstudio.dev@gmail.com
- Discord: Join our server
- GitHub: sainttlaurel/ClickStudio
MIT — see LICENSE.