# googlechromelabs/squoosh architecture

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

- Interactive diagram: https://gitdiagram.com/googlechromelabs/squoosh
- Repository: https://github.com/googlechromelabs/squoosh

## Overview

Squoosh is a browser-based image compression and comparison app: users open or drop an image, optionally rotate/resize/quantize it, choose output encoders and settings, compare results, then save locally. Codec work runs through worker-facing feature modules and WebAssembly/native codec implementations; the README emphasizes that images remain on-device. The graph preserves documented codec families and PWA caching, but many feature-to-codec dispatches are unsampled, so those links are marked unverified rather than presented as observed calls.

Main entry points: [`src/client/lazy-app/Compress/index.tsx`](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/index.tsx) (Compression workspace), [`src/client/lazy-app/worker-bridge/index.ts`](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/worker-bridge/index.ts) (Worker bridge), [`src/shared/prerendered-app/Intro/index.tsx`](https://github.com/googlechromelabs/squoosh/blob/dev/src/shared/prerendered-app/Intro/index.tsx) (Intro and file intake), [`src/features/encoders`](https://github.com/googlechromelabs/squoosh/tree/dev/src/features/encoders) (Codec feature adapters)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["User experience"]
  node_intro["Intro and file intake<br/>[index.tsx]"]
  node_compress["Compression workspace<br/>[index.tsx]"]
  node_options["Encoder options<br/>[index.tsx]"]
  node_comparison["Image comparison<br/>[index.tsx]"]
  node_results["Compression results<br/>[index.tsx]"]
  node_cache[("Result cache<br/>[result-cache.ts]")]
  node_indexpage["Landing page<br/>[index.tsx]"]
end

subgraph group_features["Image processing"]
  node_workerbridge["Worker bridge<br/>[index.ts]"]
  node_preprocess["Rotate preprocessing<br/>[rotate.ts]"]
  node_resize["Resize processing<br/>[resize.ts]"]
  node_quantize["Palette quantization<br/>[quantize.ts]"]
  node_codecfeatures["Codec feature adapters"]
end

subgraph group_runtime["Codec runtime"]
  node_codecimpl["Codec implementations"]
  node_decode["Image decoders"]
end

subgraph group_pwa["PWA delivery"]
  node_sw["Service worker<br/>[index.ts]"]
  node_cachepolicy["Dynamic cache policy<br/>[to-cache.ts]"]
  node_static["Static app and manifest<br/>[index.tsx]"]
end

node_user(("Image user"))

node_user -->|"opens image"| node_intro
node_intro -.->|"selects image"| node_compress
node_compress -->|"renders settings"| node_options
node_compress -->|"renders comparison"| node_comparison
node_compress -->|"renders results"| node_results
node_compress -->|"uses cache"| node_cache
node_compress -->|"dispatches work"| node_workerbridge
node_workerbridge -.->|"runs rotation"| node_preprocess
node_workerbridge -.->|"runs resize"| node_resize
node_workerbridge -.->|"runs quantization"| node_quantize
node_workerbridge -.->|"runs decoding"| node_decode
node_workerbridge -.->|"runs encoding"| node_codecfeatures
node_codecfeatures -.->|"uses codecs"| node_codecimpl
node_sw -->|"checks cache policy"| node_cachepolicy
node_static -->|"renders page"| node_indexpage

click node_intro "https://github.com/googlechromelabs/squoosh/blob/dev/src/shared/prerendered-app/Intro/index.tsx"
click node_compress "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/index.tsx"
click node_options "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Options/index.tsx"
click node_comparison "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Output/index.tsx"
click node_results "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Results/index.tsx"
click node_cache "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/result-cache.ts"
click node_workerbridge "https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/worker-bridge/index.ts"
click node_preprocess "https://github.com/googlechromelabs/squoosh/blob/dev/src/features/preprocessors/rotate/worker/rotate.ts"
click node_resize "https://github.com/googlechromelabs/squoosh/blob/dev/src/features/processors/resize/worker/resize.ts"
click node_quantize "https://github.com/googlechromelabs/squoosh/blob/dev/src/features/processors/quantize/worker/quantize.ts"
click node_codecfeatures "https://github.com/googlechromelabs/squoosh/tree/dev/src/features/encoders"
click node_codecimpl "https://github.com/googlechromelabs/squoosh/tree/dev/codecs"
click node_decode "https://github.com/googlechromelabs/squoosh/tree/dev/src/features/decoders"
click node_sw "https://github.com/googlechromelabs/squoosh/blob/dev/src/sw/index.ts"
click node_cachepolicy "https://github.com/googlechromelabs/squoosh/blob/dev/src/sw/to-cache.ts"
click node_static "https://github.com/googlechromelabs/squoosh/blob/dev/src/static-build/index.tsx"
click node_indexpage "https://github.com/googlechromelabs/squoosh/blob/dev/src/static-build/pages/index/index.tsx"

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_intro,node_compress,node_options,node_comparison,node_results,node_cache,node_indexpage,node_user toneBlue
class node_workerbridge,node_preprocess,node_resize,node_quantize,node_codecfeatures toneAmber
class node_codecimpl,node_decode toneMint
class node_sw,node_cachepolicy,node_static toneRose
```

## Components

### User experience

- [Intro and file intake](https://github.com/googlechromelabs/squoosh/blob/dev/src/shared/prerendered-app/Intro/index.tsx): `src/shared/prerendered-app/Intro/index.tsx`
- [Compression workspace](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/index.tsx): `src/client/lazy-app/Compress/index.tsx`
- [Encoder options](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Options/index.tsx): `src/client/lazy-app/Compress/Options/index.tsx`
- [Image comparison](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Output/index.tsx): `src/client/lazy-app/Compress/Output/index.tsx`
- [Compression results](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/Results/index.tsx): `src/client/lazy-app/Compress/Results/index.tsx`
- [Result cache](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/Compress/result-cache.ts): `src/client/lazy-app/Compress/result-cache.ts`
- [Landing page](https://github.com/googlechromelabs/squoosh/blob/dev/src/static-build/pages/index/index.tsx): `src/static-build/pages/index/index.tsx`

### Image processing

- [Worker bridge](https://github.com/googlechromelabs/squoosh/blob/dev/src/client/lazy-app/worker-bridge/index.ts): `src/client/lazy-app/worker-bridge/index.ts`
- [Rotate preprocessing](https://github.com/googlechromelabs/squoosh/blob/dev/src/features/preprocessors/rotate/worker/rotate.ts): `src/features/preprocessors/rotate/worker/rotate.ts`
- [Resize processing](https://github.com/googlechromelabs/squoosh/blob/dev/src/features/processors/resize/worker/resize.ts): `src/features/processors/resize/worker/resize.ts`
- [Palette quantization](https://github.com/googlechromelabs/squoosh/blob/dev/src/features/processors/quantize/worker/quantize.ts): `src/features/processors/quantize/worker/quantize.ts`
- [Codec feature adapters](https://github.com/googlechromelabs/squoosh/tree/dev/src/features/encoders): `src/features/encoders`

### Codec runtime

- [Codec implementations](https://github.com/googlechromelabs/squoosh/tree/dev/codecs): `codecs`
- [Image decoders](https://github.com/googlechromelabs/squoosh/tree/dev/src/features/decoders): `src/features/decoders`

### PWA delivery

- [Service worker](https://github.com/googlechromelabs/squoosh/blob/dev/src/sw/index.ts): `src/sw/index.ts`
- [Dynamic cache policy](https://github.com/googlechromelabs/squoosh/blob/dev/src/sw/to-cache.ts): `src/sw/to-cache.ts`
- [Static app and manifest](https://github.com/googlechromelabs/squoosh/blob/dev/src/static-build/index.tsx): `src/static-build/index.tsx`

### Other components

- **Image user**

## Connections

- Image user → Intro and file intake: opens image (evidence: `src/shared/prerendered-app/Intro/index.tsx`)
- Intro and file intake → Compression workspace: selects image
- Compression workspace → Encoder options: renders settings (evidence: `src/client/lazy-app/Compress/index.tsx`)
- Compression workspace → Image comparison: renders comparison (evidence: `src/client/lazy-app/Compress/index.tsx`)
- Compression workspace → Compression results: renders results (evidence: `src/client/lazy-app/Compress/index.tsx`)
- Compression workspace → Result cache: uses cache (evidence: `src/client/lazy-app/Compress/index.tsx`)
- Compression workspace → Worker bridge: dispatches work (evidence: `src/client/lazy-app/Compress/index.tsx`)
- Worker bridge → Rotate preprocessing: runs rotation
- Worker bridge → Resize processing: runs resize
- Worker bridge → Palette quantization: runs quantization
- Worker bridge → Image decoders: runs decoding
- Worker bridge → Codec feature adapters: runs encoding
- Codec feature adapters → Codec implementations: uses codecs
- Service worker → Dynamic cache policy: checks cache policy (evidence: `src/sw/index.ts`)
- Static app and manifest → Landing page: renders page (evidence: `src/static-build/index.tsx`)
