Skip to content

ICJIA/icjia-squish-2026

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Squish

License: MIT Nuxt Vue TypeScript Nuxt UI Nuxt SEO

Image compression for writers and developers

A modern, privacy-focused image compression tool built with Nuxt 4. Squish helps writers and developers optimize their images with a beautiful, interactive preview comparison slider and real-time quality adjustments.

Squish Open Graph Image

Squish Screenshot

✨ Features

  • πŸ”’ Privacy First: All processing happens locally in your browser β€” your images never leave your device
  • πŸ‘οΈ Live Preview Comparison: Interactive side-by-side slider to compare original vs compressed images
  • πŸ” Zoom & Pan: Magnify up to 800% with mouse wheel zoom and click-and-drag panning for pixel-level inspection
  • ⚑ Real-time Updates: See compression effects instantly as you adjust quality settings
  • πŸ“ Large Preview Window: Optimized for wide screens with up to 2000px layout for detailed inspection
  • 🎨 Modern UI: Dark theme with clean, intuitive interface using Nuxt UI components
  • πŸ“± Responsive Design: Works seamlessly across desktop, tablet, and mobile devices
  • 🎯 Smart Quality Control: Color-coded warnings (green/yellow/red) for quality levels with inline compression stats
  • πŸ“¦ Batch Processing: Compress multiple images at once
  • πŸ’Ύ Easy Download: Download individual images or all at once with file size and savings displayed
  • πŸ–ΌοΈ Sample Image Demo: Load a sample image to try the tool without needing your own files

πŸš€ Quick Start

Prerequisites

  • Node.js 22+ (see .nvmrc for exact version)
  • yarn or npm

Note: This is a Nuxt 4 application. Make sure you're using compatible tooling.

Installation

# Clone the repository
git clone https://github.com/ICJIA/icjia-squish-2026.git
cd icjia-squish-2026

# Install dependencies
yarn install

# Start development server
yarn dev

The app will be available at http://localhost:3000

πŸ“¦ Building for Production

# Generate static site
yarn generate

# Preview production build
yarn preview

# Or build for SSR
yarn build

πŸ› οΈ Tech Stack

  • Nuxt 4 - Latest version of The Intuitive Vue Framework
  • Vue 3 - Progressive JavaScript Framework
  • Nuxt UI - Fully styled and customizable components
  • Nuxt SEO - Complete SEO solution with sitemap, robots, and meta tags
  • TypeScript - Type-safe JavaScript
  • Tailwind CSS v4 - Utility-first CSS framework
  • Canvas API - Client-side image processing
  • Vitest - Unit testing framework with coverage reporting

πŸ“– How It Works

  1. Try It Out: Click "Load Sample Image" to see the tool in action, or drop your own images
  2. Drop or Upload: Drag and drop images or click to browse
  3. Adjust Quality: Use the slider to set compression level (10–100%)
  4. Preview Comparison: Drag the comparison slider to see the difference; scroll to zoom in for detail
  5. Download: Save individual images or download all at once β€” file sizes and savings are shown inline

Compression Process

  • Images are processed using the HTML5 Canvas API
  • Preserves original format (PNG, JPEG, WebP) with adjustable quality
  • Original images remain untouched - new compressed versions are created
  • All processing happens client-side for maximum privacy

🎨 UI Features

Preview Comparison Window

  • Large viewing area: Up to 2000px layout width on wide screens
  • 3:2 aspect ratio: Optimal for most images
  • Min height: 700px for comfortable viewing
  • Interactive slider: Smooth drag-to-compare experience
  • Zoom controls: Zoom in/out (100%–800%) with reset button and mouse wheel support
  • Pan mode: Click and drag to pan when zoomed above 100%
  • Persistent drag: Slider and pan track the mouse even when cursor leaves the image area

Quality Control

  • Visual slider: Clear track with current value display
  • Quality indicators: Color-coded warnings β€” green (50%+), yellow (25–49%), red (below 25%) β€” so you know when quality may suffer
  • Real-time stats: See original size, compressed size, and savings percentage inline
  • Smart defaults: Starts at 75% quality for optimal balance

πŸ§ͺ Testing

The project includes a comprehensive unit test suite with 99 tests covering components and composables.

# Run all tests
yarn test

# Run tests in watch mode
yarn test:watch

# Run with coverage report
yarn test:coverage

# Run component tests only
yarn test:components

# Run composable tests only
yarn test:composables

# Open Vitest UI
yarn test:ui

Test Coverage

File Statements Branches Functions Lines
useImageCompression.ts 100% 100% 100% 100%
QualityIndicator.vue 100% 100% 100% 100%
ComparisonSlider.vue ~79% 85% ~60% ~79%
ImageCompressor.vue ~83% ~91% ~25% ~83%

Tests use Vitest with happy-dom, Vue Test Utils, and vitest-canvas-mock for Canvas API simulation.

πŸ“ Project Structure

icjia-squish-2026/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ assets/css/
β”‚   β”‚   └── main.css              # Global styles and theme
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ ComparisonSlider.vue  # Interactive image comparison with zoom/pan
β”‚   β”‚   β”œβ”€β”€ ImageCompressor.vue   # Main app component
β”‚   β”‚   └── QualityIndicator.vue  # Quality recommendations
β”‚   β”œβ”€β”€ composables/
β”‚   β”‚   β”œβ”€β”€ useImageCompression.ts # Compression logic
β”‚   β”‚   └── useDebounce.ts         # Debounced function utility
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   └── index.vue             # Home page
β”‚   β”œβ”€β”€ app.config.ts             # App configuration
β”‚   └── app.vue                   # Root component
β”œβ”€β”€ test/
β”‚   β”œβ”€β”€ unit/
β”‚   β”‚   β”œβ”€β”€ components/           # Component tests (69 tests)
β”‚   β”‚   └── composables/          # Composable tests (30 tests)
β”‚   β”œβ”€β”€ fixtures/                 # Mock files and test data
β”‚   β”œβ”€β”€ helpers/                  # Test utilities and canvas mocks
β”‚   └── setup.ts                  # Global test setup
β”œβ”€β”€ documentation/                # Original Next.js reference code
β”œβ”€β”€ nuxt.config.ts               # Nuxt configuration
β”œβ”€β”€ vitest.config.ts             # Test configuration
β”œβ”€β”€ package.json                 # Dependencies
└── netlify.toml                 # Netlify deployment config

🎯 Key Components

ImageCompressor.vue

Main component handling image upload, compression, and state management.

ComparisonSlider.vue

Interactive slider for comparing original and compressed images side-by-side with zoom (100%–800%) and pan controls.

useImageCompression.ts

Composable providing image compression functionality using Canvas API.

🌐 Deployment

This project is configured for deployment on Netlify with Nuxt 4:

# Build command
yarn generate

# Publish directory
dist

The netlify.toml file is pre-configured with:

  • Nitro preset: netlify-static for optimal static site generation
  • Output directory: dist (Nuxt 4 custom configuration)
  • Security headers: CSP (with object-src 'none', base-uri 'self', form-action 'self'), HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy
  • Cache headers: 1-year cache for /_nuxt/* assets with immutable flag

Environment Variables

Set NODE_VERSION=22 and NITRO_PRESET=netlify-static in your Netlify build settings (already configured in netlify.toml).

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built with Nuxt and Nuxt UI
  • Inspired by the need for privacy-focused image tools
  • Original Next.js implementation available in documentation/ folder

πŸ›‘οΈ Security & Accessibility Audits

Last audited: 2026-03-27. Full details in CHANGELOG.md.

Security (Red/Blue Team)

Severity Found Fixed Remaining
Critical 0 β€” 0
High 0 β€” 0
Medium 2 2 0
Low 8 8 0

All findings resolved. No server-side attack surface (static site). No user data storage or transmission. No runtime CDN dependencies (icons bundled at build time). Web Worker loaded from same-origin static file. All security headers properly configured (CSP, HSTS, X-Frame-Options, Permissions-Policy, Referrer-Policy). Input validation on file types and size. No v-html usage.

Accessibility (axe-core 4.10.2)

Metric Result
Rules passed 39/39
Violations 0
Incomplete 0
Standards WCAG 2.0 A/AA, WCAG 2.1 A/AA, Best Practices

πŸ“‹ Changelog

See CHANGELOG.md for a detailed history of changes and version releases.

πŸ“§ Contact

ICJIA - Illinois Criminal Justice Information Authority


Made with ❀️ for writers and developers who care about image quality and file size

About

A modern, privacy-focused image compression tool built with Nuxt 4. Squish helps writers and designers optimize their images with a beautiful, interactive preview comparison slider and real-time quality adjustments

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors