A modern, full-stack web application for converting images to WebP format with efficient compression and batch processing capabilities.
- Overview
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Installation
- Running the Application
- API Endpoints
- Supported Image Formats
- Usage
- Development
- Project Architecture
- Configuration
- Troubleshooting
WebPify is a fast and efficient image conversion tool that transforms various image formats into WebP format. It features a beautiful, modern UI and a robust FastAPI backend that processes images with minimal overhead. Perfect for developers and designers who need to optimize images for web applications.
- π Fast Conversion: Efficient server-side processing with minimal memory usage
- π¦ Batch Processing: Convert multiple images at once with automatic ZIP download
- π¨ Quality Control: Adjustable compression quality (1-100)
- πΌοΈ Multiple Formats: Support for PNG, JPEG, BMP, TIFF, GIF, and WebP
- πΎ In-Memory Processing: No temporary files, everything processed in memory
- π― Modern UI: Beautiful, responsive design built with React and Tailwind CSS
- β‘ High Performance: Built with FastAPI for maximum throughput
- π Transparency Support: Preserves alpha channels for PNG images
- π± Responsive Design: Works seamlessly on desktop and mobile devices
- React 18.2.0 - Modern UI framework
- Vite 5.4.21 - Fast build tool and development server
- Tailwind CSS 3.1.6 - Utility-first CSS framework
- JSZip 3.10.1 - ZIP file creation for batch downloads
- FastAPI 0.109.0 - Modern, fast Python web framework
- Uvicorn - ASGI server for FastAPI
- Pillow 10.2.0 - Image processing library
- Python-Multipart - Form data handling
WebPify/
βββ client/ # React frontend application
β βββ public/ # Static assets
β β βββ fav.png # Favicon
β β βββ manifest.json # Web app manifest
β βββ src/ # Source code
β β βββ components/ # React components
β β β βββ FileUpload.jsx # File upload component
β β β βββ ConversionProgress.jsx # Progress indicator
β β β βββ ConversionResults.jsx # Results display
β β β βββ Features.jsx # Features showcase
β β β βββ Header.jsx # App header
β β β βββ Footer.jsx # App footer
β β βββ App.jsx # Main App component
β β βββ index.jsx # Entry point
β β βββ index.css # Global styles
β βββ index.html # Vite HTML template
β βββ vite.config.js # Vite configuration
β βββ package.json # Frontend dependencies
β βββ tailwind.config.js # Tailwind configuration
β βββ postcss.config.js # PostCSS configuration
β
βββ server/ # Python FastAPI backend
β βββ utils/ # Utility modules
β β βββ __init__.py
β β βββ image_converter.py # Image conversion logic
β βββ main.py # FastAPI application
β βββ start.py # Server startup script
β βββ requirements.txt # Python dependencies
β
βββ README.md # This file
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher) and npm
- Python (3.8 or higher)
- pip (Python package manager)
- Navigate to the server directory:
cd server- Create a virtual environment (recommended):
python -m venv venv- Activate the virtual environment:
- On Windows:
venv\Scripts\activate- On macOS/Linux:
source venv/bin/activate- Install Python dependencies:
pip install -r requirements.txt- Navigate to the client directory:
cd client- Install Node.js dependencies:
npm installFrom the server directory:
python start.pyThe server will start on http://localhost:8000
From the client directory:
npm run dev
# or
npm startThe client will start on http://localhost:3000 (or the next available port)
Open your browser and navigate to:
http://localhost:3000
The API includes comprehensive Swagger/OpenAPI documentation that you can access once the server is running:
Swagger UI (Interactive):
http://localhost:8000/docs
This provides an interactive interface where you can test all API endpoints directly from your browser.
ReDoc (Documentation):
http://localhost:8000/redoc
This provides an alternative documentation view with a clean, readable format.
OpenAPI JSON Schema:
http://localhost:8000/openapi.json
This provides the complete OpenAPI specification in JSON format.
GET /Returns API information and available endpoints.
Response:
{
"service": "WebPify API",
"version": "1.0.0",
"description": "Convert images to WebP format",
"endpoints": {
"/api/convert": "POST - Convert images to WebP",
"/api/health": "GET - Health check",
"/docs": "GET - Interactive API documentation (Swagger UI)",
"/redoc": "GET - Alternative API documentation"
}
}GET /api/healthReturns server health status for monitoring purposes.
Response:
{
"status": "healthy",
"service": "WebPify API",
"version": "1.0.0"
}POST /api/convertConverts one or more images to WebP format.
Request Parameters:
files(List[UploadFile], required): Image files to convertquality(int, optional): WebP quality (1-100, default: 85)
Request Format:
- Content-Type:
multipart/form-data - Body: Form data with file(s) and optional quality parameter
Response:
- Single file: Returns
image/webpwith the converted image - Multiple files: Returns
application/zipwith all converted images
Example using cURL:
Single file conversion:
curl -X POST "http://localhost:8000/api/convert?quality=90" \
-F "files=@image.png" \
--output converted.webpMultiple files conversion:
curl -X POST "http://localhost:8000/api/convert?quality=85" \
-F "files=@image1.png" \
-F "files=@image2.jpg" \
--output converted.zipExample using Python:
import requests
# Single file
with open('image.png', 'rb') as f:
response = requests.post(
'http://localhost:8000/api/convert',
files={'files': f},
params={'quality': 85}
)
with open('converted.webp', 'wb') as out:
out.write(response.content)
# Multiple files
with open('image1.png', 'rb') as f1, open('image2.jpg', 'rb') as f2:
response = requests.post(
'http://localhost:8000/api/convert',
files=[('files', f1), ('files', f2)],
params={'quality': 90}
)
with open('converted.zip', 'wb') as out:
out.write(response.content)Example using JavaScript/Fetch:
const formData = new FormData();
formData.append('files', fileInput.files[0]);
const response = await fetch('http://localhost:8000/api/convert?quality=85', {
method: 'POST',
body: formData
});
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'converted.webp';
a.click();Example using axios:
const formData = new FormData();
formData.append('files', fileInput.files[0]);
const response = await axios.post(
'http://localhost:8000/api/convert',
formData,
{
params: { quality: 85 },
responseType: 'blob'
}
);
const url = window.URL.createObjectURL(response.data);
const a = document.createElement('a');
a.href = url;
a.download = 'converted.webp';
a.click();The quality parameter controls the compression level of the WebP output:
-
1-70: High compression, smaller file size
- Best for: Thumbnails, preview images, mobile optimization
- Typical size reduction: 75-90% compared to original
-
71-85: Balanced quality and size (recommended)
- Best for: General web usage, blog images, portfolio galleries
- Typical size reduction: 60-75% compared to original
-
86-100: High quality, larger file size
- Best for: High-resolution images, professional photography
- Typical size reduction: 30-50% compared to original
Note: For images with transparency (PNG with alpha channel), quality >= 90 will use lossless compression to preserve transparency perfectly.
For developers integrating with the WebPify API:
-
Interactive Swagger UI:
http://localhost:8000/docs- Test endpoints directly in your browser
- View request/response schemas
- Try the API with real files
-
OpenAPI Specification:
http://localhost:8000/openapi.json- Download the complete OpenAPI 3.0 specification
- Import into API clients (Postman, Insomnia, etc.)
- Generate client libraries
-
ReDoc Documentation:
http://localhost:8000/redoc- Readable, single-page documentation
- Perfect for understanding the API at a glance
The application supports the following input formats:
- PNG (.png)
- JPEG (.jpg, .jpeg)
- BMP (.bmp)
- TIFF (.tiff, .tif)
- GIF (.gif)
- WebP (.webp)
- Select Images: Click "Choose Files" and select one or more images
- Review Selection: View your selected files with their names and sizes
- Convert: Click "Convert to WebP" to start the conversion process
- Download:**:
- For a single file: Download the WebP file directly
- For multiple files: Download the ZIP archive containing all converted images
The application runs in development mode with fast hot-reload enabled:
- Backend: Auto-reloads on code changes with Uvicorn
- Frontend: Instant HMR (Hot Module Replacement) with Vite for rapid development
- Backend: Follows FastAPI best practices with separate utility modules
- Frontend: Component-based architecture with Tailwind CSS styling
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β Frontend β β Backend β β Dependencies β
β (React 18) β β (FastAPI) β β & Runtime β
ββββββββββββββββββββ€ ββββββββββββββββββββ€ ββββββββββββββββββββ€
β β’ File Upload βββββΊβ β’ FastAPI β β β’ Python 3.8+ β
β β’ Progress Bar β β β’ Uvicorn Server β β β’ Pillow β
β β’ Results Displayβ β β’ Image Converterβ β β’ Node.js β
β β’ JSZip β β β’ File Validationβ β β’ NPM β
β β’ Tailwind CSS β β β’ CORS Middlewareβ β β’ Tailwind CSS β
β β’ Vite β β β’ ZIP Generator β β β’ Vite β
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
sequenceDiagram
participant User
participant React as React Frontend
participant API as FastAPI Backend
participant Validator as File Validator
participant Converter as Image Converter
participant Pillow as Pillow Library
participant Response as Response Handler
User->>React: 1. Select Images
React->>React: 2. Display Preview
User->>React: 3. Click Convert
React->>API: 4. POST /api/convert (files + quality)
API->>Validator: 5. Validate Files
Validator-->>API: 6. Files Valid
API->>Converter: 7. Process Images
Converter->>Pillow: 8. Convert to WebP
Pillow-->>Converter: 9. WebP Bytes
alt Single File
Converter->>Response: 10a. Prepare Single File
Response-->>API: 11a. image/webp
API-->>React: 12a. Download WebP
else Multiple Files
Converter->>Response: 10b. Create ZIP Archive
Response-->>API: 11b. application/zip
API-->>React: 12b. Download ZIP
end
React-->>User: 13. Display Download Link
User->>React: 14. Download File
- User uploads images via multipart form data
- FastAPI receives and validates the files
- Images are converted to WebP using Pillow in memory
- Results are streamed back to the client
- ZIP archive created for multiple files
- User selects files using the file input
- Files are displayed with preview
- On conversion, files are sent to the API
- Progress indicator shows during processing
- Results are displayed with download options
The server can be configured in server/start.py:
- Host: Default
0.0.0.0(all interfaces) - Port: Default
8000 - Reload: Auto-reload enabled in development
API endpoint is configured in client/src/App.jsx:
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000/api/convert';You can create a .env file in the client directory to set custom environment variables:
VITE_API_URL=http://localhost:8000/api/convertDefault WebP quality is set to 85 (good balance between quality and size). You can adjust this in the frontend conversion request.
Port already in use:
# Windows
netstat -ano | findstr :8000
# Kill the process using the PID
# macOS/Linux
lsof -ti:8000 | xargs killPython module not found:
pip install -r requirements.txtPort 3000 already in use:
# Vite will automatically try the next available port (3001, 3002, etc.)
# Or modify the port in vite.config.jsModule not found:
npm installBuild errors:
On Windows (PowerShell):
Remove-Item -Recurse -Force node_modules, package-lock.json
npm installOn macOS/Linux:
rm -rf node_modules package-lock.json
npm installIf you encounter CORS errors, ensure the backend allows requests from http://localhost:3000. The CORS middleware is configured in server/main.py.
- Ensure the image file is not corrupted
- Check that the file format is supported
- Verify the image file size is reasonable (large files may cause memory issues)
This project is licensed under the MIT License - see the LICENSE file for details.
Thank you to all contributors who help improve WebPify! π
Want to contribute? Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
Built with β€οΈ using FastAPI and React