buildDesignSystem() — tailwindcss Function Reference
Architecture documentation for the buildDesignSystem() function in design-system.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD c58d3214_88d6_f4fc_257f_8e84def5b24f["buildDesignSystem()"] 4c60082f_bdd8_b54c_8ccf_5b91632a61f0["run()"] 4c60082f_bdd8_b54c_8ccf_5b91632a61f0 -->|calls| c58d3214_88d6_f4fc_257f_8e84def5b24f 95cb326e_6b59_0903_0c96_d221fca5c2b1["parseCss()"] 95cb326e_6b59_0903_0c96_d221fca5c2b1 -->|calls| c58d3214_88d6_f4fc_257f_8e84def5b24f 36ae79a2_b20d_13c7_4f6b_8f43bb0d702f["loadDesignSystem()"] 36ae79a2_b20d_13c7_4f6b_8f43bb0d702f -->|calls| c58d3214_88d6_f4fc_257f_8e84def5b24f 4bf69ed2_937e_8db8_e3d5_dbd0af3cc6e4["simpleDesign()"] 4bf69ed2_937e_8db8_e3d5_dbd0af3cc6e4 -->|calls| c58d3214_88d6_f4fc_257f_8e84def5b24f 5bfda0d1_a765_b197_276f_df569264ec01["createUtilities()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 5bfda0d1_a765_b197_276f_df569264ec01 c067616f_e276_458d_2166_c9f10e6fcc93["createVariants()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| c067616f_e276_458d_2166_c9f10e6fcc93 ceb1ff41_a641_27dd_6289_7f779710b411["parseVariant()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| ceb1ff41_a641_27dd_6289_7f779710b411 0bec5ca9_74c8_dcc7_ec12_6404fb6493bd["parseCandidate()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 0bec5ca9_74c8_dcc7_ec12_6404fb6493bd 70b7448d_fd76_0d4b_e635_18f49f8ba1d6["compileAstNodes()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 70b7448d_fd76_0d4b_e635_18f49f8ba1d6 957946b3_94ca_8f71_30eb_76a6281c51df["theme()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 957946b3_94ca_8f71_30eb_76a6281c51df 6896eab3_60a4_7b0f_937b_8de4f4e9fe5a["substituteFunctions()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 6896eab3_60a4_7b0f_937b_8de4f4e9fe5a 101ae1c2_eee3_3589_2aa3_922a6a429d4f["substituteAtVariant()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 101ae1c2_eee3_3589_2aa3_922a6a429d4f 6dbfaefd_8d1b_d78e_592a_db6ff37aec55["extractUsedVariables()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 6dbfaefd_8d1b_d78e_592a_db6ff37aec55 7b01a3a8_8970_30d2_152f_715f03247ba2["markUsedVariable()"] c58d3214_88d6_f4fc_257f_8e84def5b24f -->|calls| 7b01a3a8_8970_30d2_152f_715f03247ba2 style c58d3214_88d6_f4fc_257f_8e84def5b24f fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/design-system.ts lines 70–255
export function buildDesignSystem(
theme: Theme,
utilitiesSrc?: SourceLocation | undefined,
): DesignSystem {
let utilities = createUtilities(theme)
let variants = createVariants(theme)
let parsedVariants = new DefaultMap((variant) => parseVariant(variant, designSystem))
let parsedCandidates = new DefaultMap((candidate) =>
Array.from(parseCandidate(candidate, designSystem)),
)
let compiledAstNodes = new DefaultMap<number>((flags) => {
return new DefaultMap<Candidate>((candidate) => {
let ast = compileAstNodes(candidate, designSystem, flags)
try {
// Arbitrary values (`text-[theme(--color-red-500)]`) and arbitrary
// properties (`[--my-var:theme(--color-red-500)]`) can contain function
// calls so we need evaluate any functions we find there that weren't in
// the source CSS.
substituteFunctions(
ast.map(({ node }) => node),
designSystem,
)
// JS plugins might contain an `@variant` inside a generated utility
substituteAtVariant(
ast.map(({ node }) => node),
designSystem,
)
} catch (err) {
// If substitution fails then the candidate likely contains a call to
// `theme()` that is invalid which may be because of incorrect usage,
// invalid arguments, or a theme key that does not exist.
return []
}
return ast
})
})
let trackUsedVariables = new DefaultMap((raw) => {
for (let variable of extractUsedVariables(raw)) {
theme.markUsedVariable(variable)
}
})
function candidatesToAst(classes: string[]): AstNode[][] {
let result: AstNode[][] = []
for (let className of classes) {
let wasValid = true
let { astNodes } = compileCandidates([className], designSystem, {
onInvalidCandidate() {
wasValid = false
},
})
if (utilitiesSrc) {
walk(astNodes, (node) => {
// We do this conditionally to preserve source locations from both
// `@utility` and `@custom-variant`. Even though generated nodes are
// cached this should be fine because `utilitiesNode.src` should not
// change without a full rebuild which destroys the cache.
node.src ??= utilitiesSrc
return WalkAction.Continue
})
}
// Disable all polyfills to not unnecessarily pollute IntelliSense output
astNodes = optimizeAst(astNodes, designSystem, Polyfills.None)
result.push(wasValid ? astNodes : [])
}
return result
}
function candidatesToCss(classes: string[]): (string | null)[] {
return candidatesToAst(classes).map((nodes) => {
return nodes.length > 0 ? toCss(nodes) : null
})
}
let designSystem: DesignSystem = {
theme,
utilities,
variants,
invalidCandidates: new Set(),
important: false,
candidatesToCss,
candidatesToAst,
getClassOrder(classes) {
return getClassOrder(this, classes)
},
getClassList() {
return getClassList(this)
},
getVariants() {
return getVariants(this)
},
parseCandidate(candidate: string) {
return parsedCandidates.get(candidate)
},
parseVariant(variant: string) {
return parsedVariants.get(variant)
},
compileAstNodes(candidate: Candidate, flags = CompileAstFlags.RespectImportant) {
return compiledAstNodes.get(flags).get(candidate)
},
printCandidate(candidate: Candidate) {
return printCandidate(designSystem, candidate)
},
printVariant(variant: Variant) {
return printVariant(variant)
},
getVariantOrder() {
let variants = Array.from(parsedVariants.values())
variants.sort((a, z) => this.variants.compare(a, z))
let order = new Map<Variant, number>()
let prevVariant: Variant | undefined = undefined
let index: number = 0
for (let variant of variants) {
if (variant === null) {
continue
}
// This variant is not the same order as the previous one
// so it goes into a new group
if (prevVariant !== undefined && this.variants.compare(prevVariant, variant) !== 0) {
index++
}
order.set(variant, index)
prevVariant = variant
}
return order
},
resolveThemeValue(path: `${ThemeKey}` | `${ThemeKey}${string}`, forceInline: boolean = true) {
// Extract an eventual modifier from the path. e.g.:
// - "--color-red-500 / 50%" -> "50%"
let lastSlash = path.lastIndexOf('/')
let modifier: string | null = null
if (lastSlash !== -1) {
modifier = path.slice(lastSlash + 1).trim()
path = path.slice(0, lastSlash).trim() as ThemeKey
}
let themeValue =
theme.resolve(null, [path], forceInline ? ThemeOptions.INLINE : ThemeOptions.NONE) ??
undefined
// Apply the opacity modifier if present
if (modifier && themeValue) {
return withAlpha(themeValue, modifier)
}
return themeValue
},
trackUsedVariables(raw: string) {
trackUsedVariables.get(raw)
},
canonicalizeCandidates(candidates: string[], options?: CanonicalizeOptions) {
return canonicalizeCandidates(this, candidates, options)
},
// General purpose storage, each key has to be a unique symbol to avoid
// collisions.
storage: {},
}
return designSystem
}
Domain
Subdomains
Calls
- compare()
- compileAstNodes()
- compileCandidates()
- createUtilities()
- createVariants()
- extractUsedVariables()
- get()
- getClassList()
- getClassOrder()
- getVariants()
- markUsedVariable()
- optimizeAst()
- parseCandidate()
- parseVariant()
- printCandidate()
- printVariant()
- resolve()
- set()
- substituteAtVariant()
- substituteFunctions()
- theme()
- toCss()
- walk()
- withAlpha()
Source
Frequently Asked Questions
What does buildDesignSystem() do?
buildDesignSystem() is a function in the tailwindcss codebase.
What does buildDesignSystem() call?
buildDesignSystem() calls 24 function(s): compare, compileAstNodes, compileCandidates, createUtilities, createVariants, extractUsedVariables, get, getClassList, and 16 more.
What calls buildDesignSystem()?
buildDesignSystem() is called by 4 function(s): loadDesignSystem, parseCss, run, simpleDesign.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free