The fast, stateless file optimization engine for Node.js
Condense provides fast, in-memory optimization for media, code, and binaries. It exists to offer low-latency, stateless processing for server-side and serverless environments where temporary disk I/O is undesirable or unavailable. Unlike traditional tools that rely on intermediate temporary files, Condense processes uploads and assets using Buffers and Streams, returning optimized Buffers or Streams ready to send in responses.
Condense requires Node.js v20.9.0 or higher.
Condense doesn't support any other Javascript runtime other than Node.js yet.
Install with your preferred package manager:
npm i @studioframes/condenseyarn add @studioframes/condensepnpm add @studioframes/condensebun add @studioframes/condense- Node.js ≥ 20.9.0
- Memory ~50MB base + file size
- CPU Single-threaded; use clustering for parallelism
- OS Linux/macOS/Windows
External Resources:
Internal Resources:
- Docs
- Changelog
- Code of Conduct
- Commands
- Contributing Guide
- Dependencies
- License
- Migration Guide
- Roadmap
- Security
Table of Contents:
- Introduction
- Install
- Why Condense?
- Features
- Quick Start
- Use Cases
- Usage
- Optimization Methods
- API Reference
- Benchmarks
- Documentation
- Code of Conduct
- Contributing
- License
| Feature | Condense | ImageMin | FFmpeg | Sharp | Terser |
|---|---|---|---|---|---|
| In-memory processing | ✅ | ❌ | ❌ | 🔹 | ✅ |
| No temp files | ✅ | ❌ | ❌ | ❌ | ✅ |
| Images + Media + Code + WASM | ✅ | ❌ | ❌ | ❌ | ❌ |
| Express middleware | ✅ | ❌ | ❌ | ❌ | ❌ |
| Serverless-ready | ✅ | ❌ | ❌ | 🔹 | ✅ |
Bottom line: Condense is 2-5x faster than tools that write temporary files to disk.
More over, Condense is/has:
- API-friendly: Designed to integrate cleanly into HTTP APIs and microservices.
- High-throughput: Efficient pipelines suitable for high-volume media processing.
- Low-latency: Optimized for minimal added latency in request/response flows.
No temporary disk writes. Processes files entirely using Buffers and Streams, returning optimized data ready to send in responses. Supports explicit MP4 faststart when needed.
const { optimizeImage } = require('@studioframes/condense');
// Input Buffer → optimize → output Buffer
const { buffer: optimized, outMime } = await optimizeImage(
inputBuffer,
'image/png',
'balanced'
);
// Ready to send directly in HTTP responseOptimize images (PNG, JPEG, WebP, AVIF, GIF, SVG), audio (MP3, WAV), video (MP4), code/markup (HTML, CSS, JS, TS, JSX, TSX, JSON, XML, YAML, GraphQL), and WebAssembly binaries—all in one engine.
Dynamic image resizing with width, height, and fit parameters (contain, cover, fill). Automatically chooses optimal output format based on content and mode.
const { optimizeImage } = require('@studioframes/condense');
const resized = await optimizeImage(buffer, 'image/png', 'balanced', {
width: 1920,
height: 1080,
fit: 'cover' // or 'contain', 'fill'
});Extract video thumbnails at any timestamp and generate standard MP4 faststart files for streaming. Built on ffmpeg-static for reliable cross-platform support.
const { extractVideoThumbnail } = require('@studioframes/condense');
// Extract thumbnail at 5 seconds
const { buffer: thumb } = await extractVideoThumbnail(videoBuffer, 5);Use as Express middleware for HTTP APIs, standalone CLI tool with beautiful terminal UI, or programmatic SDK. Choose the integration that fits your workflow.
const express = require('express');
const { condenseApp } = require('@studioframes/condense');
const app = express();
app.use('/optimize', condenseApp); // Ready to accept file uploadsUse ignore directives to prevent minification for a file or a specific region.
html: adddata-condense-ignoreto any element (or<html>to ignore the whole document).- Code (
js,css,ts,jsx,tsx,less,scss): add the comment/* condense-ignore */anywhere in the file to bypass minification.
<div data-condense-ignore>
<pre>
Preserved spacing and content here
</pre>
</div>/* condense-ignore */
function legacyCode() {
// This file will not be altered
var x = 10;
}Enable built-in LRU cache to avoid re-processing frequently optimized assets. Controlled via CONDENSE_CACHE=true environment variable with configurable cache size.
# Enable caching for repeated optimizations
export CONDENSE_CACHE=true
export CONDENSE_CACHE_SIZE=100 # number of cached itemsMonitor system health with the /health API endpoint. Reports CPU load, memory usage, optimization queue status, and system capabilities in real-time.
The simplest in-process example — optimize an image Buffer and get back an optimized Buffer:
const { optimizeImage } = require('@studioframes/condense');
async function simpleOptimize(rawBuffer) {
const { buffer: optimized, outMime } = await optimizeImage(rawBuffer, 'image/png', 'quality');
// send `optimized` as the HTTP response body with Content-Type `outMime`
return { optimized, outMime };
}
// Usage: pass a Buffer (e.g., from file upload or fetch response)Optimize user uploads before storage. Compress images, videos, and documents on-the-fly without temporary files. One optimization, many output formats. Perfect for file-sharing platforms, photo galleries, and document management systems.
// Example: Express API endpoint for image uploads
app.post('/api/upload', multer().single('image'), async (req, res) => {
const { buffer: optimized, outMime } = await optimizeImage(
req.file.buffer,
req.file.mimetype,
'balanced'
);
// Save directly to S3 or database
await storage.save(optimized, outMime);
res.json({ size: optimized.length });
});AWS Lambda, Google Cloud Functions, Azure Functions. No disk I/O limits, pure in-memory processing. Handle file optimization within function timeout constraints. Scales automatically with demand—pay only for what you use.
// Example: AWS Lambda handler
exports.optimizeImage = async (event) => {
const buffer = Buffer.from(event.body, 'base64');
const { buffer: optimized } = await optimizeImage(buffer, 'image/jpeg', 'balanced');
return {
statusCode: 200,
body: optimized.toString('base64'),
headers: { 'Content-Type': 'image/webp' }
};
};Optimize assets at build time with the CLI. Batch processing with beautiful TUI. Integrate into your build pipeline (Webpack, Vite, Rollup) for automated asset compression. Reduce bundle sizes by 50-80%.
# Batch optimize entire directories
npx @studioframes/condense optimize ./src/assets -o ./dist --method balanced
# Watch mode for development
npx @studioframes/condense optimize ./src -o ./dist --watchReal-time image/video resizing and compression for multiple screen sizes and devices. Generate thumbnails, create responsive image sets, and optimize video for streaming. Essential for YouTube-like platforms and content CDNs.
// Example: Generate responsive image set
const sizes = [320, 768, 1024, 1920];
const variants = await Promise.all(sizes.map(width =>
optimizeImage(buffer, 'image/jpeg', 'balanced', { width, fit: 'cover' })
));Cloudflare Workers, Vercel Edge Functions, and similar edge computing platforms. Lightweight, stateless optimization at the edge for ultra-low latency. Process and serve optimized content from locations nearest to users.
// Example: Cloudflare Worker
export default {
async fetch(request) {
const image = await request.arrayBuffer();
const { buffer: optimized } = await optimizeImage(image, 'image/png', 'extreme');
return new Response(optimized, { headers: { 'Content-Type': 'image/webp' } });
}
};Condense can run as a standalone CLI tool, a server, be mounted as Express middleware, or be used programmatically.
-
CLI Optimization:
npx @studioframes/condense optimize ./src -o ./dist -m balanced
See COMMANDS.md for full CLI documentation
-
Server:
npx @studioframes/condense
defaults to port 3000; set
PORTto override -
Express: mount
condenseAppon a route to accept uploads -
Programmatic: use helpers such as
optimizeImage,optimizeText,optimizeMediaStream,optimizeEsbuild,optimizeWasm
CONDENSE_MODE=balanced # quality, balanced, or extreme
CONDENSE_CACHE=true # Enable LRU cache
CONDENSE_CACHE_SIZE=100 # Cache entries
CONDENSE_MAX_SIZE=104857600 # Max file size (100MB default)
CONDENSE_TIMEOUT=30000 # Timeout in msCondense has a styled, fully-featured CLI:
-
Optimize a single image with extreme compression:
npx @studioframes/condense optimize photo.png -o out.webp --method extreme
-
Batch optimize a directory using the balanced method:
npx @studioframes/condense optimize ./src/ -o ./dist/ --method balanced
const express = require('express');
const { condenseApp } = require('@studioframes/condense');
const app = express();
// Mount all optimization routes under a specific path
app.use('/v1', condenseApp);
app.listen(8080, () => {
console.log('App running. POST files to http://localhost:8080/v1/optimize');
});const {
optimizeImage,
optimizeText,
optimizeMediaStream,
optimizeEsbuild,
} = require('@studioframes/condense');
// 1. Optimize an Image Buffer (returns Buffer)
const { buffer: imgBuffer, outMime: imgMime } = await optimizeImage(
rawImageBuffer,
'image/png',
'extreme'
);
// 2. Optimize an HTML / CSS / JS Buffer (returns Buffer)
const { buffer: textBuffer, outMime: textMime } = await optimizeText(
rawHtmlBuffer,
'text/html',
'balanced'
);
// 3. Optimize Audio / Video (returns PassThrough Stream)
const { stream, outMime: mediaMime } = optimizeMediaStream(rawVideoBuffer, 'video/mp4', 'quality');
// 4. Optimize TypeScript/React (returns Buffer)
const { buffer: tsBuffer, outMime: tsMime } = await optimizeEsbuild(rawTsBuffer, '.tsx', 'quality');Condense provides three primary optimization targets:
quality(Default): Visually lossless, safe compression, preserves maximum fidelity.balanced: A sweet spot between file size and quality. Introduces mild lossy compression (e.g. 65% quality for JPEGs, crf 26 for video).extreme: Maximum compression. Forces conversions to modern formats (e.g. JPEG/PNG to WebP/AVIF), drops console logs, strips WASM custom sections, downscales video.
POST /optimize
- Multipart form:
file(binary),method(quality|balanced|extreme) - Optional form/query params:
width,height,fit,keepMetadata,keepFormat,targetFormat,faststart,thumbnail. - Returns optimized binary in the response body with appropriate
Content-Type.
curl -X POST http://localhost:3000/optimize \
-F "file=@./photo.png;type=image/png" \
-F "method=balanced" \
--output photo-condensed.pngShort explanation: uploads are received into memory (Buffers or Streams), processed by Condense in-memory, optionally cached in LRU cache, and returned as an optimized Buffer or Stream without intermediate disk writes.
Below are the benchmark results of processing our sample suite through the Condense pipeline using the quality, balanced and extreme methods on demo files (Node.js v24, 2-core CPU). See demo directory to learn more.
| File Name | Original | Quality | Balanced | Extreme | Max Reduction | Time (Q/B/E) |
|---|---|---|---|---|---|---|
demo.png |
115.3 KB | 98.9 KB | 30.2 KB | 26.7 KB | -76.8% | 35/95/122ms |
app.js |
5.0 KB | 1.8 KB | 1.8 KB | 1.4 KB | -72.5% | 27/4/5ms |
component.tsx |
2.6 KB | 1.8 KB | 1.1 KB | 1.0 KB | -61.0% | — |
service.ts |
2.2 KB | 1.5 KB | 1.0 KB | 0.9 KB | -58.0% | — |
view.jsx |
2.3 KB | 1.8 KB | 1.2 KB | 1.1 KB | -52.2% | — |
demo.svg |
217.0 KB | 119.5 KB | 119.3 KB | 119.3 KB | -45.0% | — |
styles.css |
1.0 KB | 0.7 KB | 0.6 KB | 0.6 KB | -36.4% | 22/11/3ms |
index.html |
2.4 KB | 1.6 KB | 1.6 KB | 1.5 KB | -35.9% | 48/7/8ms |
config.yml |
0.9 KB | 0.7 KB | 0.7 KB | 0.6 KB | -30.0% | — |
data.json |
0.5 KB | 0.4 KB | 0.4 KB | 0.4 KB | -25.7% | <1ms |
demo.mp4 |
30.8 KB | 31.6 KB | 29.4 KB | 25.8 KB | -16.4% | — |
| Task | Condense | ImageMin | Sharp | Terser | FFmpeg |
|---|---|---|---|---|---|
| PNG (115 KB) | 94ms | 300ms | 180ms | — | 1000ms |
| JS (5 KB) | 4ms | — | — | 75ms | — |
| HTML (2.4 KB) | 7ms | — | — | 100ms | — |
The documentation set has been expanded and is now organized for both new users and contributors. The complete documentation is available on the Condense Website—which is rendered directly from the markdown files in this repository.
If you prefer to browse the source files directly here on GitHub, you can start with the docs hub in docs/README.md.
We expect all project participants to adhere to our newly established, repository-specific code of conduct. Please read the full text so that you can understand what actions will and will not be tolerated.
We welcome contributions from everyone. Read our contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Condense.
This project is managed by Studio Frames and is licensed under the Apache License 2.0. See LICENSE for the full text.