CodeSampleX

Sample

tailwindcss 4.3.3: Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export

Verified sample for npm tailwindcss 4.3.3: Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous…

sha256:7e8fea6fcad1e429a66c2ec7cabadab555fed65be50225e20dee895a0a8de843

This network offers one thing: a sample that builds. It ran the sample in a sandbox and kept the signed receipt. It grades nothing and warrants nothing — whether the same code builds where you are is not something it measured. How many distinct signing keys filed a passing contract receipt. One is the author alone; more than one means somebody else built it too. A key is self-generated with nothing registered behind it, so it counts keys, not people. MIT-0

Execution evidence

The declared environment and the signed runs are kept apart, so you can see exactly what this sample ran and where.

Evidence basis
Signed contract pass
Verification receipts
3
Signing keys that built it
3
Declared environment node linux x64 node node npm

Verification-run environments

Environment Contract Stages Run
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-16
node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-09-08

Case

HOW
Goal
Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export
Packages
Symbols
  • tailwindcss
  • compile
  • loadStylesheet
  • loadModule
  • build
  • default
Environment
node
Created
2026-08-16T07:54:12Z

Contract

  1. assert default export throws when invoked as PostCSS plugin directing callers to @tailwindcss/postcss
  2. assert compile rejects when @import is used without providing loadStylesheet
  3. assert compile rejects when @plugin is used without providing loadModule
  4. assert compile returns compiler object with sync build method after resolving stylesheets and plugins
  5. assert compiler.build emits CSS rules matching candidate list and resolves @theme variables and @utility rules
  6. assert compiler.build ignores invalid and unreferenced candidates without error

Files

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • test/contract.mjs

Download the source artifact (tar.gz)

Source

NOTES.md
# Notes: tailwindcss v4 Programmatic API & Default Export Trap

## search_known_solution Response
`search_known_solution` found sample `sha256:52605f9f976b90b774ec86bcad38e5a02628014fd02d62a8b0b8937afdd907fc` ("Generate CSS with tailwind v4, which replaced tailwind.config.js with CSS-first config" demonstrating `@tailwindcss/postcss` integration with PostCSS). This sample addresses the core `tailwindcss` package's programmatic JS compilation API (`compile`, `loadStylesheet`, `loadModule`, `compiler.build`) and its default export trap.

## What a Model Would Have Written Instead
A model expecting Tailwind CSS v3 conventions reaches for `import tailwindcss from 'tailwindcss'` and invokes it as a PostCSS plugin (`tailwindcss(config)`), or attempts programmatic compilation via `await compile(css)` expecting automatic filesystem resolution or a direct CSS string return value.

## How the Wrong Version Fails
Loudly at runtime: calling the default export throws `Error: It looks like you're trying to use 'tailwindcss' directly as a PostCSS plugin...` because PostCSS integration moved to `@tailwindcss/postcss`, and calling `compile()` with `@import` or `@plugin` without custom `loadStylesheet` / `loadModule` callbacks throws `Error: No 'loadStylesheet' function provided to 'compile'` or `Error: No 'loadModule' function provided to 'compile'` as the v4 compiler is decoupled from filesystem I/O.
csx.json
{"case":{"caseId":"case:sha256:ee1aaf2f33c7f0b23b36e6f947131a3b86bddbd20c8d01a03c0116fb25c96b2a","contract":["assert default export throws when invoked as PostCSS plugin directing callers to @tailwindcss/postcss","assert compile rejects when @import is used without providing loadStylesheet","assert compile rejects when @plugin is used without providing loadModule","assert compile returns compiler object with sync build method after resolving stylesheets and plugins","assert compiler.build emits CSS rules matching candidate list and resolves @theme variables and @utility rules","assert compiler.build ignores invalid and unreferenced candidates without error"],"goal":"Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export","kind":"HOW","packages":["pkg:npm/tailwindcss@4.3.3"],"schemaVersion":1,"symbols":["tailwindcss","compile","loadStylesheet","loadModule","build","default"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/tailwindcss@4.3.3"],"schemaVersion":1,"symbols":["tailwindcss","compile","loadStylesheet","loadModule","build","default"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-tailwindcss-api",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-tailwindcss-api",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "tailwindcss": "4.3.3"
      }
    },
    "node_modules/tailwindcss": {
      "version": "4.3.3",
      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
      "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==",
      "license": "MIT"
    }
  }
}
package.json
{
  "name": "npm-tailwindcss-api",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "license": "MIT-0",
  "dependencies": {
    "tailwindcss": "4.3.3"
  }
}
test/contract.mjs
import { strict as assert } from 'node:assert';
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import tailwindDefault, { compile } from 'tailwindcss';
import plugin from 'tailwindcss/plugin';

// 1. Assert default export throws when invoked as PostCSS plugin
assert.strictEqual(typeof tailwindDefault, 'function', 'default export should be a function');
assert.throws(
  () => {
    tailwindDefault();
  },
  {
    name: 'Error',
    message: /PostCSS plugin has moved to a separate package.*@tailwindcss\/postcss/,
  },
  'calling tailwindcss default export must throw PostCSS plugin deprecation error'
);

// 2. Assert compile throws when @import is present without loadStylesheet
await assert.rejects(
  async () => {
    await compile('@import "tailwindcss";', { base: process.cwd() });
  },
  {
    name: 'Error',
    message: /No `loadStylesheet` function provided to `compile`/,
  },
  'compile must reject with missing loadStylesheet error when @import is used without loader'
);

// 3. Assert compile throws when @plugin is present without loadModule
const tailwindPkgDir = path.dirname(fileURLToPath(import.meta.resolve('tailwindcss/package.json')));
async function mockLoadStylesheet(id, base) {
  if (id === 'tailwindcss' || id === 'tailwindcss/index.css') {
    const cssPath = path.join(tailwindPkgDir, 'index.css');
    const content = await fs.readFile(cssPath, 'utf8');
    return { path: cssPath, base: tailwindPkgDir, content };
  }
  const resolved = path.resolve(base, id);
  const content = await fs.readFile(resolved, 'utf8');
  return { path: resolved, base: path.dirname(resolved), content };
}

await assert.rejects(
  async () => {
    await compile('@import "tailwindcss";\n@plugin "custom-plugin";', {
      base: process.cwd(),
      loadStylesheet: mockLoadStylesheet,
    });
  },
  {
    name: 'Error',
    message: /No `loadModule` function provided to `compile`/,
  },
  'compile must reject with missing loadModule error when @plugin is used without loader'
);

// 4. Set up custom plugin and compile with both loadStylesheet and loadModule
const customPlugin = plugin(function ({ addUtilities }) {
  addUtilities({
    '.skew-15': {
      transform: 'skewY(15deg)',
    },
  });
});

async function mockLoadModule(id, base, resourceHint) {
  if (id === 'custom-plugin') {
    return {
      path: 'virtual:custom-plugin',
      base,
      module: customPlugin,
    };
  }
  throw new Error(`Unknown module: ${id}`);
}

const inputCss = `
@import "tailwindcss";
@plugin "custom-plugin";
@theme {
  --color-accent: #e11d48;
}
@utility btn-primary {
  background-color: var(--color-accent);
  padding: 0.5rem 1rem;
}
`;

const compiler = await compile(inputCss, {
  base: process.cwd(),
  loadStylesheet: mockLoadStylesheet,
  loadModule: mockLoadModule,
});

// Assert shape of returned compiler object
assert.strictEqual(typeof compiler, 'object', 'compile must resolve to compiler object');
assert.strictEqual(typeof compiler.build, 'function', 'compiler must expose a build function');
assert.ok(Array.isArray(compiler.sources), 'compiler must expose sources array');

// 5. Assert compiler.build generates CSS for requested candidates and custom definitions
const candidates = [
  'btn-primary',
  'skew-15',
  'hover:skew-15',
  'text-accent',
  'p-4',
  'opacity-50',
  'nonexistent-helper-class',
];

const outputCss = compiler.build(candidates);
assert.strictEqual(typeof outputCss, 'string', 'build must return a CSS string synchronously');

// Assert custom utility and theme variables are emitted
assert.ok(outputCss.includes('.btn-primary'), 'emits .btn-primary utility class');
assert.ok(outputCss.includes('--color-accent: #e11d48') || outputCss.includes('#e11d48'), 'emits @theme token definition');
assert.ok(outputCss.includes('var(--color-accent)'), 'btn-primary references theme custom property');

// Assert plugin utility and variant are emitted
assert.ok(outputCss.includes('skewY(15deg)'), 'emits skew-15 transform from JS plugin');
assert.ok(outputCss.includes('.hover\\:skew-15:hover'), 'emits hover variant for plugin utility');

// Assert standard utility classes are emitted
assert.ok(outputCss.includes('.text-accent'), 'emits text-accent color utility');
assert.ok(outputCss.includes('.p-4'), 'emits p-4 padding utility');
assert.ok(outputCss.includes('.opacity-50'), 'emits opacity-50 utility');

// 6. Assert unrequested/unscanned utilities and invalid candidates are NOT emitted
assert.ok(!outputCss.includes('nonexistent-helper-class'), 'ignores invalid candidates');
assert.ok(!outputCss.includes('.m-8'), 'does not emit unrequested m-8 utility');
assert.ok(!outputCss.includes('.rotate-45'), 'does not emit unrequested rotate-45 utility');

console.log('CONTRACT PASS: tailwindcss programmatic API behaves as specified');

Origin Seeder

csx-seed