or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-css-inline--css-inline

High-performance library for inlining CSS into HTML 'style' attributes

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@css-inline/css-inline@0.17.x

To install, run

npx @tessl/cli install tessl/npm-css-inline--css-inline@0.17.0

index.mddocs/

CSS Inline

CSS Inline is a high-performance library for inlining CSS into HTML 'style' attributes. It's designed for scenarios such as preparing HTML emails or embedding HTML into third-party web pages where external stylesheets cannot be loaded.

Package Information

  • Package Name: @css-inline/css-inline
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install @css-inline/css-inline

Core Imports

import { inline, inlineFragment, version } from "@css-inline/css-inline";

For CommonJS:

const { inline, inlineFragment, version } = require("@css-inline/css-inline");

For WebAssembly (browser):

import { initWasm, inline, inlineFragment, version } from "@css-inline/css-inline/wasm-binding";

Basic Usage

import { inline } from "@css-inline/css-inline";

// Inline CSS from a complete HTML document
const html = `
<html>
  <head>
    <style>h1 { color: blue; }</style>
  </head>
  <body>
    <h1>Big Text</h1>
  </body>
</html>
`;

const inlinedHtml = inline(html);
// Result: <html><head></head><body><h1 style="color: blue;">Big Text</h1></body></html>

Architecture

CSS Inline operates through two execution environments:

  • Node.js Native: Uses Rust-based native bindings via NAPI for maximum performance
  • WebAssembly: Provides browser compatibility with limited functionality (no caching, no remote/local stylesheet loading)

The library processes HTML documents by:

  1. Parsing HTML and CSS using components from Mozilla's Servo project
  2. Applying CSS selectors to matching HTML elements
  3. Converting matched CSS rules to inline style attributes
  4. Removing original <style> and <link> tags (configurable)

Capabilities

HTML Document Inlining

Complete HTML document processing that inlines CSS from <style> tags and external stylesheets referenced by <link> tags.

/**
 * Inline CSS styles from <style> tags to matching elements in the HTML tree
 * @param html - Complete HTML document to process
 * @param options - Configuration options for inlining behavior
 * @returns HTML document with CSS inlined into style attributes
 */
function inline(html: string, options?: Options | undefined | null): string;

Usage Examples:

import { inline } from "@css-inline/css-inline";

// Basic inlining
const result = inline(`
<html>
  <head>
    <style>
      h1 { color: red; }
      p { font-size: 14px; }
    </style>
  </head>
  <body>
    <h1>Title</h1>
    <p>Paragraph</p>
  </body>
</html>
`);

// With external stylesheet
const resultWithExternalCSS = inline(`
<html>
  <head>
    <link href="styles.css" rel="stylesheet">
  </head>
  <body>
    <h1>Title</h1>
  </body>
</html>
`, { baseUrl: "file:///path/to/stylesheets/" });

// With caching for performance
const resultWithCache = inline(html, {
  cache: { size: 10 },
  loadRemoteStylesheets: true
});

HTML Fragment Inlining

Process HTML fragments (partial HTML without full document structure) by applying provided CSS styles directly.

/**
 * Inline CSS styles into an HTML fragment
 * @param html - HTML fragment to process (no <html>, <head>, or <body> required)
 * @param css - CSS styles to apply to the fragment
 * @param options - Configuration options for inlining behavior
 * @returns HTML fragment with CSS inlined into style attributes
 */
function inlineFragment(html: string, css: string, options?: Options | undefined | null): string;

Usage Examples:

import { inlineFragment } from "@css-inline/css-inline";

// Process a fragment
const fragment = `
<main>
  <h1>Hello</h1>
  <section>
    <p>Content here</p>
  </section>
</main>
`;

const css = `
h1 { color: blue; }
p { color: red; font-size: 16px; }
`;

const result = inlineFragment(fragment, css);
// Result: <main><h1 style="color: blue;">Hello</h1><section><p style="color: red; font-size: 16px;">Content here</p></section></main>

Version Information

Get the current package version for debugging or compatibility checks.

/**
 * Get the package version
 * @returns Package version string
 */
function version(): string;

WebAssembly Initialization

Initialize the WebAssembly module before using WASM variant functions. Required for browser usage.

/**
 * Initialize Wasm module (WASM variant only)
 * @param module_or_path - WebAssembly Module or .wasm file URL
 * @returns Promise that resolves when initialization is complete
 * @throws Error if called multiple times
 */
function initWasm(module_or_path: Promise<InitInput> | InitInput): Promise<void>;

Usage Example:

import { initWasm, inline } from "@css-inline/css-inline/wasm-binding";
import { promises as fs } from "fs";

// Initialize WASM module first (only once per session)
await initWasm(fs.readFile("path/to/index_bg.wasm"));

// Now use the API normally (no remote stylesheets or caching supported)
const result = inline(htmlContent);

WASM Limitations:

  • No remote stylesheet loading (HTTP/HTTPS URLs not supported)
  • No local file system access
  • No caching support
  • Different error messages for unsupported operations

Configuration

Options Interface

interface Options {
  /** Whether to inline CSS from "style" tags (default: true) */
  inlineStyleTags?: boolean;
  /** Keep "style" tags after inlining (default: false) */
  keepStyleTags?: boolean;
  /** Keep "link" tags after inlining (default: false) */
  keepLinkTags?: boolean;
  /** Base URL for resolving relative stylesheet URLs */
  baseUrl?: string;
  /** Whether remote stylesheets should be loaded (default: true) */
  loadRemoteStylesheets?: boolean;
  /** LRU cache for external stylesheets (Node.js only) */
  cache?: StylesheetCache;
  /** Additional CSS to inline beyond document styles */
  extraCss?: string;
  /** Pre-allocate HTML node capacity for performance (default: 32) */
  preallocateNodeCapacity?: number;
}

StylesheetCache Interface

interface StylesheetCache {
  /** Cache size - must be integer greater than zero */
  size: number;
}

WebAssembly Types

interface InlineOptions {
  /** Whether to inline CSS from "style" tags (default: true) */
  inlineStyleTags?: boolean;
  /** Keep "style" tags after inlining (default: false) */
  keepStyleTags?: boolean;
  /** Keep "link" tags after inlining (default: false) */
  keepLinkTags?: boolean;
  /** Keep "at-rules" like @media after inlining (default: false) */
  keepAtRules?: boolean;
  /** Base URL for resolving relative stylesheet URLs (limited support in WASM) */
  baseUrl?: string;
  /** Whether remote stylesheets should be loaded (NOT supported in WASM) */
  loadRemoteStylesheets?: boolean;
  /** Additional CSS to inline beyond document styles */
  extraCss?: string;
  /** Pre-allocate HTML node capacity for performance (default: 32) */
  preallocateNodeCapacity?: number;
}

type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;

Advanced Configuration

HTML Element Control

Control inlining behavior per HTML element using data attributes:

<!-- Skip inlining for this element -->
<h1 data-css-inline="ignore">Won't receive styles</h1>

<!-- Keep the style tag (don't remove it) -->
<style data-css-inline="keep">h1 { color: blue; }</style>

<!-- Ignore this style tag entirely -->
<style data-css-inline="ignore">h1 { color: red; }</style>

External Stylesheet Handling

// Load stylesheets from local filesystem
const result = inline(html, {
  baseUrl: "file:///path/to/project/",
  loadRemoteStylesheets: true
});

// Load from remote URLs with caching
const result = inline(html, {
  baseUrl: "https://example.com/assets/",
  cache: { size: 5 }, // Cache up to 5 stylesheets
  loadRemoteStylesheets: true
});

// Add extra CSS beyond document styles
const result = inline(html, {
  extraCss: "body { margin: 0; padding: 0; }"
});

Performance Optimization

// Pre-allocate capacity for large documents
const result = inline(html, {
  preallocateNodeCapacity: 1000 // If you expect ~1000 HTML nodes
});

// Cache external stylesheets for performance
const result = inline(html, {
  cache: { size: 10 }, // Cache up to 10 stylesheets
  loadRemoteStylesheets: true
});

Error Handling

The library throws errors with different behaviors depending on the execution environment:

Node.js Native Errors

  • InvalidArg: Invalid argument values (e.g., malformed baseUrl)
  • GenericFailure: Processing failures (e.g., invalid CSS syntax, malformed HTML)
try {
  const result = inline(html, { baseUrl: "invalid-url" });
} catch (error) {
  console.log(error.code); // "InvalidArg"  
  console.log(error.message); // "relative URL without a base: invalid-url"
}

WASM Errors

WASM variant throws string errors without structured codes:

try {
  const result = inline(html, { baseUrl: "invalid-url" });
} catch (error) {
  console.log(error); // "relative URL without a base: invalid-url"
}

// WASM-specific errors for unsupported operations
try {
  const result = inline(`<link href="http://example.com/style.css" rel="stylesheet">`);
} catch (error) {
  console.log(error); // "Loading remote stylesheets is not supported on WASM: http://example.com/style.css"
}

Platform Support

  • Node.js: Native performance on Linux, Windows, macOS, FreeBSD, Android
  • Architectures: x64, arm64, ia32, armv7
  • Browsers: WebAssembly support (no caching or filesystem access)
  • Minimum Version: Node.js 10+

Performance

Built on Mozilla Servo components, CSS Inline significantly outperforms JavaScript alternatives:

  • 3x faster than most alternatives in typical scenarios
  • Efficient stylesheet caching reduces network requests
  • Optional memory pre-allocation for large documents
  • Lazy evaluation and optimized CSS parsing