Programmatic API
Use design-token-lint as a library from Node.js — lint strings, files, or individual class names.
@zudolab/design-token-lint exports a small API for integration with build tools, editors, or custom tooling.
Installation
pnpm add @zudolab/design-token-lint
Exports
import {
// File/content linting
lintFile,
lintContent,
type LintResult,
// Single-class checking
checkClass,
checkClassWithConfig,
type Violation,
// Config loading and compilation
loadConfig,
compileConfig,
compilePattern,
setConfig,
getConfig,
DEFAULT_CONFIG,
type LintConfig,
type CompiledConfig,
type CompiledRule,
// Class extraction
extractClasses,
type ExtractedClass,
} from '@zudolab/design-token-lint';
Linting Files and Content
lintFile(filePath)
Read a file from disk and return an array of lint results — one entry per violation.
const results = await lintFile('src/App.tsx');
for (const r of results) {
console.log(`${r.filePath}:${r.line} ${r.className} ${r.reason}`);
}
Returns Promise<LintResult[]>:
interface LintResult {
filePath: string;
line: number;
className: string;
reason: string;
}
Each entry is a flat record for one violation. If the file has no violations, the returned array is empty.
lintContent(filePath, content)
Lint a string directly — useful for editor plugins or in-memory content. Returns LintResult[] (same shape as above).
const results = lintContent('file.tsx', '<div className="p-4 bg-gray-500">');
// [
// { filePath: 'file.tsx', line: 1, className: 'p-4', reason: '...' },
// { filePath: 'file.tsx', line: 1, className: 'bg-gray-500', reason: '...' }
// ]
Checking a Single Class
checkClass(className)
Check one class name against the active config. Returns a Violation if the class is prohibited, or null if it passes.
const violation = checkClass('p-4');
if (violation) {
console.error(violation.reason);
// "Numeric spacing \"p-4\" — use semantic token (hgap-*/vgap-*) or arbitrary value"
}
Returns Violation | null:
interface Violation {
className: string;
reason: string;
}
checkClassWithConfig(className, compiledConfig)
Same as above, but with an explicit compiled config instead of the global one.
import { loadConfig, compileConfig, checkClassWithConfig } from '@zudolab/design-token-lint';
const config = await loadConfig(process.cwd());
const compiled = compileConfig(config);
const violation = checkClassWithConfig('bg-blue-500', compiled);
Working with Config
loadConfig(cwd)
Load .design-token-lint.json or design-token-lint.config.json from a directory. Falls back to DEFAULT_CONFIG if neither exists.
const config = await loadConfig(process.cwd());
compileConfig(config)
Compile a plain config object into an efficient rule set ready for matching.
const compiled = compileConfig({
prohibited: ['p-{n}', 'bg-{color}-{shade}'],
allowed: ['p-0'],
ignore: [],
});
setConfig(compiled) / getConfig()
Set or get the global compiled config used by checkClass() and lintFile().
setConfig(compiled);
const active = getConfig();
compilePattern(pattern)
Compile a single pattern string (like p-{n}) into a CompiledRule.
const rule = compilePattern('bg-{color}-{shade}');
// { prefix: 'bg', valuePattern: /^(slate|gray|...)-(\d{2,3})$/, reasonTemplate: '...', isSpacingRule: false }
Extracting Classes
extractClasses(content)
Extract all class name tokens from a source file string, with their line numbers.
const extracted = extractClasses('<div className="p-4 bg-red-500">');
// [
// { className: 'p-4', line: 1 },
// { className: 'bg-red-500', line: 1 }
// ]
Returns ExtractedClass[]:
interface ExtractedClass {
className: string;
line: number;
}
Supported syntaxes:
className="..."andclass="..."(JSX/Astro)className={'...'}single-quote braceclassName={`...`}template literals (simple cases)class:list={["...", '...']}Astro class arrayscn(...),clsx(...),classNames(...),twMerge(...)utility calls
Types
LintConfig
interface LintConfig {
prohibited: string[];
allowed: string[];
ignore: string[];
patterns?: string[];
suggestionSuffix?: string;
}
LintResult
interface LintResult {
filePath: string;
line: number;
className: string;
reason: string;
}
Violation
interface Violation {
className: string;
reason: string;
}
Example: Custom Linter Script
import { glob } from 'glob';
import {
loadConfig,
compileConfig,
setConfig,
lintFile,
} from '@zudolab/design-token-lint';
async function main() {
const config = await loadConfig(process.cwd());
setConfig(compileConfig(config));
const files = await glob('src/**/*.{tsx,jsx}');
let totalViolations = 0;
for (const file of files) {
const results = await lintFile(file);
for (const r of results) {
console.log(`${r.filePath}:${r.line} ${r.className} ${r.reason}`);
totalViolations++;
}
}
process.exit(totalViolations > 0 ? 1 : 0);
}
main();