Ecosystem
Three bundler plugins. Same API surface. Same CSS output.
Lass ships official plugins for Vite, Bun, and Webpack. Each plugin follows the same pattern: intercept .lass imports, transpile to a JavaScript module via @lass-lang/core, execute the module to extract the CSS string, and hand the result to your bundler's CSS pipeline.
The output is always static CSS. No runtime. No client-side JavaScript.
Vite Plugin
@lass-lang/vite-plugin-lass — The flagship integration.
npm install @lass-lang/vite-plugin-lass --save-dev
// vite.config.js
import { defineConfig } from 'vite'
import lass from '@lass-lang/vite-plugin-lass'
export default defineConfig({
plugins: [lass()]
})
Key features:
- Hot Module Replacement — Edit a
.lassfile, see the change instantly. HMR works through Vite's standard CSS handling. - CSS Modules — Name your file
.module.lassand import scoped class names. - TypeScript-first — Preambles are TypeScript by default. Respects your
tsconfig.jsonwhen present. - Zero config — Works out of the box. One optional setting:
verbose: truefor debug logging.
How it works:
- Intercepts
.lassfile imports - Resolves
.lassto a virtual.cssmodule (e.g.,theme.lass->theme.css) - Transpiles via
@lass-lang/coreto a JavaScript module - Executes the JS module to extract the CSS string
- Returns CSS to Vite's pipeline for standard processing (PostCSS, minification, etc.)
Peer dependency: Vite 5 or 6.
Bun Plugin
@lass-lang/bun-plugin-lass — Native Bun integration.
bun add @lass-lang/bun-plugin-lass --dev
With Bun.build()
import lass from '@lass-lang/bun-plugin-lass'
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
plugins: [lass()],
})
With bunfig.toml (zero-config preload)
# bunfig.toml
preload = ["@lass-lang/bun-plugin-lass/preload"]
This registers the plugin globally — .lass imports work everywhere without explicit plugin configuration.
Key features:
- CSS Modules —
.module.lassfiles return scoped class name objects. - Preload mode — Register via
bunfig.tomlfor zero-config builds. - TypeScript-first — Same TypeScript-by-default behavior as all Lass plugins.
How it works:
- Hooks into Bun's
onResolve/onLoadplugin API - Transpiles
.lasssource to JS via@lass-lang/core - Executes JS to extract CSS string
- Returns CSS with
loader: "css"to Bun's CSS pipeline - For
.module.lass: resolves to a virtual.module.csspath for CSS Modules scoping
Limitation: Bun's plugin API doesn't support HMR. For development with hot reloading, use Vite with @lass-lang/vite-plugin-lass.
Peer dependency: Bun 1.0+.
Webpack Plugin
@lass-lang/webpack-plugin-lass — Webpack 5 loader and plugin.
npm install @lass-lang/webpack-plugin-lass css-loader mini-css-extract-plugin --save-dev
Plugin mode (recommended)
// webpack.config.js
const { LassPlugin } = require('@lass-lang/webpack-plugin-lass')
module.exports = {
plugins: [new LassPlugin()],
}
The plugin auto-configures module.rules — no manual loader setup needed.
Manual loader mode
For projects that need custom loader chains:
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.lass$/,
use: ['@lass-lang/webpack-plugin-lass'],
type: 'javascript/auto',
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [new MiniCssExtractPlugin()],
}
Key features:
- Auto-configuration —
LassPluginsets upmodule.rulesfor you. - CSS Modules —
.module.lassworks withcss-loader's module support. - Watch mode — Preamble imports are preserved in webpack's module graph for automatic rebuilds.
- TypeScript-first — Same default behavior as all Lass plugins.
How it works (Svelte-style pattern):
- First pass: Loader transpiles
.lassto JS, executes it to extract CSS - Caches the CSS and returns JS with a self-referencing inline
!=!import - Second pass: Loader returns cached CSS to webpack's CSS pipeline
- Preamble imports stay in the module graph for watch/rebuild support
Peer dependency: Webpack 5+.
Shared Plugin Utilities
All three plugins share common logic via @lass-lang/plugin-utils:
- tsconfig detection — Automatically finds and respects your
tsconfig.json - Script language mode — TypeScript by default; opt into JavaScript with
useJS: true - Consistent API — All plugins accept the same options (
verbose,useJS)
CLI
For standalone compilation outside of a bundler:
npm install @lass-lang/cli --save-dev
npx lass button.lass dist/button.css
npx lass src/styles/ --out dist/css/
The CLI uses the same @lass-lang/core transpiler as the bundler plugins. Same input, same output.
Comparison
| Vite | Bun | Webpack | |
|---|---|---|---|
| HMR | Yes | No | Watch mode |
| CSS Modules | .module.lass |
.module.lass |
.module.lass |
| TypeScript default | Yes | Yes | Yes |
| Zero-config | lass() |
bunfig.toml preload |
new LassPlugin() |
| Peer dep | Vite 5/6 | Bun 1.0+ | Webpack 5+ |
Links
- Home
- Getting Started
- Tooling — VS Code, syntax highlighting
- Examples