Troubleshoot
Troubleshoot
A decision tree for the most common shilp-sutra setup breakages. Read symptoms top-to-bottom; the first match is usually the right diagnosis.
Symptom: Tailwind utilities don't apply (no styling at all)
Diagnosis: Tailwind is not detecting design-system source classes, OR the CSS imports are out of order.
Check 1 — import order. Open the global CSS file. The order MUST be:
@import "tailwindcss"; /* FIRST */
@import "@devalok/shilp-sutra/css"; /* SECOND */
If reversed, swap them.
Check 2 — both imports present. Some setups accidentally drop @import "tailwindcss" after a refactor. Both imports are required.
Check 3 — file is actually loaded. In Next.js, globals.css must be imported from app/layout.tsx (App Router) or pages/_app.tsx (Pages Router). In Vite, from src/main.tsx. In Remix, via links export. In Astro, from a layout file.
Symptom: Spacing utilities like p-4 don't work but p-ds-04 does
Diagnosis: Working as designed.
Shilp Sutra uses the --spacing-ds-* namespace to avoid colliding with consumer numeric spacing. Use p-ds-04, gap-ds-03, mx-ds-08, etc. Plain p-4 is the consumer's own spacing (Tailwind's default scale) — it works but is unrelated to the design system.
If p-ds-* does NOT work, you have the styling-not-applying issue above.
Symptom: Console error or weird animation glitches involving MotionConfig, LayoutGroup, or AnimatePresence
Diagnosis: Multiple copies of framer-motion are resolved.
Run:
pnpm why framer-motion
# or
npm ls framer-motion
If more than one version is listed, fix with overrides:
pnpm:
// package.json
{
"pnpm": {
"overrides": {
"framer-motion": "^12"
}
}
}
npm:
// package.json
{
"overrides": {
"framer-motion": "^12"
}
}
yarn (berry):
// package.json
{
"resolutions": {
"framer-motion": "^12"
}
}
bun:
// package.json
{
"overrides": {
"framer-motion": "^12"
}
}
After editing, delete the lockfile + node_modules and reinstall.
Symptom: Next.js error: Cannot find module '@devalok/shilp-sutra/...' or Module parse failed: Unexpected token
Diagnosis: transpilePackages is missing from next.config.{ts,js,mjs}.
Add:
transpilePackages: ["@devalok/shilp-sutra"],
Symptom: Build error Cannot find module 'sonner' / 'input-otp' / 'date-fns' / '@tiptap/react' / 'react-pdf' / 'react-markdown' / '@emoji-mart/react'
Diagnosis: an optional peer dependency is missing. Each component below has a peer it pulls only when imported. Install the matching peer (always BEFORE the first import):
| You imported (per-component subpath) | Install |
|---|---|
…/ui/toaster or …/ui/toast | pnpm add sonner |
…/ui/input-otp | pnpm add input-otp |
…/composed/date-picker | pnpm add date-fns |
…/composed/emoji-picker | pnpm add @emoji-mart/data @emoji-mart/react |
…/composed/extensions/emoji-node or …/extensions/emoji-suggestion | pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder |
…/composed/rich-text-editor | pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder |
…/composed/rich-chat-input | pnpm add @tiptap/react @tiptap/starter-kit @tiptap/extension-placeholder |
…/composed/file-preview | pnpm add react-pdf react-zoom-pan-pinch |
…/composed/markdown-viewer | pnpm add react-markdown react-syntax-highlighter remark-gfm |
…/ai/block-renderer, …/ai/blocks/text, …/ai/blocks/error | pnpm add react-markdown remark-gfm |
Any …/ui/charts/* | pnpm add d3-array d3-axis d3-format d3-interpolate d3-scale d3-selection d3-shape d3-time-format d3-transition |
These ship as optional peers so consumers who never render the matching component don't pay the install cost. Once you import the component, the peer becomes required. Each affected component's JSDoc carries the same install hint — hover the import in your editor to see it inline.
Catch this at edit time, not build time: install @devalok/eslint-plugin-shilp-sutra (pnpm add -D @devalok/eslint-plugin-shilp-sutra, then shilpSutra.configs['flat/recommended']). Its prefer-per-component-import rule flags peer-cliff symbols imported from a barrel and autofixes the path — surfacing the cliff in your editor before the bundler ever fails.
For the full table in your framework's install recipe, see install-<framework>.md → §2a. Optional peer dependencies.
Symptom: Hydration warning on every page load (Next.js)
Diagnosis: next-themes writes the class attribute on <html> before React hydrates, causing a server/client class mismatch.
Add suppressHydrationWarning to <html> in app/layout.tsx (App Router) or pages/_document.tsx (Pages Router):
<html lang="en" suppressHydrationWarning>
This warning is specific to the class attribute on <html> — it does NOT suppress hydration warnings on other elements.
Symptom: Dark mode toggle does nothing
Diagnosis: The .dark class is not being applied to <html> (or any ancestor of the components).
Quick verification — open the browser console and run:
document.documentElement.classList.add("dark");
If components now render in dark mode, the toggle wiring is broken (not the design system). Check:
next-themesis installed and<ThemeProvider attribute="class">wraps the app- For Vite/Remix/Astro/TanStack: the
theme-bootstrap.jsscript runs before any React mount
If .dark IS on <html> and components still look light, the CSS imports are out of order — see the first symptom above.
Symptom: RSC error — You're importing a component that needs useState. It only works in a Client Component
Diagnosis: A client-only shilp-sutra component is being imported into a Server Component via the barrel.
Switch to per-component imports:
// ❌ pulls client code into RSC
import { Button } from "@devalok/shilp-sutra/ui";
// ✅ component-scoped, declares "use client" only where needed
import { Button } from "@devalok/shilp-sutra/ui/button";
For the full RSC-safety matrix, see server-components.md.
Symptom: Fonts render in browser default (Times/Arial), not Inter/Ranade
Diagnosis: Either the CSS import did not load (see first symptom), or the consumer is overriding --font-sans / --font-display and pointing at a font that isn't loaded.
Check the computed value of --font-sans on <html> in DevTools. It should be "Inter Variable", system-ui, .... If the override variable points at a font that isn't loaded, the browser falls back.
The font files ship inside the package — no next/font configuration is required for the defaults to work.
Symptom: Bare shadow class produces no visible shadow
Diagnosis: Working as designed. Tailwind 4 has no default --shadow token, so the shadow utility no longer exists.
Use the explicit shadow variants:
shadow-raised— cards, buttonsshadow-overlay— popovers, dropdownsshadow-floating— modals, dialogsshadow-brand— accent emphasis
Symptom: <Toaster /> is mounted but toast() doesn't show anything
Diagnosis: Either sonner is not installed, or two <Toaster /> instances are mounted at different positions and they're stacking off-screen.
Check 1 — pnpm list sonner shows ^2.0.0 or higher.
Check 2 — only ONE <Toaster /> is mounted in the app. Search the project: grep -r "<Toaster" src/ app/.
In dev mode, calling toast() without a mounted <Toaster /> logs a one-time console warning pointing to the fix (since v0.36.0).
Symptom: Build error mentioning use-sync-external-store
Diagnosis: Should not happen since v0.37.0 — use-sync-external-store was moved to runtime dependencies and is auto-installed transitively.
If it still happens, install it explicitly:
pnpm add use-sync-external-store
And open an issue at https://github.com/devalok-design/shilp-sutra/issues with the resolution graph (pnpm why use-sync-external-store) so we can fix the root cause.
Symptom: Storybook MCP server localhost:6006/mcp returns 404
Diagnosis: Storybook dev server isn't running, OR the MCP plugin is not enabled in this Storybook version.
Check 1 — pnpm dev is running and http://localhost:6006/ shows the Storybook UI.
Check 2 — the MCP endpoint requires Storybook 9+ with the MCP plugin enabled. Older versions of this repo's Storybook setup may need an upgrade.
The MCP server is a development convenience for AI agents — llms.txt and llms-full.txt are the authoritative docs and do not require a running server.
Still stuck
Open an issue with this template:
## Environment
- Framework + version (Next.js 15.x / Vite 5.x / Remix 2.x / Astro 5.x / TanStack Start ...)
- Package manager + version (pnpm 10.x / npm 11.x / yarn / bun)
- Node version
- @devalok/shilp-sutra version
- Other peer deps (framer-motion, sonner, tailwindcss versions)
## What I tried
[Recipe followed, step where it broke]
## What happened
[Exact error message, stack trace, screenshot]
## What I expected
[Behavior described in the recipe]
File at: https://github.com/devalok-design/shilp-sutra/issues/new