@studioframes/condense
v0.3.16
Published
Condense is a high-performance, stateless file optimization and minification engine for Node.js.
Maintainers
Readme
The fast, stateless file optimization engine for Node.js
Introduction
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.
Install
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
npm i @studioframes/condenseyarn
yarn add @studioframes/condensepnpm
pnpm add @studioframes/condensebun
bun add @studioframes/condenseSystem Requirements
- Node.js ≥ 20.9.0
- Memory ~50MB base + file size
- CPU Single-threaded; use clustering for parallelism
- OS Linux/macOS/Windows
Quick Links
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
Why Condense?
| 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.
Features
In-Memory Processing
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 responseComprehensive Format Support
Optimize 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.
Intelligent Resizing
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'
});Media Utilities
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);Multiple Integration Points
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 uploadsSmart Ignore Directives
Use 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.
Examples
html
<div data-condense-ignore>
<pre>
Preserved spacing and content here
</pre>
</div>js/ts
/* condense-ignore */
function legacyCode() {
// This file will not be altered
var x = 10;
}Optional LRU Caching
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 itemsHealth & Diagnostics
Monitor system health with the /health API endpoint. Reports CPU load, memory usage, optimization queue status, and system capabilities in real-time.
Quick Start
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)Use Cases
Web APIs
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 });
});Serverless Functions
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' }
};
};Build Tools
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 --watchMedia Platforms
Real-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' })
));Edge Runtimes
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' } });
}
};Usage
Condense can run as a standalone CLI tool, a server, be mounted as Express middleware, or be used programmatically.
Quick Start Reference
CLI Optimization:
npx @studioframes/condense optimize ./src -o ./dist -m balancedSee COMMANDS.md for full CLI documentation
Server:
npx @studioframes/condensedefaults to port 3000; set
PORTto overrideExpress: mount
condenseAppon a route to accept uploadsProgrammatic: use helpers such as
optimizeImage,optimizeText,optimizeMediaStream,optimizeEsbuild,optimizeWasm
Environment Variables
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 msExamples
CLI Usage
Condense has a styled, fully-featured CLI:
Optimize a single image with extreme compression:
npx @studioframes/condense optimize photo.png -o out.webp --method extremeBatch optimize a directory using the balanced method:
npx @studioframes/condense optimize ./src/ -o ./dist/ --method balanced
Express Middleware
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');
});Programmatic Helper SDK
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');Optimization Methods
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.
API Reference (selected)
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.
Example Request:
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.
Benchmarks
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% | — |
Performance vs Competitors
| Task | Condense | ImageMin | Sharp | Terser | FFmpeg | |------|----------|----------|-------|--------|--------| | PNG (115 KB) | 94ms | 300ms | 180ms | — | 1000ms | | JS (5 KB) | 4ms | — | — | 75ms | — | | HTML (2.4 KB) | 7ms | — | — | 100ms | — |
Documentation
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.
Code of Conduct
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.
Contributing to Condense
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.
License
This project is managed by Studio Frames and is licensed under the Apache License 2.0. See LICENSE for the full text.
