LunarCSS

PostCSS Web Plugin

Reads lunar.config.ts at build time and emits @theme {} for Tailwind v4.

Overview

The lunarcss PostCSS plugin reads lunar.config.ts via jiti and emits an @theme { ... } block directly before @import "tailwindcss". This makes your custom tokens available as Tailwind CSS variables at compile time.

Setup

// postcss.config.js
module.exports = {
  plugins: {
    '@tailwindcss/postcss': {},
    '@lunar-kit/css': {},
  },
}

Your entry CSS file:

/* app/globals.css */
@import "tailwindcss";
@plugin "@lunar-kit/css";

Options

const lunarcss = require('@lunar-kit/css/web/plugin')

module.exports = {
  plugins: [
    require('@tailwindcss/postcss'),
    lunarcss({
      configFile: '/abs/path/to/lunar.config.ts',  // override discovery
      projectRoot: process.cwd(),                   // override cwd
      passthrough: false,                           // run but emit nothing (debug)
    }),
  ],
}

What gets emitted

Input:

/* LunarCSS */
@import "tailwindcss";
@plugin "@lunar-kit/css";

Output (with colors.primary = '#6366f1', spacing.xs = '4px'):

/* LunarCSS */
/* lunarcss:emitted */
@theme {
  --color-primary: #6366f1;
  --spacing-xs: 4px
}
@import "tailwindcss";
@plugin "@lunar-kit/css";

Tokens are sorted alphabetically. The /* lunarcss:emitted */ marker prevents double injection on re-runs.

Injection target

  • If @import "tailwindcss" is found → @theme {} is inserted directly before it
  • If only @plugin "@lunar-kit/css" is found → @theme {} is prepended to the root
  • If neither is found → plugin skips the file entirely (avoids polluting unrelated stylesheets)

Hot-reload

The plugin pushes a type: 'dependency' PostCSS message pointing at lunar.config.ts. Next.js, Vite, and Webpack honor this — editing lunar.config.ts automatically re-runs PostCSS on dependent CSS files.

jiti runs with moduleCache: false and fsCache: false — no stale config across reads.

Idempotency

Re-running PostCSS on already-emitted output is a no-op — the /* lunarcss:emitted */ marker short-circuits injection.

Next.js example

npx lunar-css init   # generates globals.css + updates postcss.config.js

Or manually:

  1. app/globals.css:
@import "tailwindcss";
@plugin "@lunar-kit/css";
  1. app/layout.tsx:
import './globals.css'
  1. postcss.config.js:
module.exports = {
  plugins: {
    '@tailwindcss/postcss': {},
    '@lunar-kit/css': {},
  },
}

On this page