Production Optimization: Compress Your Code with OXC Minifier
Learn to use OXC Minifier to compress JavaScript code, reduce file size, improve page load speed, 5x faster than Terser.
Production Optimization: Compress Your Code with OXC Minifier
In web development, every KB matters. Smaller JavaScript files mean faster load times, less bandwidth consumption, and better user experience.
Today, we’ll learn about OXC Minifier — a code minification tool more than 5x faster than Terser.
Why Do We Need Code Minification?
Let the Numbers Speak
Suppose your project’s bundled JS file:
| Status | File Size | 4G Load Time | 3G Load Time |
|---|---|---|---|
| Unminified | 500 KB | 1.2 seconds | 4 seconds |
| Minified | 180 KB | 0.4 seconds | 1.5 seconds |
Minification reduces size by 64%! This is especially important for mobile users.
What Does Code Minification Do?
Look at a simple example:
// Original code (about 200 bytes)
function calculateTotal(items) {
let total = 0;
for (const item of items) {
if (item.price > 0) {
total = total + item.price * item.quantity;
}
}
return total;
}
export { calculateTotal };
After minification:
// Minified (about 80 bytes)
function calculateTotal(e){let t=0;for(const o of e)o.price>0&&(t+=o.price*o.quantity);return t}export{calculateTotal};
Specific Minification Operations
| Operation | Description |
|---|---|
| Remove Whitespace | Remove spaces, newlines, indentation |
| Remove Comments | Remove all comment content |
| Compress Variable Names | Change long variable names to short ones |
| Merge Constants | Combine unchanged values |
| Simplify Expressions | Optimize logical expressions |
| Remove Dead Code | Remove unreachable code |
What Can Minifier Do?
OXC Minifier provides these capabilities:
- Code Minification: Reduce file size
- Code Obfuscation: Make code harder to read (increases reverse engineering difficulty)
- Dead Code Elimination: Remove unused code
- Source Map Generation: Preserve debugging capability
Quick Start
Installation
npm install @oxc-minifier
Basic Usage
import { minifySync } from "@oxc-minifier";
const code = `
function greeting(name) {
const message = "Hello, " + name + "!";
console.log(message);
return message;
}
export { greeting };
`;
const result = minifySync(code);
console.log(result.code);
Output:
function greeting(e){const o="Hello, "+e+"!";return console.log(o),o}export{greeting};
Asynchronous Minification
import { minify } from "@oxc-minifier";
const result = await minify(code, {
compress: true,
mangle: true,
});
console.log(result.code);
Practical: Minifying a Project
Let’s walk through the code minification process step by step.
Step 1: Create Test Project
mkdir minify-demo
cd minify-demo
npm init -y
npm install @oxc-minifier
mkdir src dist
Create src/bundle.js:
// src/bundle.js
/**
* User management module
* @module userManager
*/
// Configuration
const API_BASE_URL = "https://api.example.com/v1";
const DEFAULT_TIMEOUT = 5000;
const MAX_RETRIES = 3;
/**
* User class
*/
class User {
constructor(id, name, email) {
this.id = id;
this.name = name;
this.email = email;
this.createdAt = new Date();
}
getDisplayName() {
return `${this.name} <${this.email}>`;
}
toJSON() {
return {
id: this.id,
name: this.name,
email: this.email,
createdAt: this.createdAt.toISOString(),
};
}
}
/**
* User service
*/
class UserService {
constructor(baseUrl = API_BASE_URL) {
this.baseUrl = baseUrl;
this.cache = new Map();
}
async fetchUser(userId) {
// Check cache
if (this.cache.has(userId)) {
return this.cache.get(userId);
}
// Make request
const response = await fetch(`${this.baseUrl}/users/${userId}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error(`Failed to fetch user: ${response.status}`);
}
const data = await response.json();
const user = new User(data.id, data.name, data.email);
// Cache result
this.cache.set(userId, user);
return user;
}
async updateUser(userId, updates) {
const response = await fetch(`${this.baseUrl}/users/${userId}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(updates),
});
if (!response.ok) {
throw new Error(`Failed to update user: ${response.status}`);
}
// Clear cache
this.cache.delete(userId);
return this.fetchUser(userId);
}
}
// Create default instance
const userService = new UserService();
// Export
export { User, UserService, userService, API_BASE_URL };
Step 2: Create Minification Script
Create minify.js:
// minify.js
import { minifySync } from "@oxc-minifier";
import fs from "fs";
function minifyFile(inputPath, outputPath) {
console.log(`📦 Minifying: ${inputPath}`);
// Read source file
const code = fs.readFileSync(inputPath, "utf-8");
const originalSize = Buffer.byteLength(code, "utf-8");
// Minify
const result = minifySync(code, {
compress: true, // Enable compression
mangle: true, // Enable variable name obfuscation
sourcemap: true, // Generate Source Map
});
// Write minified code
fs.writeFileSync(outputPath, result.code);
// Write Source Map
if (result.map) {
fs.writeFileSync(`${outputPath}.map`, result.map);
}
const minifiedSize = Buffer.byteLength(result.code, "utf-8");
const reduction = ((1 - minifiedSize / originalSize) * 100).toFixed(1);
console.log(`✅ Output: ${outputPath}`);
console.log(`📊 Size: ${originalSize} → ${minifiedSize} bytes (${reduction}% reduction)`);
console.log();
}
// Execute minification
minifyFile("./src/bundle.js", "./dist/bundle.min.js");
Step 3: Run Minification
node minify.js
Output:
📦 Minifying: ./src/bundle.js
✅ Output: ./dist/bundle.min.js
📊 Size: 2048 → 687 bytes (66.5% reduction)
Step 4: View Minified Result
dist/bundle.min.js content:
const t="https://api.example.com/v1",e=5e3;class s{constructor(t,e,s){this.id=t,this.name=e,this.email=s,this.createdAt=new Date}getDisplayName(){return`${this.name} <${this.email}>`}toJSON(){return{id:this.id,name:this.name,email:this.email,createdAt:this.createdAt.toISOString()}}}class i{constructor(e=t){this.baseUrl=e,this.cache=new Map}async fetchUser(t){if(this.cache.has(t))return this.cache.get(t);const e=await fetch(`${this.baseUrl}/users/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw new Error(`Failed to fetch user: ${e.status}`);const i=await e.json(),r=new s(i.id,i.name,i.email);return this.cache.set(t,r),r}async updateUser(t,e){const s=await fetch(`${this.baseUrl}/users/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok)throw new Error(`Failed to update user: ${s.status}`);return this.cache.delete(t),this.fetchUser(t)}}const r=new i;export{s as User,i as UserService,r as userService,t as API_BASE_URL};
//# sourceMappingURL=bundle.min.js.map
Configuration Options Explained
compress - Compression Options
minifySync(code, {
compress: {
// Boolean options
booleans: true, // Optimize boolean values
conditionals: true, // Optimize conditional expressions
dead_code: true, // Remove dead code
drop_console: false, // Remove console.*
drop_debugger: true, // Remove debugger statements
evaluate: true, // Evaluate constant expressions
loops: true, // Optimize loops
unused: true, // Remove unused code
// Numeric options
sequences: true, // Use comma operator to merge statements
comparisons: true, // Optimize comparison operations
inline: 2, // Inline simple functions
passes: 2, // Number of compression passes
},
});
mangle - Obfuscation Options
minifySync(code, {
mangle: {
toplevel: false, // Whether to obfuscate top-level variables
properties: false, // Whether to obfuscate property names
reserved: ["exports", "require"], // Reserved names
// Output mapping file (for debugging)
// output_map: "mangle-map.json",
},
});
format - Format Options
minifySync(code, {
format: {
comments: false, // Remove all comments
beautify: false, // Whether to beautify output (for debugging)
indent_level: 2, // Indentation level (only when beautifying)
},
});
sourcemap - Source Map
// Generate external Source Map
minifySync(code, {
sourcemap: true,
});
// Generate inline Source Map
minifySync(code, {
sourcemap: "inline",
});
// Don't generate Source Map
minifySync(code, {
sourcemap: false,
});
Integration with Bundlers
Vite Integration
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
build: {
minify: "oxc",
// OXC minification options
oxc: {
minify: {
compress: true,
mangle: true,
},
},
},
});
Webpack Integration
// webpack.config.js
const OxcMinifyPlugin = require("@oxc-minifier/webpack");
module.exports = {
mode: "production",
optimization: {
minimizer: [
new OxcMinifyPlugin({
compress: true,
mangle: true,
sourcemap: true,
}),
],
},
};
Rollup Integration
// rollup.config.js
import { oxcMinify } from "@oxc-minifier/rollup";
export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "esm",
sourcemap: true,
},
plugins: [oxcMinify()],
};
Performance Comparison
Test Environment
- File: A medium-sized project bundle
- Original size: 1.2 MB
- Machine: MacBook Pro M1
Comparison with Terser
// benchmark.js
import { minifySync as oxcMinify } from "@oxc-minifier";
import { minify as terserMinify } from "terser";
import fs from "fs";
const code = fs.readFileSync("./large-bundle.js", "utf-8");
// OXC Minifier
console.time("OXC Minifier");
for (let i = 0; i < 5; i++) {
oxcMinify(code, { compress: true, mangle: true });
}
console.timeEnd("OXC Minifier");
// Terser
console.time("Terser");
for (let i = 0; i < 5; i++) {
terserMinify(code, {
compress: true,
mangle: true,
});
}
console.timeEnd("Terser");
Test Results
| Tool | Minification Time | Output Size | Reduction Rate |
|---|---|---|---|
| Terser | 3.2 seconds | 420 KB | 65% |
| OXC Minifier | 0.5 seconds | 435 KB | 63.75% |
OXC Minifier is about 6x faster than Terser!
While the compression rate is slightly lower, the speed advantage is significant and pays off more in larger projects.
Before and After Comparison
Example 1: Conditional Expression Optimization
// Original code
function getStatus(user) {
if (user.isActive === true) {
if (user.hasPremium === true) {
return "premium";
} else {
return "active";
}
} else {
return "inactive";
}
}
// Minified
function getStatus(e){return e.isActive?!0===e.hasPremium?"premium":"active":"inactive"}
Example 2: Constant Folding
// Original code
const SECONDS_PER_MINUTE = 60;
const MINUTES_PER_HOUR = 60;
const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
function formatDuration(seconds) {
const hours = Math.floor(seconds / SECONDS_PER_HOUR);
const remainingSeconds = seconds % SECONDS_PER_HOUR;
const minutes = Math.floor(remainingSeconds / SECONDS_PER_MINUTE);
return `${hours}h ${minutes}m`;
}
// Minified (constants calculated)
function formatDuration(e){const s=Math.floor(e/3600);return`${s}h ${Math.floor(e%3600/60)}m`}
Example 3: Dead Code Elimination
// Original code
function debug(message) {
if (process.env.NODE_ENV === "development") {
console.log("[DEBUG]", message);
}
}
function doSomething() {
debug("Starting operation");
return "done";
}
// In production, debug function calls will be removed
// Minified (assuming NODE_ENV=production)
function doSomething(){return"done"}
FAQ
Code Errors After Minification?
Possible causes:
- Using
evalorwith: These affect variable scope, minification may cause errors - Depend on specific property names: If code depends on property name strings, don’t obfuscate properties
Solution:
minifySync(code, {
mangle: {
reserved: ["importantName"], // Preserve specific names
},
});
Source Map Doesn’t Match?
Ensure minification options are consistent with bundler settings:
// Make sure Source Map is enabled
minifySync(code, {
sourcemap: true,
});
Want to Preserve Certain Comments?
minifySync(code, {
format: {
comments: /license|copyright/i, // Preserve comments containing these keywords
},
});
Remove console to Keep Logs?
minifySync(code, {
compress: {
drop_console: true, // Remove all console.*
},
});
Best Practices
1. Enable Minification in Production
{
"scripts": {
"build": "vite build --mode production",
"build:dev": "vite build --mode development"
}
}
2. Preserve Source Map for Debugging
// Generate Source Map in production too (upload to error monitoring platform)
minifySync(code, {
sourcemap: true,
});
3. Separate Minification and Obfuscation
// Only minify, no obfuscation (debugging phase)
minifySync(code, {
compress: true,
mangle: false,
});
// Full minification (release phase)
minifySync(code, {
compress: true,
mangle: true,
});
4. Further Compress with gzip
# Minify then gzip
oxc-minify bundle.js -o bundle.min.js
gzip -k bundle.min.js
# Final file: bundle.min.js.gz
Summary
This article covered OXC Minifier’s core usage:
| Content | Description |
|---|---|
| Minify code | Reduce file size by 60%+ |
| Variable obfuscation | Increase reverse engineering difficulty |
| Source Map | Preserve debugging capability |
| Performance advantage | 5x+ faster than Terser |
Minifier’s core value: Users download less, load faster.
Next Steps
Want to learn more about Minifier’s configuration options? Visit OXC Documentation - Minifier Section
In the next article, we’ll learn about OXC Resolver — understanding the magic behind module path resolution!
💡 Related Reading: