Configuration
Maple does not use configuration files. Runtime options are passed through the script URL, so the same engine can be tuned for custom breakpoints, reference caching, class merging, cascade priority, debug warnings, and dark mode behavior without adding a build step.
Script Query String
Add configuration parameters to the Maple script src as a standard query string. Boolean options only need the parameter name, while breakpoint options use name=value.
<script src="maple.js?refs&nomerge&md=680px&4xl=1920px"></script>
refsEnables global reference variables for generated values.
Large pages or applications reuse many of the same utilities.
nomergeDisables runtime utility conflict cleanup.
Your class strings are already clean and you want less runtime work.
nohybridDisables hybrid dark mode rule generation.
You want @dark: to generate media-query rules only.
important Marks every generated declaration !important.
You are retrofitting Maple onto a site with existing unlayered CSS.
debugLogs console warnings for classes and aliases that silently produce no styles.
You are in development and need to know why a class is not applying.
{breakpoint}={value}Overrides or adds a named breakpoint.
Your design system needs different responsive thresholds.
Load Order Still Matters
<head>. Do not add async, defer, or type="module", because the browser may render elements before Maple has generated their styles. Custom Breakpoints
Breakpoint parameters let you override Maple's defaults or introduce new names. The configured name becomes available anywhere a Maple breakpoint can be used, including container queries and viewport queries.
<!-- Override defaults and add a custom 4xl breakpoint -->
<script src="maple.js?sm=480px&md=680px&lg=960px&4xl=1920px"></script>
<!-- Use the configured breakpoint -->
<div class="@4xl:cols-4">
4 columns at 1920px and above
</div>
After configuration, the breakpoint name is used exactly like any other media prefix. For example, @4xl:cols-4 targets a viewport at 1920px and above, while 4xl:cols-4 targets the nearest container at that same threshold.
Container First
@ prefix when you want a viewport media query instead of a container query. Nomerge Mode
Utility classes often have the same specificity. When two classes target the same CSS property, the browser does not use the order of the classes in the class attribute to decide the winner. It uses the order of the generated CSS rules. Maple's merger keeps the class string as the source of truth by resolving conflicts in class order before those equal-specificity rules can become ambiguous.
For example, p-4 p-8 expresses a clear intent: p-8 should win because it comes later. By default, Maple applies that last-one-wins behavior and removes the overridden utility from the DOM.
<!-- Disable conflict cleanup -->
<script src="maple.js?nomerge"></script>
<!-- With default merging, p-4 is removed and p-8 wins always. -->
<div class="p-4 p-8">
With nomerge, both classes stay in the DOM.
The browser uses CSS rule order, not this class order.
For example, if .p-8 is generated previously by another element, .p-4 wins.
</div>
Maple calculates utility conflicts, applies last-one-wins behavior, and cleans overridden classes from the element.
Specificity stays predictable because the class string order decides conflicts between equivalent utilities.
nomergeMaple leaves class attributes untouched and skips the conflict cleanup pass.
Conflicting utilities remain in place, so the browser cascade may choose based on CSS generation order instead of class string order.
Use nomerge when your class strings are generated in a controlled way and you are confident they do not contain conflicting utilities. It can reduce initial runtime work, but the cost is that Maple no longer protects you from equal-specificity conflicts, duplicated utilities, or class lists whose visible order does not match the final style.
Global Important Mode
Maple generates its rules inside CSS cascade layers, and unlayered CSS always beats layered CSS. On a page that already ships an unlayered stylesheet, such as a WordPress theme or a legacy CSS file, Maple utilities silently lose for every property that stylesheet already sets. The per-utility ! prefix fixes this case by case, but prefixing every class is impractical when retrofitting Maple onto an existing site.
Add important to the script query string to mark every generated declaration !important globally. The per-utility ! prefix keeps working and produces the same output.
<!-- Mark every generated declaration !important -->
<script src="maple.js?important"></script>
<!-- Wins over an unlayered legacy stylesheet without a per-class prefix -->
<div class="bgc-accent-500 p-4">
background-color and padding are both generated as !important
</div>
Inline Styles Lose Too
!important declaration also outranks a plain inline style, so utilities start overriding values that third-party scripts write to element.style, such as positioning for a tooltip or a carousel. Only an inline !important still wins. On greenfield projects the cascade already resolves correctly, so leave the flag off. Debug Mode
By default, Maple stays silent when a class produces no styles. An invalid utility, a dropped merge conflict, or an ignored alias simply does nothing. Add debug to the script query string to surface these cases as [maple] prefixed console warnings.
<!-- Enable console warnings for silent failures -->
<script src="maple.js?debug"></script>
<!-- [maple] skipped class "bgc-" on <div>: unknown utility -->
<div class="bgc- p-4"></div>
<!-- [maple] merged: "pt-2 p-8" -> "p-8" -->
<div class="pt-2 p-8"></div>
What Debug Mode Reports
Startup configuration. The resolved options object is logged once at boot, including breakpoints. A mistyped flag such as
?nomregeis treated as a breakpoint and becomes immediately visible here.Skipped classes. A class that shows Maple intent but produces no rule is reported with the reason, such as an unknown utility or a missing style declaration. Intent means the class resolved to a known utility key, like the typo
bgc-, or that it carries Maple syntax markers: it contains:or=, or starts with!or$. Plain CSS classes such asbtn-primarystay silent.Merge rewrites. When conflict resolution changes an element's class attribute, the full rewrite is logged, for example
merged: "pt-2 p-8" -> "p-8".Alias problems. Unknown alias usage, invalid alias parameters, expansion depth limit hits from circular definitions, and alias definitions that arrive after the lock. A new or changed
--alias-*definition added to<html>after the initial markup is processed is ignored, and debug mode is the only signal.Cache evictions. Internal parse caches evict their oldest entries when full. Repeated eviction warnings suggest unbounded dynamic class generation.
Warnings raised while an element's classes are being processed, meaning skipped classes, merge rewrites, and alias problems, include the element as a second console argument, so you can click it in DevTools to locate the node.
Development Only
debug out of production builds. The checks are skipped entirely when the flag is off, so omitting it keeps the hot path free of debug work. Reference Mode
By default, Maple prepares the full fallback chain for each generated utility rule. This keeps every utility locally scoped, but complex values such as colors require Maple to assemble the same OKLCH fallback logic again whenever an equivalent utility is generated.
/* Without refs: the full fallback chain lives in each rule */
.c-red {
color: oklch(
from var(--c-red, var(--color-red, var(--red, red)))
calc(l * var(--c-red-l-scale, var(--red-l-scale, var(--c-l-scale, var(--l-scale, 1)))))
calc(c * var(--c-red-c-scale, var(--red-c-scale, var(--c-c-scale, var(--c-scale, 1)))))
calc(h + var(--c-red-h-rotate, var(--red-h-rotate, var(--c-h-rotate, var(--h-rotate, 0))))) /
alpha
);
}
With refs enabled, Maple generates that fallback chain once as a global reference variable. Later utilities can point to the reference instead of rebuilding the same chain. The purpose is runtime efficiency: less repeated generation work in Maple, and in some cases less repeated variable math for the browser when referenced values are recalculated.
/* With refs: the calculation is cached once and reused */
:root {
--ref-c-red: oklch(from var(--c-red, var(--color-red, var(--red, red))) calc(...) calc(...) calc(...) / alpha);
}
.c-red {
color: var(--ref-c-red);
}
.bgc-red {
background-color: var(--ref-bgc-red);
}
Trade-offs
Reference mode is a runtime caching strategy, not a CSS file size optimization. It can make large pages cheaper to generate, but it introduces specific trade-offs to consider:
Referenced utilities read from global
:rootvariables, so local overrides no longer affect those utilities by default. See the local override section below if you need to override a specific utility when refs mode is enabled.Browser DevTools may also become harder to navigate in large applications with many ref definitions, as every selected element lists the generated
:rootreference variables.
Local Overrides with Refs
Prefix a utility with $ when refs is enabled and that one utility should keep its full fallback chain. This lets the class respond to local CSS variables while the rest of the page still benefits from reference caching.
<script src="maple.js?refs"></script>
<!-- Uses the global reference cache -->
<div class="p-4">
Cached spacing
</div>
<!-- Skips the cache for this utility, so the local variable can win -->
<div class="$p-4 --p-4=2rem">
Locally overridden spacing
</div>
Choosing Reference Mode
refs for large applications with stable global tokens. Leave it off for component libraries or heavily scoped themes where local variable overrides are part of the public API. Disabling Hybrid Dark Mode
Maple's dark mode prefixes normally generate rules for both system preferences and manual dark or light classes on the <html> element. Add nohybrid when you only want the system preference media query.
<!-- Disable hybrid dark mode generation -->
<script src="maple.js?nohybrid"></script>
<div class="@dark:bgc-gray-950 @dark:c-white">
System dark mode only
</div>
With nohybrid, @dark: generates @media (prefers-color-scheme: dark) only. Manual root classes are no longer included in the generated selector behavior.