npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lightning-vue/compiler

v0.0.4

Published

Vue SFC compiler module with a Lightning CSS-backed style compiler

Readme

Compiler SFC Lightning CSS

@lightning-vue/compiler is a compiler-module variant of @vue/compiler-sfc whose style compiler is implemented with Lightning CSS.

[!WARNING] @lightning-vue/compiler is in early development. Expect breaking changes, incomplete compatibility coverage, and behavior shifts while the style compiler is still being hardened.

The package re-exports the public @vue/compiler-sfc surface so tooling can swap it in as a compiler-module override, but it owns its own style engine:

  • compileStyle(...)
  • compileStyleAsync(...)
  • compileStyleWithLightningCss(...)

Everything outside style compilation is still passed through from @vue/compiler-sfc.

Intended Use

The main target is tooling that already accepts a compiler-module override, such as @vitejs/plugin-vue:

import vue from "@vitejs/plugin-vue";
import * as compiler from "@lightning-vue/compiler";

export default {
  plugins: [vue({ compiler })],
};

That is the reason this package re-exports the whole compiler surface instead of shipping only a standalone compileStyle.

Style Compiler Contract

This package is strict.

It does not emulate the full PostCSS-based style pipeline from @vue/compiler-sfc. Unsupported style options fail fast. There is no silent fallback.

Supported:

  • ordinary <style> and <style scoped> compilation
  • :deep(), :slotted(), and :global() selectors
  • nested CSS via source normalization + Lightning CSS lowering
  • postcssOptions.map, which is the sourcemap request shape commonly used by @vitejs/plugin-vue
  • compileStyleAsync(..., { modules: true }) for Lightning CSS's built-in CSS Modules support
    • supported subset:
      • default local scoping
      • Lightning CSS's default naming, which currently uses [hash]_[local]
      • modulesOptions.generateScopedName as a string pattern using only [name], [local], and [hash]
      • modulesOptions.localsConvention
    • note:
      • this stays async-only to match @vue/compiler-sfc's public API contract, even though the underlying Lightning CSS modules transform is synchronous

Unsupported:

  • postcssPlugins
  • postcssOptions keys other than map
  • compileStyle(..., { modules: true })
  • modules combined with scoped
  • CSS Modules options outside the supported Lightning CSS subset, including scopeBehaviour: 'global', function generateScopedName, hashPrefix, exportGlobals, and globalModulePaths
  • legacy scoped selector syntax such as >>>, /deep/, ::v-deep(...), ::v-slotted(...), and ::v-global(...); use :deep(), :slotted(), and :global() instead. These are good future codemod targets.
  • trim: false

When those option shapes are needed, use @vue/compiler-sfc.

Benchmarks

The compare suite measures @lightning-vue/compiler against the current PostCSS-based @vue/compiler-sfc style compiler on the same scoped CSS input.

Snapshot from pnpm bench:compare on April 24, 2026, using a 5-run median. Environment: MacBook Air (13-inch, M4, 2025), Apple M4, 10-core CPU (4 performance + 6 efficiency), 32 GB memory, macOS 26.4.1, Node v24.15.0, pnpm 10.33.0, darwin/arm64.

node tools/bench-scoped-selector.mjs --bench bench/compileStyle.compare.bench.ts --runs 5

Times are median wall time per compileStyle call. Speedup is based on operations per second, so lower time and higher speedup both favor @lightning-vue/compiler.

Parity Cases

These cases emit the same CSS after normalization.

| Case | Lightning CSS | PostCSS | Speedup | | ------------------------------------------------ | ------------: | --------: | ------: | | Simple selectors | 0.2147 ms | 0.7965 ms | 4.48x | | :deep() / :slotted() / :global() selectors | 0.5654 ms | 1.6062 ms | 3.27x | | Nested selectors | 0.3445 ms | 1.4948 ms | 4.92x | | Animation keyframes | 0.2881 ms | 0.7488 ms | 2.93x | | Nested at-rules with simple selectors | 0.2584 ms | 0.5807 ms | 2.43x | | Nested at-rules with compound selectors | 0.3011 ms | 0.7973 ms | 3.06x | | Nested at-rules with descendant selectors | 0.2998 ms | 0.6953 ms | 2.52x | | Nested at-rules with realistic selectors | 0.3792 ms | 1.1415 ms | 3.42x | | Mixed nested selectors and at-rules | 0.4289 ms | 1.8702 ms | 4.94x |

Correctness-Sensitive Cases

These cases exercise documented drift examples. They measure throughput on the same input while the two compilers preserve different selector semantics.

| Case | Lightning CSS | PostCSS | Speedup | | ------------------------------------------------------- | ------------: | --------: | ------: | | Selectors that wrap :deep() | 0.3784 ms | 0.9187 ms | 2.81x | | Mixed realistic styles | 0.6985 ms | 1.7445 ms | 2.74x | | Nested at-rules with :slotted() and wrapped :deep() | 0.4925 ms | 1.0328 ms | 2.38x |

The Node build is benchmarked here; the browser/WASM build may have different performance characteristics and is not covered by this snapshot.

Intentional Drifts

This package currently has a small set of intentional semantic drifts from the current PostCSS-based @vue/compiler-sfc implementation.

For concrete examples and side-by-side outputs, see the divergence playground: https://lightning-vue.haoqun.dev/divergence/

  • Wildcard selectors stay valid
    • @lightning-vue/compiler: Keeps valid selectors such as * + :hover and svg\|* valid after scoping.
    • Current PostCSS path: Still breaks some wildcard forms.
  • Selectors that wrap :deep() stay locally scoped
    • @lightning-vue/compiler: In selectors like :not(.foo :deep(.bar)) and :has(.foo :deep(.bar)), lowers the deep branch and keeps the wrapper locally anchored.
    • Current PostCSS path: The inner deep branch now lowers too. The outer [data-v-*] anchor can still drop off the wrapper, which changes the final selector shape.
  • Nested :slotted(...) keeps its meaning
    • @lightning-vue/compiler: Keeps nested selectors under :slotted(...) targeting slotted content, even inside @media, @supports, and @container.
    • Current PostCSS path: Can lose that meaning inside nested at-rules and treat the nested rule like an ordinary local selector instead.
  • Split mixed slotted and local selector lists
    • @lightning-vue/compiler: For :slotted(.x), .y { .b {} }, the nested .b is emitted as a local descendant of .y. It does not also get a second slotted interpretation.
    • Current PostCSS path: Can blur those branches together. A single nested rule cannot safely mean two different things at once, so split the selector list when the slotted branch and the local branch need different output.
  • CSS Modules naming differs
    • @lightning-vue/compiler: Uses Lightning CSS's built-in [hash]_[local] pattern by default.
    • Current PostCSS path: Uses the @vue/compiler-sfc / postcss-modules default of _<local>_<hash>_<line>.
  • Mixed-case animation declarations still track local keyframes
    • @lightning-vue/compiler: Tracks renamed local @keyframes through declarations such as Animation: foo 1s and Animation-Name: foo.
    • Current PostCSS path: Still uses lowercase-only heuristics, so those valid mixed-case declarations can stop tracking the renamed local @keyframes.
  • Rare ambiguous animation shorthands follow CSS parsing
    • @lightning-vue/compiler: In ambiguous shorthands such as animation: paused foo 1s, it renames the actual keyframe name foo and leaves paused alone.
    • Current PostCSS path: In rare cases, still splits the shorthand into whitespace-separated tokens and rewrites the first token that matches a local @keyframes name. That can rename paused instead of foo, or rename ease in animation: ease 1s when ease is only a timing function.

Related Packages

  • @vue/compiler-sfc The default compiler-sfc package with the PostCSS-based style compiler.
  • @lightning-vue/utils Shared selector and source utilities used by this package’s style pipeline.

Dependency

This package requires lightningcss to be available in the dependency tree.