Getting Started

CLI

npm install @lass-lang/cli
npx lass input.lass -o output.css
npx lass src/styles --outdir dist/css

Vite

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()],
});

Bun

bun add @lass-lang/bun-plugin-lass --dev
// build.js
import lass from '@lass-lang/bun-plugin-lass';

Bun.build({
  entrypoints: ['./src/index.ts'],
  plugins: [lass()],
});

Script Language Mode (JavaScript vs TypeScript)

Lass Script Preambles run as TypeScript by default (first-class citizen). JavaScript mode requires explicit opt-in.

Default Behavior: TypeScript First

TypeScript mode is always the default, regardless of project configuration:

Override to JavaScript Mode

Explicitly opt into JavaScript mode via bundler config:

// vite.config.js
import lass from '@lass-lang/vite-plugin-lass'

export default {
  plugins: [
    lass({ useJS: true })  // Opt into JavaScript mode
  ]
}
// bun build.js
import lass from '@lass-lang/bun-plugin-lass'

Bun.build({
  entrypoints: ['./src/index.ts'],
  plugins: [
    lass({ useJS: true })  // Opt into JavaScript mode
  ]
})

When to Use JavaScript Mode

Best Practice

Don't set useJS at all. Let Lass use the default (TypeScript). If your project has tsconfig.json, you'll get type-checking automatically.

IDE Support

IDE extensions (VS Code, WebStorm, etc.) provide IntelliSense and type-checking for the Script Preamble.

Detection logic:

  1. Check bundler config file (vite.config.* or bunfig.toml)
  2. If lass() plugin found: read useJS option (default: false)
  3. If no lass() plugin or no useJS option: TypeScript mode (first citizen)

This keeps bundler and IDE behavior synchronized automatically.

Your First .lass File

Create a file with the .lass extension. Lass files are just CSS - write styles exactly as you would in a .css file:

:root {
  --color-primary: #6366f1;
  --color-secondary: #8b5cf6;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
}

.button {
  background: var(--color-primary);
  color: white;
  padding: 0.75rem 1.25rem;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
}

.button:hover {
  background: var(--color-secondary);
}
:root {
  --color-primary: #6366f1;
  --color-secondary: #8b5cf6;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
}

.button {
  background: var(--color-primary);
  color: white;
  padding: 0.75rem 1.25rem;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
}

.button:hover {
  background: var(--color-secondary);
}

That's it! Any valid CSS works in a .lass file.

Importing in Your App

Import .lass files just like CSS:

// src/main.js
import './styles/theme.lass';

// Your app code...
document.querySelector('#app').innerHTML = `
  <div class="container">
    <button class="button">Click me</button>
  </div>
`;

Start the dev server:

npm run dev

Your Lass styles are now active. Edit the .lass file and see changes reflected instantly via Vite's HMR.

Adding TypeScript Power

Want to do more? Add a TypeScript preamble before a --- separator to unlock the full power of Lass:

---
const primary = '#6366f1';
const secondary = '#8b5cf6';
const spacing = (n) => `${n * 0.25}rem`;

---

:root {
  --color-primary: {{ primary }};
  --color-secondary: {{ secondary }};
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: {{ spacing(4) }} {{ spacing(6) }};
}

.button {
  background: {{ primary }};
  color: white;
  padding: {{ spacing(3) }} {{ spacing(5) }};
  border: none;
  border-radius: {{ spacing(2) }};
  cursor: pointer;
}

.button:hover {
  background: {{ secondary }};
}

:root {
  --color-primary: #6366f1;
  --color-secondary: #8b5cf6;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
}

.button {
  background: #6366f1;
  color: white;
  padding: 0.75rem 1.25rem;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
}

.button:hover {
  background: #8b5cf6;
}

The preamble lets you:

Everything compiles to static CSS at build time - zero runtime overhead. TypeScript types are optional (gradual typing).

TypeScript Support

For TypeScript projects, add type declarations so the compiler recognizes .lass imports.

Create src/lass.d.ts:

// src/lass.d.ts

// Side-effect imports (import './styles.lass')
declare module '*.lass';

// CSS Modules (import styles from './component.module.lass')
declare module '*.module.lass' {
  const classes: { readonly [key: string]: string };
  export default classes;
}

Ensure this file is included in your tsconfig.json:

{
  "include": ["src/**/*.ts", "src/**/*.d.ts"]
}

CSS Modules

Use .module.lass for scoped class names:

---
const shadow = '0 4px 6px -1px rgb(0 0 0 / 0.1)';

---

.card {
  background: white;
  border-radius: 8px;
  box-shadow: {{ shadow }};
  padding: 1.5rem;
}

.title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
  padding: 1.5rem;
}

.title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

Import with a default import to get scoped class names:

// src/components/Card.ts
import styles from './Card.module.lass';

const card = document.createElement('div');
card.className = styles.card;  // Scoped class name

const title = document.createElement('h2');
title.className = styles.title;

Common Pitfalls

Wrong Package Name

Use the scoped package name:

# Correct
npm install @lass-lang/vite-plugin-lass --save-dev

# Wrong - these packages don't exist
npm install vite-plugin-lass
npm install lass

Forgot to Add Plugin

If .lass files aren't being processed, check that the plugin is added to your Vite config:

// vite.config.js
import lass from '@lass-lang/vite-plugin-lass';

export default defineConfig({
  plugins: [lass()],  // Don't forget this!
});

Missing TypeScript Declarations

If TypeScript complains about .lass imports:

Cannot find module './styles.lass' or its corresponding type declarations.

Create src/lass.d.ts with the declarations shown in the TypeScript Support section.

Expression vs Substitution

Use {{ }} for expressions (computed at build time):

---
const size = 16;

---

.text {
  font-size: {{ size }}px;
  line-height: {{ size * 2 }}px;
}

.text {
  font-size: 16px;
  line-height: 32px;
}

Use $name for simple text substitution (no computation). Variables must be $-prefixed:

---
const $unit = 'rem';

---

.box {
  margin: 1$unit;
}

.box {
  margin: 1rem;
}

Preamble Must Come First

When using JavaScript, the preamble must come before the --- separator:

---
const color = 'blue';

---

.box { color: {{ color }}; }

.box { color: blue; }

Without a preamble, you don't need a separator at all - just write CSS directly.

What's Next

You now have Lass running in your project. Explore more:


Back to Home | Next: Syntax Reference