CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lightningcss

A CSS parser, transformer, and minifier written in Rust with Node.js bindings

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

rust-api.mddocs/

Rust Library API

Direct Rust library interface providing low-level CSS parsing, transformation, and serialization capabilities with zero-cost abstractions and memory safety.

Capabilities

StyleSheet Parsing and Transformation

Core stylesheet parsing, minification, and serialization with configurable options and error handling.

use lightningcss::{
    stylesheet::{StyleSheet, MinifyOptions, ParserOptions, PrinterOptions, ToCssResult},
    error::{Error, ParserError, MinifyErrorKind, PrinterErrorKind},
    traits::{Parse, ToCss},
};

impl<'i, 'o, T> StyleSheet<'i, 'o, T> 
where 
    T: crate::traits::AtRuleParser<'i>
{
    /// Parse a CSS stylesheet from a string
    pub fn parse(
        css: &'i str, 
        options: ParserOptions<'o, 'i>
    ) -> Result<Self, Error<ParserError<'i>>>;
    
    /// Minify the stylesheet in-place
    pub fn minify(&mut self, options: MinifyOptions) -> Result<(), Error<MinifyErrorKind>>;
    
    /// Serialize the stylesheet to CSS
    pub fn to_css(&self, options: PrinterOptions) -> Result<ToCssResult, Error<PrinterErrorKind>>;
    
    /// Get the rules in this stylesheet
    pub fn rules(&self) -> &crate::rules::CssRuleList<'i, 'o, T>;
    
    /// Get mutable access to the rules in this stylesheet
    pub fn rules_mut(&mut self) -> &mut crate::rules::CssRuleList<'i, 'o, T>;
}

/// Configuration options for CSS parsing
pub struct ParserOptions<'o, 'i> {
    /// The filename being parsed, used for error messages
    pub filename: &'i str,
    /// CSS Modules configuration
    pub css_modules: Option<crate::css_modules::CssModulesConfig<'o>>,
    /// Source index for source maps
    pub source_index: u32,
    /// Whether to recover from parse errors
    pub error_recovery: bool,
    /// Optional warnings collection
    pub warnings: Option<&'o mut Vec<Error<ParserError<'i>>>>,
    /// Parser feature flags
    pub flags: crate::parser::ParserFlags,
}

/// Options for CSS minification
pub struct MinifyOptions {
    /// Browser targets for optimization
    pub targets: Option<crate::targets::Targets>,
    /// List of unused symbols to remove
    pub unused_symbols: std::collections::HashSet<String>,
}

/// Options for CSS serialization/printing
pub struct PrinterOptions<'a> {
    /// Whether to minify the output
    pub minify: bool,
    /// Whether to include source map information
    pub source_map: Option<&'a mut crate::sourcemap::SourceMap>,
    /// Project root for source map paths
    pub project_root: Option<&'a str>,
    /// Browser targets for vendor prefixes
    pub targets: Option<crate::targets::Targets>,
    /// Whether to analyze dependencies
    pub analyze_dependencies: Option<crate::dependencies::DependencyOptions<'a>>,
    /// Pseudo-class replacements
    pub pseudo_classes: Option<crate::properties::ui::PseudoClasses<'a>>,
}

/// Result of CSS serialization
pub struct ToCssResult {
    /// The serialized CSS code
    pub code: String,
    /// Extracted dependencies, if enabled
    pub dependencies: Option<Vec<crate::dependencies::Dependency>>,
    /// CSS module exports, if enabled
    pub exports: Option<crate::css_modules::CssModuleExports>,
    /// CSS module references, if enabled
    pub references: Option<crate::css_modules::CssModuleReferences>,
}

Usage Examples:

use lightningcss::{
    stylesheet::{StyleSheet, MinifyOptions, ParserOptions, PrinterOptions},
    targets::Targets,
};

// Basic parsing and minification
fn process_css(css: &str) -> Result<String, Box<dyn std::error::Error>> {
    let mut stylesheet = StyleSheet::parse(css, ParserOptions::default())?;
    
    stylesheet.minify(MinifyOptions::default())?;
    
    let result = stylesheet.to_css(PrinterOptions {
        minify: true,
        ..PrinterOptions::default()
    })?;
    
    Ok(result.code)
}

// Advanced configuration
fn process_with_targets(css: &str) -> Result<String, Box<dyn std::error::Error>> {
    let mut warnings = Vec::new();
    
    let mut stylesheet = StyleSheet::parse(css, ParserOptions {
        filename: "input.css",
        error_recovery: true,
        warnings: Some(&mut warnings),
        ..ParserOptions::default()
    })?;
    
    let targets = Targets {
        chrome: Some(80 << 16),
        firefox: Some(75 << 16),
        safari: Some(13 << 16),
        ..Targets::default()
    };
    
    stylesheet.minify(MinifyOptions {
        targets: Some(targets.clone()),
        unused_symbols: ["unused-class", "old-animation"].iter().map(|s| s.to_string()).collect(),
    })?;
    
    let result = stylesheet.to_css(PrinterOptions {
        minify: true,
        targets: Some(targets),
        ..PrinterOptions::default()
    })?;
    
    // Handle warnings
    for warning in warnings {
        eprintln!("Warning: {:?}", warning);
    }
    
    Ok(result.code)
}

Browser Targets

Rust-native browser targeting for CSS transformation and vendor prefixing.

use lightningcss::targets::{Targets, Browsers};

/// Browser compatibility targets
#[derive(Debug, Clone, Default)]
pub struct Targets {
    pub android: Option<u32>,
    pub chrome: Option<u32>,
    pub edge: Option<u32>,
    pub firefox: Option<u32>,
    pub ie: Option<u32>,
    pub ios_saf: Option<u32>,
    pub opera: Option<u32>,
    pub safari: Option<u32>,
    pub samsung: Option<u32>,
}

impl Targets {
    /// Create targets from browser versions
    pub fn new(browsers: &Browsers) -> Self;
    
    /// Check if a specific feature is supported
    pub fn is_compatible(&self, feature: crate::compat::Feature) -> bool;
    
    /// Get the minimum browser versions
    pub fn browsers(&self) -> Browsers;
}

/// Browser version specifications
#[derive(Debug, Clone, Default)]
pub struct Browsers {
    pub android: Option<f32>,
    pub chrome: Option<f32>, 
    pub edge: Option<f32>,
    pub firefox: Option<f32>,
    pub ie: Option<f32>,
    pub ios_saf: Option<f32>,
    pub opera: Option<f32>,
    pub safari: Option<f32>,
    pub samsung: Option<f32>,
}

Usage Examples:

use lightningcss::targets::{Targets, Browsers};

// Direct target creation
let targets = Targets {
    chrome: Some(90 << 16),
    firefox: Some(88 << 16), 
    safari: Some(14 << 16),
    ..Targets::default()
};

// From browser versions
let browsers = Browsers {
    chrome: Some(90.0),
    firefox: Some(88.0),
    safari: Some(14.0),
    ..Browsers::default()
};
let targets = Targets::new(&browsers);

// Feature compatibility checking
let supports_grid = targets.is_compatible(crate::compat::Feature::CssGrid);

CSS Bundling

Rust API for bundling CSS files with dependency resolution and @import inlining.

#[cfg(feature = "bundler")]
use lightningcss::bundler::{Bundler, BundleErrorKind, FileProvider, SourceProvider};

/// CSS bundler for combining multiple files
pub struct Bundler<'a, 'o, 's, P, T> 
where 
    P: SourceProvider,
    T: crate::traits::AtRuleParser<'a>
{
    /// Create a new bundler with a source provider
    pub fn new(provider: &'s P, source_map: Option<&'s mut crate::sourcemap::SourceMap>) -> Self;
    
    /// Bundle a CSS file and its dependencies
    pub fn bundle(
        &mut self,
        fs_path: &std::path::Path,
        options: crate::stylesheet::ParserOptions<'o, 'a>
    ) -> Result<crate::stylesheet::StyleSheet<'a, 'o, T>, BundleErrorKind<'a, std::io::Error>>;
}

/// Trait for providing CSS source content
pub trait SourceProvider: Send + Sync {
    type Error: std::error::Error + Send + Sync + 'static;
    
    /// Read CSS content from a file path
    fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error>;
}

/// File system source provider
pub struct FileProvider {
    /// Create a new file provider
    pub fn new() -> Self;
}

impl SourceProvider for FileProvider {
    type Error = std::io::Error;
    
    fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error> {
        std::fs::read_to_string(file).map(std::borrow::Cow::Owned)
    }
}

Usage Examples:

#[cfg(feature = "bundler")]
use lightningcss::bundler::{Bundler, FileProvider};
use lightningcss::stylesheet::{ParserOptions, PrinterOptions};
use std::path::Path;

#[cfg(feature = "bundler")]
fn bundle_css(entry_path: &Path) -> Result<String, Box<dyn std::error::Error>> {
    let fs = FileProvider::new();
    let mut bundler = Bundler::new(&fs, None);
    
    let stylesheet = bundler.bundle(entry_path, ParserOptions::default())?;
    
    let result = stylesheet.to_css(PrinterOptions {
        minify: true,
        ..PrinterOptions::default()
    })?;
    
    Ok(result.code)
}

// Custom source provider
#[cfg(feature = "bundler")]
struct DatabaseProvider {
    // Custom implementation
}

#[cfg(feature = "bundler")]
impl SourceProvider for DatabaseProvider {
    type Error = Box<dyn std::error::Error>;
    
    fn read<'a>(&'a self, file: &std::path::Path) -> Result<std::borrow::Cow<'a, str>, Self::Error> {
        // Read from database, cache, etc.
        let content = fetch_from_database(file)?;
        Ok(std::borrow::Cow::Owned(content))
    }
}

Style Attribute Processing

Parse and transform individual CSS declaration lists for style attributes.

use lightningcss::stylesheet::StyleAttribute;

/// Parser for CSS declaration lists (style attributes)
pub struct StyleAttribute<'i> {
    /// Parse a declaration list from a string
    pub fn parse(
        input: &'i str,
        options: crate::stylesheet::ParserOptions<'_, 'i>
    ) -> Result<Self, crate::error::Error<crate::error::ParserError<'i>>>;
    
    /// Minify the declarations in-place
    pub fn minify(
        &mut self, 
        options: crate::stylesheet::MinifyOptions
    ) -> Result<(), crate::error::Error<crate::error::MinifyErrorKind>>;
    
    /// Serialize to CSS
    pub fn to_css(
        &self, 
        options: crate::stylesheet::PrinterOptions
    ) -> Result<crate::stylesheet::ToCssResult, crate::error::Error<crate::error::PrinterErrorKind>>;
    
    /// Get the declarations
    pub fn declarations(&self) -> &crate::declaration::DeclarationBlock<'i>;
    
    /// Get mutable access to declarations
    pub fn declarations_mut(&mut self) -> &mut crate::declaration::DeclarationBlock<'i>;
}

Usage Examples:

use lightningcss::stylesheet::{StyleAttribute, ParserOptions, MinifyOptions, PrinterOptions};

fn process_style_attribute(style: &str) -> Result<String, Box<dyn std::error::Error>> {
    let mut declarations = StyleAttribute::parse(style, ParserOptions::default())?;
    
    declarations.minify(MinifyOptions::default())?;
    
    let result = declarations.to_css(PrinterOptions {
        minify: true,
        ..PrinterOptions::default()
    })?;
    
    Ok(result.code)
}

// Example: "color: red; background: blue; margin: 10px 20px 10px 20px"
// Result: "color:red;background:blue;margin:10px 20px"

Error Handling

Comprehensive error types for different CSS processing stages.

use lightningcss::error::{Error, ErrorLocation, ParserError, MinifyErrorKind, PrinterErrorKind};

/// Generic error wrapper with location information
pub struct Error<T> {
    /// The error kind
    pub kind: T,
    /// Source location where error occurred
    pub loc: Option<ErrorLocation>,
}

/// Source location information
pub struct ErrorLocation {
    /// Filename where error occurred
    pub filename: String,
    /// Line number (1-based)
    pub line: u32,
    /// Column number (1-based)
    pub column: u32,
}

/// CSS parsing errors
pub enum ParserError<'i> {
    /// Unexpected token during parsing
    UnexpectedToken(cssparser::Token<'i>),
    /// Unexpected EOF
    UnexpectedEOF,
    /// Invalid selector
    SelectorError(crate::error::SelectorError<'i>),
    /// Invalid at-rule
    InvalidAtRule(std::borrow::Cow<'i, str>),
    /// Invalid declaration
    InvalidDeclaration,
    /// Invalid value for property
    InvalidValue,
    /// Invalid media query
    InvalidMediaQuery(cssparser::ParseError<'i, cssparser::BasicParseError<'i>>),
    // ... more error variants
}

/// CSS minification errors
pub enum MinifyErrorKind {
    /// Circular dependency in @import rules
    CircularImport,
    /// Invalid property value during minification
    InvalidPropertyValue,
    // ... more error variants
}

/// CSS printing/serialization errors  
pub enum PrinterErrorKind {
    /// I/O error during output
    Io(std::io::Error),
    /// Invalid UTF-8 in output
    InvalidUtf8,
    // ... more error variants
}

Usage Examples:

use lightningcss::{
    stylesheet::{StyleSheet, ParserOptions},
    error::{Error, ParserError, ErrorLocation},
};

fn handle_css_errors(css: &str) {
    match StyleSheet::parse(css, ParserOptions::default()) {
        Ok(stylesheet) => {
            println!("Parsed successfully");
        }
        Err(Error { kind, loc }) => {
            match kind {
                ParserError::UnexpectedToken(token) => {
                    println!("Unexpected token: {:?}", token);
                }
                ParserError::InvalidDeclaration => {
                    println!("Invalid CSS declaration");
                }
                ParserError::SelectorError(sel_err) => {
                    println!("Invalid selector: {:?}", sel_err);
                }
                _ => {
                    println!("Parse error: {:?}", kind);
                }
            }
            
            if let Some(ErrorLocation { filename, line, column }) = loc {
                println!("  at {}:{}:{}", filename, line, column);
            }
        }
    }
}

Trait Implementations

Core traits for parsing and serialization that can be implemented for custom types.

use lightningcss::traits::{Parse, ToCss};

/// Trait for parsing CSS values from tokens
pub trait Parse<'i>: Sized {
    /// Parse this value from a CSS parser
    fn parse<'t>(input: &mut cssparser::Parser<'i, 't>) -> Result<Self, cssparser::ParseError<'i, Self::Error>>;
    
    /// Associated error type for parsing failures
    type Error: 'i;
}

/// Trait for serializing values to CSS
pub trait ToCss {
    /// Write this value as CSS to the given destination
    fn to_css<W>(&self, dest: &mut crate::printer::Printer<W>) -> Result<(), crate::error::PrinterError>
    where W: std::fmt::Write;
    
    /// Convert to a CSS string
    fn to_css_string(&self) -> Result<String, crate::error::PrinterError> {
        let mut s = String::new();
        let mut printer = crate::printer::Printer::new(&mut s, crate::printer::PrinterOptions::default());
        self.to_css(&mut printer)?;
        Ok(s)
    }
}

Usage Examples:

use lightningcss::traits::{Parse, ToCss};
use cssparser::{Parser, Token};

// Custom CSS value type
#[derive(Debug, Clone)]
struct CustomLength {
    value: f32,
    unit: String,
}

impl<'i> Parse<'i> for CustomLength {
    type Error = ();
    
    fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, cssparser::ParseError<'i, Self::Error>> {
        match input.next()? {
            Token::Dimension { value, unit, .. } => {
                Ok(CustomLength {
                    value: *value,
                    unit: unit.to_string(),
                })
            }
            _ => Err(input.new_custom_error(())),
        }
    }
}

impl ToCss for CustomLength {
    fn to_css<W>(&self, dest: &mut crate::printer::Printer<W>) -> Result<(), crate::error::PrinterError>
    where W: std::fmt::Write {
        write!(dest, "{}{}", self.value, self.unit)?;
        Ok(())
    }
}

// Usage
fn parse_custom_length(css: &str) -> Result<CustomLength, Box<dyn std::error::Error>> {
    let mut input = cssparser::ParserInput::new(css);
    let mut parser = cssparser::Parser::new(&mut input);
    Ok(CustomLength::parse(&mut parser)?)
}

docs

bundling.md

index.md

rust-api.md

style-attributes.md

targets.md

transformation.md

visitors.md

tile.json