Node.js-specific utilities and runtime functionality for Tailwind CSS v4, providing compilation tools, module dependency analysis, source map handling, path normalization, and optimization utilities.
Comprehensive source map generation, manipulation, and serialization with inline embedding support for debugging workflows. Provides utilities for converting between different source map formats and generating inline source map comments.
Converts source maps to a standardized format with both raw and inline representations.
/**
* Converts a source map to standardized format with inline support
* @param map - Source map as decoded object or JSON string
* @returns SourceMap object with raw and inline representations
*/
function toSourceMap(map: DecodedSourceMap | string): SourceMap;
interface SourceMap {
/** Raw source map as JSON string */
readonly raw: string;
/** Inline source map comment for embedding in CSS/JS */
readonly inline: string;
}Usage Examples:
import { toSourceMap } from "@tailwindcss/node";
// Convert from JSON string
const sourceMapJson = JSON.stringify({
version: 3,
sources: ["input.css"],
names: [],
mappings: "AAAA,UAAU,CAAC,KAAK,CAAC"
});
const sourceMap = toSourceMap(sourceMapJson);
console.log(sourceMap.raw); // Original JSON string
console.log(sourceMap.inline); // /*# sourceMappingURL=data:application/json;base64,... */
// Convert from decoded source map
const decodedMap: DecodedSourceMap = {
mappings: [
{
generatedPosition: { line: 1, column: 0 },
originalPosition: {
line: 1,
column: 0,
source: { url: "input.css", content: ".container { color: red; }" }
}
}
]
};
const convertedMap = toSourceMap(decodedMap);
console.log(convertedMap.raw);The inline source map format is ready for direct embedding in CSS or JavaScript files:
import { toSourceMap, optimize } from "@tailwindcss/node";
const css = ".container { display: flex; }";
const optimized = optimize(css, {
minify: true,
file: "styles.css"
});
if (optimized.map) {
const sourceMap = toSourceMap(optimized.map);
// Embed inline source map
const cssWithSourceMap = optimized.code + "\n" + sourceMap.inline;
console.log(cssWithSourceMap);
// Output:
// .container{display:flex}
// /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLC... */
}Represents a decoded source map with detailed mapping information.
interface DecodedSourceMap {
/** Array of source mappings between generated and original positions */
mappings: Array<{
/** Position in generated file */
generatedPosition: { line: number; column: number };
/** Position in original file (if available) */
originalPosition?: {
line: number;
column: number;
source: DecodedSource
};
/** Original identifier name (if available) */
name?: string;
}>;
}Represents source file information within a source map.
interface DecodedSource {
/** URL or path to the source file */
url: string;
/** Original source file content */
content: string;
}import { toSourceMap, type DecodedSourceMap, type DecodedSource } from "@tailwindcss/node";
// Create a complex source map with multiple sources
const mainSource: DecodedSource = {
url: "components/button.css",
content: ".btn { padding: 0.5rem; }"
};
const utilitySource: DecodedSource = {
url: "utilities/spacing.css",
content: ".p-2 { padding: 0.5rem; }"
};
const complexMap: DecodedSourceMap = {
mappings: [
{
generatedPosition: { line: 1, column: 0 },
originalPosition: {
line: 1,
column: 0,
source: mainSource
}
},
{
generatedPosition: { line: 2, column: 0 },
originalPosition: {
line: 1,
column: 0,
source: utilitySource
},
name: "utility-class"
}
]
};
const sourceMap = toSourceMap(complexMap);
console.log(sourceMap.raw);The internal serialization process handles source deduplication and proper formatting:
import { toSourceMap } from "@tailwindcss/node";
// Sources are automatically deduplicated and assigned unique URLs
const mapWithDuplicates: DecodedSourceMap = {
mappings: [
{
generatedPosition: { line: 1, column: 0 },
originalPosition: {
line: 1,
column: 0,
source: { url: "same.css", content: "content" }
}
},
{
generatedPosition: { line: 2, column: 0 },
originalPosition: {
line: 2,
column: 0,
source: { url: "same.css", content: "content" } // Same source
}
}
]
};
const result = toSourceMap(mapWithDuplicates);
// Sources are properly deduplicated in the outputThe system gracefully handles mappings with missing source information:
import { toSourceMap, type DecodedSourceMap } from "@tailwindcss/node";
const mapWithMissingSources: DecodedSourceMap = {
mappings: [
{
generatedPosition: { line: 1, column: 0 },
// No originalPosition - generates placeholder
},
{
generatedPosition: { line: 2, column: 0 },
originalPosition: {
line: 1,
column: 0,
source: null as any // Missing source
}
}
]
};
const result = toSourceMap(mapWithMissingSources);
// Missing sources get placeholder names like "<unknown 1>"import { toSourceMap } from "@tailwindcss/node";
// In a webpack loader
module.exports = function(source: string) {
const callback = this.async();
// Process CSS...
const processed = processCss(source);
if (processed.map) {
const sourceMap = toSourceMap(processed.map);
callback(null, processed.code, JSON.parse(sourceMap.raw));
} else {
callback(null, processed.code);
}
};import { toSourceMap } from "@tailwindcss/node";
// In a Vite plugin
export function tailwindNodePlugin() {
return {
name: "tailwind-node",
transform(code: string, id: string) {
if (id.endsWith(".css")) {
const result = processCss(code);
if (result.map) {
const sourceMap = toSourceMap(result.map);
return {
code: result.code,
map: JSON.parse(sourceMap.raw)
};
}
return { code: result.code };
}
}
};
}The generated source maps are fully compatible with browser developer tools:
import { toSourceMap } from "@tailwindcss/node";
const sourceMap = toSourceMap(map);
// The inline format is automatically recognized by browsers
const cssWithMap = cssCode + "\n" + sourceMap.inline;
// Or use external source map file
const externalMapUrl = "/*# sourceMappingURL=styles.css.map */";
const cssWithExternal = cssCode + "\n" + externalMapUrl;
// Write the source map file
fs.writeFileSync("styles.css.map", sourceMap.raw);tessl i tessl/npm-tailwindcss--node@4.1.0docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10