CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-minify

Minifier of js, css, html and img files with CLI and programmatic interfaces

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

configuration.mddocs/

Configuration System

Flexible configuration management supporting .minify.json files with directory traversal for CLI usage and direct options passing for programmatic usage.

Capabilities

.minify.json Configuration Files

The CLI automatically reads .minify.json configuration files from the current directory or parent directories. For programmatic usage, pass options directly to minify functions.

interface MinifyConfiguration {
  js?: JSConfiguration;
  css?: CSSConfiguration;  
  html?: HTMLConfiguration;
  img?: ImageConfiguration;
}

interface JSConfiguration {
  type?: 'putout' | 'terser' | 'esbuild' | 'swc';
  putout?: PutoutOptions;
  terser?: TerserOptions;
  esbuild?: ESBuildOptions;
  swc?: SWCOptions;
}

interface CSSConfiguration {
  type?: 'lightningcss' | 'clean-css';
  'clean-css'?: CleanCSSOptions;
}

interface HTMLConfiguration extends HTMLMinifierOptions {}

interface ImageConfiguration {
  maxSize?: number;
}

Usage Examples:

import { minify } from "minify";

// Programmatic usage - pass options directly
const options = {
  js: { type: 'terser', terser: { mangle: true } },
  css: { type: 'clean-css' },
  html: { removeComments: true }
};

const minified = await minify.js(source, options);

// CLI usage automatically loads .minify.json files
// No programmatic import needed for configuration files

Configuration File Format

.minify.json Structure

The configuration file uses JSON format with sections for each minifier type:

{
  "js": {
    "type": "putout",
    "putout": {
      "quote": "'",
      "mangle": true,
      "mangleClassNames": true,
      "removeUnusedVariables": true,
      "removeConsole": false,
      "removeUselessSpread": true
    },
    "terser": {
      "mangle": true,
      "compress": {
        "drop_console": true
      }
    },
    "esbuild": {
      "minifyWhitespace": true,
      "minifyIdentifiers": true,
      "minifySyntax": true
    },
    "swc": {
      "mangle": true,
      "module": true
    }
  },
  "css": {
    "type": "clean-css",
    "clean-css": {
      "level": 2,
      "compatibility": "*"
    }
  },
  "html": {
    "removeComments": true,
    "removeCommentsFromCDATA": true,
    "removeCDATASectionsFromCDATA": true,
    "collapseWhitespace": true,
    "collapseBooleanAttributes": true,
    "removeAttributeQuotes": true,
    "removeRedundantAttributes": true,
    "useShortDoctype": true,
    "removeEmptyAttributes": true,
    "removeEmptyElements": false,
    "removeOptionalTags": true,
    "removeScriptTypeAttributes": true,
    "removeStyleLinkTypeAttributes": true,
    "minifyJS": true,
    "minifyCSS": true
  },
  "img": {
    "maxSize": 4096
  }
}

Directory Traversal

Configuration File Discovery

The system walks up parent directories to find .minify.json files:

interface DirectoryTraversal {
  startDirectory: string;               // Current working directory
  searchPattern: string;                // ".minify.json" filename
  traversalOrder: string[];             // Directories checked in order
  stopCondition: string;                // Root directory or first file found
}

// Example traversal path:
// /project/src/components/  →  /project/src/components/.minify.json
// /project/src/             →  /project/src/.minify.json  
// /project/                 →  /project/.minify.json
// /                         →  /.minify.json

Directory Traversal Examples:

// Project structure:
// /project/
// ├── .minify.json          ← Root configuration
// ├── src/
// │   ├── .minify.json      ← Source-specific overrides
// │   └── components/
// │       └── Button.js     ← Uses src/.minify.json

// CLI working from /project/src/components/
minify Button.js
// Uses: /project/src/.minify.json

// CLI working from /project/
minify src/components/Button.js
// Uses: /project/.minify.json

// No configuration file found - uses defaults
// CLI working from /tmp/
minify /some/file.js
// Uses: built-in defaults

Configuration Sections

JavaScript Configuration

Configure JavaScript minifiers with type selection and options:

{
  "js": {
    "type": "putout",
    "putout": {
      "quote": "'",
      "mangle": true,
      "mangleClassNames": true,
      "removeUnusedVariables": true,
      "removeConsole": false,
      "removeUselessSpread": true
    }
  }
}

JavaScript Configuration Examples:

// Putout configuration (default)
{
  "js": {
    "type": "putout",
    "putout": {
      "mangle": true,
      "removeUnusedVariables": false,
      "quote": "'"
    }
  }
}

// Terser configuration
{
  "js": {
    "type": "terser", 
    "terser": {
      "mangle": {
        "toplevel": true
      },
      "compress": {
        "drop_console": true,
        "drop_debugger": true,
        "pure_funcs": ["console.log"]
      }
    }
  }
}

// ESBuild configuration
{
  "js": {
    "type": "esbuild",
    "esbuild": {
      "minifyWhitespace": true,
      "minifyIdentifiers": true,
      "minifySyntax": true,
      "target": ["es2020"]
    }
  }
}

// SWC configuration
{
  "js": {
    "type": "swc",
    "swc": {
      "mangle": true,
      "module": true,
      "compress": {
        "unused": true
      }
    }
  }
}

CSS Configuration

Configure CSS minifiers with backend selection and optimization levels:

{
  "css": {
    "type": "clean-css",
    "clean-css": {
      "level": {
        "1": {
          "specialComments": 0,
          "removeWhitespace": true
        },
        "2": {
          "mergeAdjacentRules": true,
          "removeEmpty": true,
          "removeDuplicateRules": true
        }
      },
      "compatibility": {
        "properties": {
          "colors": false,
          "ieFilters": true
        }
      }
    }
  }
}

CSS Configuration Examples:

// LightningCSS (default - minimal configuration)
{
  "css": {
    "type": "lightningcss"
  }
}

// Clean-CSS with optimization levels
{
  "css": {
    "type": "clean-css",
    "clean-css": {
      "level": 2,
      "compatibility": "*",
      "format": "beautify",
      "sourceMap": true
    }
  }
}

// Clean-CSS with detailed options
{
  "css": {
    "type": "clean-css", 
    "clean-css": {
      "level": {
        "1": {
          "cleanupCharsets": true,
          "normalizeUrls": true,
          "optimizeBackground": true,
          "optimizeBorderRadius": true,
          "optimizeFilter": true,
          "optimizeFont": true,
          "removeEmpty": true,
          "removeWhitespace": true,
          "specialComments": "all"
        },
        "2": {
          "mergeAdjacentRules": true,
          "mergeIntoShorthands": true,
          "mergeMedia": true,
          "removeDuplicateRules": true,
          "removeUnusedAtRules": false
        }
      }
    }
  }
}

HTML Configuration

Configure HTML minification with comprehensive optimization settings:

{
  "html": {
    "removeComments": true,
    "removeCommentsFromCDATA": true,
    "removeCDATASectionsFromCDATA": true,
    "collapseWhitespace": true,
    "collapseBooleanAttributes": true,
    "removeAttributeQuotes": true,
    "removeRedundantAttributes": true,
    "useShortDoctype": true,
    "removeEmptyAttributes": true,
    "removeEmptyElements": false,
    "removeOptionalTags": true,
    "removeScriptTypeAttributes": true,
    "removeStyleLinkTypeAttributes": true,
    "minifyJS": true,
    "minifyCSS": true
  }
}

HTML Configuration Examples:

// Conservative HTML minification
{
  "html": {
    "removeComments": false,
    "collapseWhitespace": true,
    "removeEmptyElements": false,
    "removeOptionalTags": false,
    "minifyJS": false,
    "minifyCSS": false
  }
}

// Aggressive HTML minification
{
  "html": {
    "removeComments": true,
    "collapseWhitespace": true,
    "removeAttributeQuotes": true,
    "removeRedundantAttributes": true,
    "removeEmptyAttributes": true,
    "removeOptionalTags": true,
    "minifyJS": true,
    "minifyCSS": true,
    "useShortDoctype": true
  }
}

// Template-friendly configuration
{
  "html": {
    "collapseWhitespace": true,
    "removeComments": false,
    "removeEmptyElements": false,
    "ignoreCustomFragments": [
      "<%[\\s\\S]*?%>",
      "<\\?[\\s\\S]*?\\?>"
    ]
  }
}

Image Configuration

Configure image processing and base64 inlining thresholds:

{
  "img": {
    "maxSize": 102400
  }
}

Image Configuration Examples:

// Conservative image inlining (small files only)
{
  "img": {
    "maxSize": 10000
  }
}

// Aggressive image inlining
{
  "img": {
    "maxSize": 500000
  }
}

// Disable image inlining
{
  "img": {
    "maxSize": 0
  }
}

// Default behavior (100KB threshold)
{
  "img": {
    "maxSize": 102400
  }
}

Configuration Hierarchy

Precedence Rules

Configuration sources are applied in order of precedence:

interface ConfigurationPrecedence {
  1: 'runtime-options';                 // Highest: Options passed to minify functions
  2: 'nearest-config-file';             // .minify.json in current/nearest parent directory
  3: 'default-settings';                // Lowest: Built-in default configurations
}

// Example precedence resolution for programmatic usage:
const runtimeOptions = { js: { type: 'terser' } }; // Passed to function

const finalConfig = {
  ...builtInDefaults,
  ...runtimeOptions  // Takes precedence
};

Hierarchy Examples:

// Project with nested configuration
// /project/.minify.json:
{
  "js": { "type": "putout" },
  "css": { "type": "clean-css" }
}

// /project/src/.minify.json:
{
  "js": { "type": "terser" }  // Overrides parent
}

// CLI working from /project/src/ uses nearest config:
minify app.js
// Uses: { js: { type: "terser" }, css: { type: "clean-css" } }

// Programmatic usage ignores config files:
const result = await minify.js(source, {
  js: { type: 'esbuild' }  // Only uses passed options
});

Error Handling

Configuration Error Management

Robust error handling for configuration file issues:

interface ConfigurationErrors {
  fileNotFound: 'cli-uses-defaults';           // CLI continues with defaults
  invalidJSON: 'cli-throws-parse-error';       // JSON syntax errors in CLI
  filePermissions: 'cli-throws-access-error';  // File access denied in CLI
  malformedOptions: 'validates-at-usage';      // Validation during minification
}

Error Handling Examples:

# Missing configuration file (CLI uses defaults)
minify app.js
# Uses built-in defaults, no error

# Invalid JSON syntax in .minify.json
# { "js": { type: "invalid" }  // Missing closing brace
minify app.js
# CLI Error: JSON parse error in .minify.json

# File permission error
# .minify.json exists but is not readable
minify app.js  
# CLI Error: EACCES - cannot read .minify.json
// Invalid configuration options (caught during programmatic usage)
const invalidConfig = { js: { type: 'nonexistent-minifier' } };
try {
  const result = await minify.js(source, invalidConfig);
} catch (error) {
  console.log(error.message); // Invalid minifier type error
}

Testing and Development

Configuration Usage Patterns

Different approaches for various use cases:

interface UsagePatterns {
  programmatic: 'pass-options-directly';
  cli: 'use-minify-json-files';
  testing: 'pass-options-directly';
  environment: 'conditional-configuration';
}

// Production vs Development example
const getConfig = (environment) => ({
  js: {
    type: environment === 'production' ? 'terser' : 'putout',
    [environment === 'production' ? 'terser' : 'putout']: {
      mangle: environment === 'production',
      removeConsole: environment === 'production'
    }
  }
});

Testing Integration Examples:

// Test configuration by passing options directly
import { minify } from 'minify';

describe('Configuration System', () => {
  test('should use custom JS configuration', async () => {
    const options = { js: { type: 'esbuild' } };
    const result = await minify.js('function test() {}', options);
    expect(result).toBeTruthy();
  });

  test('should use custom CSS configuration', async () => {
    const options = { css: { type: 'clean-css' } };
    const result = await minify.css('body { color: red; }', options);
    expect(result).toBeTruthy();
  });
});

// Development environment - different configs for dev vs prod
const isDev = process.env.NODE_ENV === 'development';
const devConfig = {
  js: { 
    type: 'putout',
    putout: { removeConsole: false }  // Keep console in dev
  }
};
const prodConfig = {
  js: {
    type: 'terser',
    terser: { compress: { drop_console: true } }
  }
};

const config = isDev ? devConfig : prodConfig;
const result = await minify.js(source, config);

docs

auto-detection.md

cli-interface.md

configuration.md

css-minification.md

html-minification.md

image-processing.md

index.md

javascript-minification.md

tile.json