Skip to content

targets are ignored unless minify: true #15

Closed

Description

@malomalo

Summary

LightningCSS.transform (and LightningCSS.bundle) only apply targets when minify: true is also passed. Without it, no vendor prefixes are added and colors aren't lowered, with no warning. Lightning CSS's own Node binding applies targets whether or not it minifies.

Reproduction

lightningcss 1.33.0.1 (crate 1.0.0-alpha.72), Ruby 4.0.5, arm64-darwin

LightningCSS.transform(".a { user-select: none }", targets: { safari: 12 }).code
#=> ".a {\n  user-select: none;\n}\n"

LightningCSS.transform(".a { user-select: none }", targets: { safari: 12 }, minify: true).code
#=> ".a{-webkit-user-select:none;user-select:none}"

LightningCSS.transform(".a { color: lab(50% 40 59) }", targets: { chrome: 80 }).code
#=> ".a {\n  color: lab(50% 40 59);\n}\n"

LightningCSS.transform(".a { color: lab(50% 40 59) }", targets: { chrome: 80 }, minify: true).code
#=> ".a{color:#bf5702;color:lab(50% 40 59)}"

The same input through the npm package (1.33.0), without minify:

transform({ filename: "a.css", code: Buffer.from(".a { user-select: none }"), targets: { safari: 12 << 16 } }).code.toString()
// .a {
//   -webkit-user-select: none;
//   user-select: none;
// }

Expected

targets change the output the same way whether minify is true or false. minify only controls how the result is printed.

Cause

In rust/src/lib.rs (on main, aa4ee79), transform_source and bundle_source only call StyleSheet::minify inside if options.minify { ... } (lines 177 and 251). StyleSheet::minify(MinifyOptions { targets, .. }) is the pass that adds prefixes and lowers properties. PrinterOptions.targets on its own only covers what's lowered while printing, such as nesting, which is why nesting is still lowered without minify.

transform_attribute already calls attribute.minify(...) every time, so the three entry points are currently inconsistent.

The Node binding behaves as if it runs that pass every time (see the npm output above), with minify affecting only how the result is printed.

Suggested fix

Call stylesheet.minify(MinifyOptions { targets, ..Default::default() }) every time in transform_source and bundle_source, and keep minify: options.minify on PrinterOptions, so the output matches the Node binding's.

This changes the output of non-minified calls that pass targets, which is the intended behaviour. It's probably worth a note in the changelog. The README example under "Targeting browsers" passes minify: true, which hides the bug, so a test without minify would cover it.

Activity

  1. marcoroth commented on Oct 14, 2026

    @marcoroth
    Owner

    Thanks for reporting @malomalo, I opened #19 to address this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions