Repository navigation
create: scaffold's unlayered body styles defeat its own @layer base rules (and any shadcn theme) #511
Description
Which project does this relate to?
Create Tanstack App
Describe the bug
The generated src/styles.css has an unlayered body rule that permanently defeats the @layer base { body { … } } rule further down in the same file.
@import 'tailwindcss' sets up @layer theme, base, components, utilities. Unlayered CSS outranks all layered CSS, so in a fresh scaffold:
/* line 166 — unlayered → wins */
body {
margin: 0;
color: var(--sea-ink);
font-family: var(--font-sans);
background-color: var(--bg-base);
background: radial-gradient(...);
}
/* line 339 — layered → can never take effect */
@layer base {
body {
background-color: var(--background);
color: var(--foreground);
}
}The @layer base block is dead code as shipped — --background and --foreground never reach body.
This becomes a functional bug with the shadcn add-on. shadcn apply --preset <code> writes its theme into those same custom properties, so applying any preset from ui.shadcn.com/create has no visible effect:
--background/--foregroundlose to--bg-base/--sea-ink- the preset's font loses too — presets emit
@layer base { html { @apply font-serif } }, which the unlayeredbody { font-family: var(--font-sans) }(line 169) overrides a { color: var(--lagoon-deep) }(line 208, unlayered) overrides the theme's link colour
The CLI prints "Preset applied successfully.", the values written are correct, and the build passes. The page just doesn't change. Reproduces with apply <code>, --only theme, and --only theme,font.
Your Example Website or App
N/A — this is a create scaffolding bug. It happens when the project is generated, so there's no app to link. See Steps to Reproduce.
Steps to Reproduce the Bug or Issue
npx @tanstack/cli@latest create demo \
--framework react --non-interactive --add-ons shadcn \
--no-examples --package-manager npm --toolchain eslint --no-git --no-intent
cd demo
# any preset code from https://ui.shadcn.com/create
npx shadcn@latest apply --preset b5VsmmRNAG -y
npm run build
grep -o "body{[^}]*}" dist/client/assets/styles-*.cssActual output — four body rules, the shadcn one first and losing to three unlayered ones:
body{background-color:var(--background);color:var(--foreground)} /* @layer base — loses */
body{color:var(--sea-ink);background-color:var(--bg-base);background:radial-…} /* unlayered — wins */
body{background:radial-gradient(…)} /* unlayered — wins */
body{-webkit-font-smoothing:antialiased;overflow-x:hidden} /* unlayered */Visually: the page renders the scaffold's teal/green palette and Manrope, not the selected preset's palette and font.
Expected behavior
The @layer base rules the template itself ships should be able to take effect,
and an applied shadcn preset should govern the page's colours and font.
Concretely: after shadcn apply, body should resolve to the preset's
--background / --foreground, and the preset's font should apply — instead of
being silently overridden by the scaffold's own unlayered decorative rules.
Screenshots or Videos
No response
Platform
OS: macOS 27.0 (build 26A428), Darwin 27.0.0, arm64
Node: 24.14.1
npm: 11.16.0
@tanstack/cli: 0.71.0
@tanstack/create: 0.70.0
shadcn: 4.21.0
tailwindcss: 4.1.18
vite: 8.0.0
react: 19.2.0
Additional context
No response
Activity
mishucodes commentedon Sep 16, 2026
A few things I couldn't fit in the form.
Scope. Grepping the published
@tanstack/create@0.70.0tarball forsea-inkmatches 98 generated template files, includingdist/generated/worker/frameworks/react.jsand…/solid.jsplus many per-add-on templates. I only tested React — flagging Solid as likely-affected based on the grep, not on a run.Related, but not duplicates:
--sea-ink& friends from:rootinto@themeas--color-*. As far as I can tell it wouldn't fix this — the conflict is the unlayeredbodyrule, not where the custom properties are declared — so the two changes look compatible rather than overlapping.I searched open and closed issues for
shadcn,styles.css,theme,layer,cascade, andsea-inkand didn't find this reported — apologies if I missed it.Possible directions. I don't know whether the decorative CSS being unlayered was deliberate, or what else depends on it, so take these as options rather than recommendations:
@layer basewould let user CSS and shadcn tokens override them normally, while keeping the starter's appearance as-is.@layer base { body { … } }block currently in the template can't take effect, so it may be worth removing or relocating regardless of which direction you pick.Minor, same file: the template targets
#app(html, body, #app { min-height: 100% }), but TanStack Start builds the document in__root.tsx'sshellComponentand renders no#appelement — looks like a carry-over from the Vite SPA template.Workaround for anyone who hits this: delete the decorative block from
src/styles.css— the--sea-ink/--lagoon/--hero-*custom properties in:rootand.dark, and every rule frombody {through.site-footer. Keep the imports,@custom-variant dark, the--background-onward tokens,@theme inline, and the trailing@layer baseblock. In my project none of the decorative classes were referenced by any generated component, so removing them changed nothing visually and let the shadcn theme render as intended. Result: 347 → 144 lines, CSS bundle 24 KB → 17.8 KB.Happy to open a PR if any of that direction is useful — though you'd know better than me which one fits.