Overview
Reduce response size for faster client loading.
Features
- Bun native gzip
- Configurable threshold
- Content-type filtering
- Automatic detection
Installation
npx hanma add elysia-compression --framework elysia
Code
import { Elysia } from "elysia";
export interface CompressionOptions {
/** Minimum size in bytes before compression is applied (default: 1024) */
threshold?: number;
/** Compression level 1-9 (default: 6) */
level?: number;
/** Content types to compress (default: text/*, application/json, application/javascript) */
contentTypes?: string[];
}
const shouldCompress = (
contentType: string | null,
allowedTypes: string[]
): boolean => {
if (!contentType) return false;
return allowedTypes.some((type) => {
if (type.endsWith("/*")) {
return contentType.startsWith(type.slice(0, -1));
}
return contentType.includes(type);
});
};
/**
* Compression middleware for Elysia
* Uses Bun's native gzip compression
*/
export const compression = (options: CompressionOptions = {}) => {
const config = {
threshold: options.threshold ?? 1024,
level: Math.min(9, Math.max(1, options.level ?? 6)),
contentTypes: options.contentTypes ?? [
"text/*",
"application/json",
"application/javascript",
"application/xml",
"image/svg+xml",
],
};
return new Elysia({ name: "compression" })
.mapResponse(({ response, set, request }) => {
// Check if client accepts gzip
const acceptEncoding = request.headers.get("accept-encoding") ?? "";
if (!acceptEncoding.includes("gzip")) {
return response;
}
// Skip if already compressed
if (set.headers["Content-Encoding"]) {
return response;
}
// Get response body
let body: string | null = null;
let contentType = set.headers["Content-Type"] ?? set.headers["content-type"];
if (typeof response === "string") {
body = response;
contentType = contentType ?? "text/plain";
} else if (typeof response === "object" && response !== null) {
body = JSON.stringify(response);
contentType = contentType ?? "application/json";
}
if (!body) return response;
// Check content type
if (!shouldCompress(contentType, config.contentTypes)) {
return response;
}
// Check threshold
const bodySize = new TextEncoder().encode(body).length;
if (bodySize < config.threshold) {
return response;
}
// Compress using Bun
const compressed = Bun.gzipSync(body, { level: config.level });
set.headers["Content-Encoding"] = "gzip";
set.headers["Vary"] = "Accept-Encoding";
return new Response(compressed, {
headers: {
"Content-Type": contentType,
"Content-Encoding": "gzip",
"Vary": "Accept-Encoding",
},
});
});
};
/* USAGE:
import { Elysia } from "elysia";
import { compression } from "./middleware/compression";
const app = new Elysia()
.use(compression())
.get("/", () => "Hello World")
.get("/large", () => {
// Large JSON response will be compressed
return { data: Array(1000).fill({ id: 1, name: "test" }) };
})
.listen(3000);
// With custom options
const app = new Elysia()
.use(compression({
threshold: 512, // Compress responses larger than 512 bytes
level: 9, // Maximum compression
contentTypes: ["text/*", "application/json"],
}))
.listen(3000);
*/
Usage
import { compression } from './middleware/compression';
app.use(compression({ threshold: 1024 }));
Dependencies
No external dependencies required.
Frequently Asked Questions
How do I install Compression?
Run the following command:
npx hanma add elysia-compression --framework elysiaHow do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to
src/middleware/compression.ts.Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.