# saeetarde/photo-booth architecture

> Architecture diagram of the GitHub repository saeetarde/photo-booth, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/saeetarde/photo-booth
- Repository: https://github.com/saeetarde/photo-booth

## Overview

Booth for Two is a browser-based, two-person photo booth. A visitor creates or enters a room code, shares the room link, and joins a live camera call; either partner can trigger a synchronized four-shot session, optionally decorate the video with a face-tracked bunny overlay, apply a photo style, and download the resulting strip. The server serves the pages and relays room signaling and session-start events, while media travels peer-to-peer through WebRTC. The graph follows the supplied source; landing and page markup are represented by their exact paths, but their contents were not sampled.

Main entry points: [`public/js/booth.js`](https://github.com/saeetarde/photo-booth/blob/main/public/js/booth.js) (Booth controls), [`public/js/socket.js`](https://github.com/saeetarde/photo-booth/blob/main/public/js/socket.js) (WebSocket client), [`server.js`](https://github.com/saeetarde/photo-booth/blob/main/server.js) (HTTP and signaling), [`public/js/webrtc.js`](https://github.com/saeetarde/photo-booth/blob/main/public/js/webrtc.js) (Peer call)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Room entry"]
  node_landing["Room entry UI<br/>[index.html]"]
  node_landingjs["Create or join<br/>[landing.js]"]
  node_boothpage["Booth page<br/>[booth.html]"]
  node_booth["Booth controls<br/>[booth.js]"]
end

subgraph group_connect["Live connection"]
  node_socket["WebSocket client<br/>[socket.js]"]
  node_webrtc["Peer call<br/>[webrtc.js]"]
  node_camera(("Camera and mic"))
  node_stun(("STUN service"))
end

subgraph group_photos["Photo creation"]
  node_capture["Four-shot capture<br/>[capture.js]"]
  node_doodle["Face-tracked overlay<br/>[doodle.js]"]
  node_faceapi(("Face models"))
  node_strip["Strip composition<br/>[strip.js]"]
  node_filters["Photo styles<br/>[filters.js]"]
  node_download["Downloaded image"]
end

subgraph group_runtime["Server runtime"]
  node_server["HTTP and signaling<br/>[server.js]"]
  node_rooms[("Room membership<br/>[server.js]")]
end

node_visitor(("Visitor"))
node_partner(("Room partner"))

node_visitor -->|"opens"| node_landing
node_landing -->|"loads script"| node_landingjs
node_landingjs -->|"navigates to"| node_boothpage
node_visitor -->|"uses controls"| node_booth
node_server -->|"serves page"| node_landing
node_server -->|"serves room page"| node_boothpage
node_booth -->|"creates client"| node_socket
node_socket -->|"joins and signals"| node_server
node_server -->|"updates membership"| node_rooms
node_server -->|"relays events"| node_socket
node_socket -->|"delivers signaling"| node_webrtc
node_webrtc -->|"requests media"| node_camera
node_webrtc -.->|"uses ICE service"| node_stun
node_webrtc -->|"negotiates peer call"| node_partner
node_partner -->|"streams media"| node_webrtc
node_booth -->|"starts session"| node_capture
node_booth -->|"sends snap start"| node_socket
node_socket -->|"relays snap start"| node_partner
node_booth -->|"controls overlay"| node_doodle
node_doodle -.->|"loads models"| node_faceapi
node_capture -->|"reads composite"| node_doodle
node_capture -->|"passes shots"| node_strip
node_booth -->|"renders result"| node_strip
node_strip -->|"applies style"| node_filters
node_booth -->|"exports PNG"| node_download

click node_landing "https://github.com/saeetarde/photo-booth/blob/main/public/index.html"
click node_landingjs "https://github.com/saeetarde/photo-booth/blob/main/public/js/landing.js"
click node_boothpage "https://github.com/saeetarde/photo-booth/blob/main/public/booth.html"
click node_booth "https://github.com/saeetarde/photo-booth/blob/main/public/js/booth.js"
click node_server "https://github.com/saeetarde/photo-booth/blob/main/server.js"
click node_rooms "https://github.com/saeetarde/photo-booth/blob/main/server.js"
click node_socket "https://github.com/saeetarde/photo-booth/blob/main/public/js/socket.js"
click node_webrtc "https://github.com/saeetarde/photo-booth/blob/main/public/js/webrtc.js"
click node_capture "https://github.com/saeetarde/photo-booth/blob/main/public/js/capture.js"
click node_doodle "https://github.com/saeetarde/photo-booth/blob/main/public/js/doodle.js"
click node_strip "https://github.com/saeetarde/photo-booth/blob/main/public/js/strip.js"
click node_filters "https://github.com/saeetarde/photo-booth/blob/main/public/js/filters.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_landing,node_landingjs,node_boothpage,node_booth toneBlue
class node_socket,node_webrtc,node_camera,node_stun toneAmber
class node_capture,node_doodle,node_faceapi,node_strip,node_filters,node_download toneMint
class node_server,node_rooms toneRose
class node_visitor,node_partner toneIndigo
```

## Components

### Room entry

- [Room entry UI](https://github.com/saeetarde/photo-booth/blob/main/public/index.html): `public/index.html`
- [Create or join](https://github.com/saeetarde/photo-booth/blob/main/public/js/landing.js): `public/js/landing.js`
- [Booth page](https://github.com/saeetarde/photo-booth/blob/main/public/booth.html): `public/booth.html`
- [Booth controls](https://github.com/saeetarde/photo-booth/blob/main/public/js/booth.js): `public/js/booth.js`

### Live connection

- [WebSocket client](https://github.com/saeetarde/photo-booth/blob/main/public/js/socket.js): `public/js/socket.js`
- [Peer call](https://github.com/saeetarde/photo-booth/blob/main/public/js/webrtc.js): `public/js/webrtc.js`
- **Camera and mic**
- **STUN service**

### Photo creation

- [Four-shot capture](https://github.com/saeetarde/photo-booth/blob/main/public/js/capture.js): `public/js/capture.js`
- [Face-tracked overlay](https://github.com/saeetarde/photo-booth/blob/main/public/js/doodle.js): `public/js/doodle.js`
- **Face models**
- [Strip composition](https://github.com/saeetarde/photo-booth/blob/main/public/js/strip.js): `public/js/strip.js`
- [Photo styles](https://github.com/saeetarde/photo-booth/blob/main/public/js/filters.js): `public/js/filters.js`
- **Downloaded image**

### Server runtime

- [HTTP and signaling](https://github.com/saeetarde/photo-booth/blob/main/server.js): `server.js`
- [Room membership](https://github.com/saeetarde/photo-booth/blob/main/server.js): `server.js`

### Other components

- **Visitor**
- **Room partner**

## Connections

- Visitor → Room entry UI: opens
- Room entry UI → Create or join: loads script
- Create or join → Booth page: navigates to
- Visitor → Booth controls: uses controls
- HTTP and signaling → Room entry UI: serves page
- HTTP and signaling → Booth page: serves room page
- Booth controls → WebSocket client: creates client
- WebSocket client → HTTP and signaling: joins and signals
- HTTP and signaling → Room membership: updates membership
- HTTP and signaling → WebSocket client: relays events
- WebSocket client → Peer call: delivers signaling
- Peer call → Camera and mic: requests media
- Peer call → STUN service: uses ICE service
- Peer call → Room partner: negotiates peer call
- Room partner → Peer call: streams media
- Booth controls → Four-shot capture: starts session
- Booth controls → WebSocket client: sends snap start
- WebSocket client → Room partner: relays snap start
- Booth controls → Face-tracked overlay: controls overlay
- Face-tracked overlay → Face models: loads models
- Four-shot capture → Face-tracked overlay: reads composite
- Four-shot capture → Strip composition: passes shots
- Booth controls → Strip composition: renders result
- Strip composition → Photo styles: applies style
- Booth controls → Downloaded image: exports PNG
