Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 120 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,55 @@
[![npm](https://img.shields.io/npm/v/@studioframes/condense?colorA=006AFF&colorB=000000)](https://www.npmjs.com/package/@studioframes/condense)
[![downloads](https://img.shields.io/npm/dt/@studioframes/condense?labelColor=006AFF&color=000000)](https://www.npmjs.com/package/@studioframes/condense)

**A high-performance, completely stateless file optimization and minification engine for Node.js. Condense handles images, video, audio, and code natively in-memory (RAM) using Buffers and Streams, completely bypassing the local server disk.**

<p align="center">
<a href="#features">Features</a> •
<a href="#installation">Installation</a> •
<a href="#usage">Usage</a>
</p>
**Condense is a high-performance, stateless file optimization and minification engine for [Node.js](https://nodejs.org). It optimizes images, audio, video, and code entirely in-memory using Buffers and Streams, and avoids writing temporary files to disk.**

</div>

## Features
- **Zero Disk I/O:** Fully streaming and buffer-based architecture to minimize memory overhead.
- **Granular Bypass Rules:** Add `data-condense-ignore` to any HTML tag (or `/* condense-ignore */` in JS/CSS) to prevent minification on a per-element or per-file basis.
- **Multi-Format Pipeline:**
- Code & Markup: JS, CSS, JSON, HTML
- Media: MP4, MP3, WAV
- Images: JPG, PNG, WebP
## Introduction

Condense provides fast, in-memory optimization for media and code. 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.

### Table of Contents
- <a href="#why-condense">Why Condense?</a>
- <a href="#features">Features</a>
- <a href="#supported-formats">Supported Formats</a>
- <a href="#installation">Installation</a>
- <a href="#quick-start">Quick Start</a>
- <a href="#usage">Usage</a>
- <a href="#ignore-directives">Ignore Directives</a>
- <a href="#api-reference-selected">API Reference</a>
- <a href="#architecture-diagram">Architecture Diagram</a>
- <a href="#benchmarks">Benchmarks</a>
- <a href="#system-requirements">System Requirements</a>
- <a href="#license">License</a>

## Why Condense?

- **No temporary files:** Processes files entirely in-memory using Buffers and Streams without writing temporary files to disk.
- **Stateless architecture:** Optimizations are performed per-request without persistent state, easing horizontal scaling.
- **API-friendly:** Designed to integrate cleanly into HTTP APIs and microservices.
- **Serverless-ready:** Works well in ephemeral environments (Cloud Functions, Lambda-like runtimes) where disk access is limited.
- **High-throughput:** Efficient pipelines suitable for high-volume media processing.
- **Low-latency:** Optimized for minimal added latency in request/response flows.

## System Requirements
## Features
- In-memory Buffer & Stream processing (no temporary disk writes)
- Image, audio, video, and code/markup optimization
- Express middleware and standalone CLI options
- Ignore directives to opt-out specific regions or files from minification

Condense utilizes modern native binary distributions (`sharp`, `ffmpeg-static`) which compile against updated Node-API architectures.
## Supported Formats

* **Minimum Node.js Version:** `20.9.0` (or higher)
* **Recommended Environments:** Node **20 LTS** or Node **22 LTS**
* **Forward Compatibility:** Fully supports newer major engine releases (e.g., Node 23, Node 24+).
| Category | Formats |
| --- | --- |
| Images | PNG, JPG, JPEG, WebP |
| Audio | MP3, WAV |
| Video | MP4 |
| Code & Markup | HTML, CSS, JavaScript, JSON |

## Installation

Using a package manager:
Install with your preferred package manager:

#### npm

Expand All @@ -59,21 +79,33 @@ pnpm add @studioframes/condense
bun add @studioframes/condense
```

## Usage
## Quick Start

### Option A: Standalone CLI Server
Run a dedicated Condense microservice directly from your terminal:
The simplest in-process example — optimize an image Buffer and get back an optimized Buffer:

```bash
npx @studioframes/condense
```
*Defaults to port `3000`. You can configure the port using the `PORT` environment variable:*
```bash
PORT=8080 npx @studioframes/condense
```javascript
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)
```

### Option B: Express Middleware / Sub-App
Mount Condense directly onto an existing Express application router:
## Usage

Condense can run as a standalone CLI server, be mounted as Express middleware, or be used programmatically.

- CLI: `npx @studioframes/condense` (defaults to port 3000; set `PORT` to override)
- Express: mount `condenseApp` on a route to accept uploads
- Programmatic: use helpers such as `optimizeImage`, `optimizeText`, `optimizeMediaStream`

### Examples

### A. Express Middleware

```javascript
const express = require('express');
Expand All @@ -89,8 +121,7 @@ app.listen(8080, () => {
});
```

### Option C: Programmatic Helper SDK
Import the low-level processing functions to optimize Buffers directly inside your codebase without HTTP routing:
### B. Programmatic Helper SDK

```javascript
const { optimizeImage, optimizeText, optimizeMediaStream } = require('@studioframes/condense');
Expand All @@ -105,28 +136,24 @@ const { buffer: textBuffer, outMime: textMime } = await optimizeText(rawHtmlBuff
const { stream, outMime: mediaMime } = optimizeMediaStream(rawVideoBuffer, 'video/mp4', 'quality');
```

## Ignore Directives

Use ignore directives to prevent minification for a file or a specific region.

## Granular Ignorance (Opt-Outs)
- HTML: add `data-condense-ignore` to any element (or `<html>` to ignore the whole document).
- JS/CSS: add the comment `/* condense-ignore */` anywhere in the file to bypass minification.

Condense supports local directives so that specific code segments are not modified during minification.

### In HTML Documents
Add the `data-condense-ignore` attribute to any tag (or the root `<html>` tag to ignore the whole file). Condense protects that tag and all its nested children:
Example (HTML):

```html
<!-- This div, the image, and the text will be returned exactly as-is -->
<div data-condense-ignore class="uncompressed-layout">
<p> Some formatted text here. </p>
<img src="large-photo.jpg">
<div data-condense-ignore>
<pre>
Preserved spacing and content here
</pre>
</div>

<!-- This will be compressed normally -->
<p>This paragraph gets minified.</p>
```

### In CSS & JavaScript
Add the `/* condense-ignore */` comment anywhere inside your JS or CSS file to bypass minification entirely:
Example (JS):

```javascript
/* condense-ignore */
Expand All @@ -136,23 +163,61 @@ function legacyCode() {
}
```

## API Endpoint Reference (For Options A & B)
Example (CSS):

### `POST /optimize`
Optimizes an uploaded file in-memory.
```css
/* condense-ignore */
p {
color: red;
text-align: center;
}
```

**Payload (Multipart Form-Data):**
- `file`: The binary file (Max 50MB)
- `method`: `quality` (visually lossless, default) or `extreme` (aggressive size reduction)
## API Reference (selected)

**Example Request:**
POST `/optimize`
- Multipart form: `file` (binary), `method` (`quality` | `extreme`)
- Returns optimized binary in the response body with appropriate `Content-Type`.

### Example Request:
```bash
curl -X POST http://localhost:3000/v1/optimize \
-F "file=@./photo.png" \
-F "method=extreme" \
--output photo-condensed.webp
```

## Architecture Diagram

```
Client Upload
Buffer
Condense
Buffer/Stream
Response
```

Short explanation: uploads are received into memory (Buffers or Streams), processed by Condense in-memory, and returned as an optimized Buffer or Stream without intermediate disk writes.

## Benchmarks*

| File Type | Original Size | Optimized Size |
| --- | ---: | ---: |
| PNG | 4.2 MB | 1.1 MB |
| MP4 | 25 MB | 9 MB |
| HTML | 120 KB | 42 KB |

*These numbers are illustrative. Actual savings vary depending on content, encoding, and chosen optimization method.

## System Requirements

- Minimum Node.js: >= 20.9
- Uses native binaries (`sharp`, `ffmpeg-static`) where applicable

## License

This Project is managed by **Studio Frames** and is licensed under the terms of the **Apache License 2.0**. See [LICENSE](https://github.com/studioframes/Condense/edit/main/LICENSE) to learn more.
This project is managed by Studio Frames and is licensed under the Apache License 2.0. See [https://github.com/studioframes/Condense/blob/main/LICENSE](https://github.com/studioframes/Condense/blob/main/LICENSE) for the full text.
Loading