Squash is a modern, browser-based image compression tool that leverages WebAssembly for high-performance image optimization. It supports multiple image formats and provides an intuitive interface for compressing images without compromising quality.
π Read the project overview for more details.
- πΌοΈ Multiple Image Format Support: AVIF, JPEG (MozJPEG), JPEG XL, PNG (OxiPNG), WebP
- π High-performance Compression: Powered by WebAssembly codecs
- ποΈ Batch Processing: Process multiple images at once
- π Real-time Preview and Format Conversion
- π Size Reduction Statistics
- π₯ Drag & Drop Interface with Smart Queue for large files
- React + TypeScript: For the user interface
- Vite: For fast development and builds
- WebAssembly: For native-speed image processing
- Tailwind CSS: For styling
- jSquash: For image codec implementations
- Framer Motion: For animations
- GitHub Actions: For CI/CD
- Jest: For testing
Squash is built with a modular architecture that allows for easy addition of new image codecs and optimization tools. The core components are:
graph TD
A[User] --> B[React UI]
B --> C[Compression Options]
B --> D[DropZone]
B --> E[ImageList]
C --> F[WebAssembly Compression]
F --> G{Compression Codecs}
G --> H[AVIF]
G --> I[JPEG]
G --> J[JPEG XL]
G --> K[PNG]
G --> L[WebP]
The WebAssembly Compression Module handles the loading and initialization of codecs. Each codec provides a common interface for image compression. The React UI manages user interactions and displays compressed images.
sequenceDiagram
participant User
participant DropZone
participant CompressionEngine
participant WASM
participant DownloadManager
participant ClearButton
User ->> DropZone: Drag and drop images
DropZone ->> CompressionEngine: Add images to queue
CompressionEngine ->> WASM: Process images using WebAssembly
WASM -->> CompressionEngine: Return compressed image data
CompressionEngine ->> User: Display compressed image preview
User ->> DownloadManager: Click "Download All"
DownloadManager ->> User: Provide zip file with compressed images
User ->> DownloadManager: Click "Download" on individual image
DownloadManager ->> User: Download compressed image
User ->> ClearButton: Click "Clear All"
ClearButton ->> User: Clear all images
graph LR
App --> CompressionOptions
App --> DropZone
App --> ImageList
App --> DownloadAll
CompressionOptions --> QualitySelector
DropZone --> useImageManager
DropZone --> useImageQueue
ImageList --> ImageListItem
ImageListItem --> formatFileSize
ImageListItem --> downloadImage
The App
component serves as the main entry point, containing several child components:
- CompressionOptions: Manages output format and quality settings.
- DropZone: Handles drag-and-drop image uploads and queues images.
- ImageList: Displays a list of images.
- DownloadAll: Provides batch download functionality.
flowchart TD
A[Image Selection] --> B{Validate Image}
B -- Valid --> C[Add to Queue]
C --> D[Decode Image using WebAssembly]
D --> E[Compress Image]
E --> F{Compression Successful?}
F -- Yes --> G[Generate Compressed Image Preview]
F -- No --> H[Display Error]
G --> I[Download Compressed Image]
If an image is valid, it is added to the queue. The WebAssembly module decodes and compresses the image using the selected codec. If successful, a preview is generated, and the user can download the compressed image.
stateDiagram-v2
state App {
state useImageManager {
images --> setImages
setImages --> removeImage
setImages --> clearAllImages
}
state useImageQueue {
queue --> addToQueue
addToQueue --> processImage
processImage --> updateStatus
}
useImageManager --> useImageQueue: Pass image data
}
State management is handled through custom hooks:
- useImageManager: Manages image state (add, remove, clear).
- useImageQueue: Manages image compression queue and processing.
Squash uses a CI/CD pipeline powered by GitHub Actions for continuous integration and Vercel for seamless deployment. This combination ensures that every change is automatically tested and deployed to production without manual intervention, promoting an efficient and reliable development workflow.
sequenceDiagram
actor Developer
participant GitHubRepo as "GitHub Repository"
participant GitHubActions as "GitHub Actions"
participant Jest as "Testing Framework (Jest)"
participant Vite as "Vite Build System"
participant Vercel as "Vercel Deployment"
Developer ->> GitHubRepo: Push Code / Create Pull Request
GitHubRepo ->> GitHubActions: Trigger CI Workflow
GitHubActions ->> Jest: Run Unit Tests
Jest -->> GitHubActions: Report Test Results (Success/Failure)
GitHubActions ->> Vite: Build Production Application
Vite -->> GitHubActions: Build Status (Success/Failure)
alt All Steps Passed
GitHubActions ->> Vercel: Deploy Build to Production
Vercel -->> Developer: Deployment Success Notification
else Tests/Build Failed
GitHubActions -->> Developer: CI Failure Notification
end
-
Developer Pushes Code / Creates Pull Request The workflow is automatically triggered on every code push or pull request to the
main
branch. -
GitHub Actions CI Process GitHub Actions orchestrates a multi-step process to validate the changes:
- Dependency Installation: Dependencies are installed using pnpm, ensuring faster and more efficient builds.
- Run Unit Tests: Jest tests all components and modules to validate functionality.
- Build Production Application: Vite compiles the application to ensure it can be successfully built for production.
-
Conditional Check If all steps pass, the application is deployed to Vercel.
-
Automatic Deployment with Vercel Vercel takes the production build and deploys it to its global content delivery network (CDN), providing instant access to the new version.
- Preview Deployments: A unique preview URL is generated for each pull request, enabling easy testing and collaboration.
- Production Deployment: Once changes are merged, the application is deployed to production.
- Notifications
- If all steps pass, the developer receives a deployment success notification.
- If any step fails (tests, build, or deployment), GitHub Actions sends a failure notification with detailed logs for debugging.
The GitHub Actions workflow (.github/workflows/tests.yml
):
name: Run Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 10
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/package.json') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Run tests
run: pnpm test
- Vercel for Continuous Deployment Once the tests pass successfully, Vercel handles the deployment of the application. Vercel provides:
- Automatic Preview Deployments: Every pull request is deployed to a unique preview URL, allowing for easy review and testing.
- Instant Rollbacks: In case of an error in the production build, itβs easy to roll back to a previous deployment.
- Optimized Build and Delivery: Vercel optimizes the production build for speed and scalability, ensuring that Squash is always served efficiently.
-
Fully Automated Workflow Every change is tested, built, and deployed automatically, ensuring quick feedback and reducing the chance of introducing bugs into production.
-
Collaborative Review Preview deployments allow stakeholders and collaborators to test and review features before they are merged into the main branch.
-
Scalability and Performance With Vercelβs edge network, the Squash application is served globally with low latency, providing a fast and seamless user experience.
π¦ Decoders: Image Processing with 
To learn more about the decoders package in Squash, visit the decoders README.
π Hooks: Image Manager and Queue Hooks
To learn more about the hooks package in Squash, visit the hooks README.
- Node.js 18 or later
- pnpm 10.x or later
-
Clone the repository:
git clone https://github.com/nicholasadamou/squash.git cd squash
-
Install dependencies:
pnpm install
-
Start the development server:
pnpm run dev
- Drag and Drop Images: Upload images by dragging and dropping them into the DropZone.
- Select Output Format: Choose between AVIF, JPEG, JPEG XL, PNG, and WebP.
- Adjust Quality: Use the quality slider for optimal compression.
- Download: Download individual images or all at once.
- AVIF: 50%
- JPEG: 75%
- JPEG XL: 75%
- PNG: Lossless
- WebP: 75%