Troubleshooting
The eleven doctor checks, and the silent failure each one exists to catch.
bunx delacour@latest doctor✓ Expo SDK ~57.0.15, react-native 0.86.2
✓ New Architecture enabled
✓ Uniwind uniwind and tailwindcss installed
✓ Metro wrapped, outermost, pointing at the configured entry
✗ Tailwind sources not scanned: src/components/ui
→ Classes in those files are dropped from release builds.
! Gesture Handler no GestureHandlerRootView found
→ Wrap your root layout in <GestureHandlerRootView style={{ flex: 1 }}>.Every check here exists because the thing it catches produces no error. A React Native app with any of these wrong builds fine, boots fine, and is quietly wrong — which is why this command exists at all and shadcn has no equivalent.
--fast skips the two checks that shell out to the Expo CLI. --json prints the results for CI;
the exit code is non-zero when a check fails.
Symptom → cause
My components render, but with no styles
Three causes, in the order worth checking.
Nothing imports the CSS entry. withUniwindConfig's cssEntryFile tells the transformer which
file to compile — it does not put that file in the bundle. If no module imports it, the app builds,
boots and renders every component completely unstyled, with nothing logged.
import "@/styles/global.css";First statement, in the root layout. delacour doctor checks this, and is careful to ignore a doc
comment that merely names the import.
The signature is unmistakable once you have seen it: no padding, no gaps, no colours, and spinners drawn at their natural SVG size rather than the icon scale. Every component is mounting — it is only the classes that never arrived.
Tailwind's @source coverage, and usually only in a release build. Tailwind compiles the
classes it finds in source text, so a glob that does not reach your components means those classes
were never compiled.
In a monorepo, the usual cause is a @source pointing through node_modules — the scanner does
not follow symlinks, so it scans nothing. See Monorepos.
bunx delacour@latest doctor # "Tailwind sources — not scanned: …"
bunx delacour@latest init -f # rewrites the managed @source blockMetro's wrapper ordering. If withUniwindConfig is present but not the outermost wrapper,
something applied after it can replace config.transformer, and className stops compiling
entirely. doctor checks the ordering, not just the presence.
Light works, dark never arrives
theme.css is still in shadcn's shape. A pasted globals.css declares its dark palette in a
.dark { … } block, and Uniwind reads that as a utility class named dark — no error, no
warning, and every dark value silently never reaches a component. Uniwind takes a theme only from
@variant light / @variant dark.
bunx delacour@latest doctor # "Theme tokens — theme.css is in shadcn's :root / .dark shape"
bunx delacour@latest theme # rewrites theme.css in placeThe command also fills in the tokens shadcn has no name for — --destructive-foreground among
them, which shadcn v4 stopped declaring and which every destructive control here paints its label
with. See Theming.
Presses do nothing
No GestureHandlerRootView above the component. Every pressable in this library is a Gesture
Handler detector, and a detector outside the root never receives a touch — no error, no warning.
import { DelacourProvider } from "@/components/ui/provider";
export default function RootLayout() {
return <DelacourProvider>{children}</DelacourProvider>;
}Unable to resolve "@/components/ui/button"
Metro does not read tsconfig path mappings unless you ask it to:
experiments: { tsconfigPaths: true }doctor only raises this when native-components.json actually has aliases. If it does not, your imports
are relative and this is not your problem.
A red box naming a module I just installed
A native module is not live until the app is rebuilt — a JavaScript reload cannot pick it up,
because the module is not in the binary. add warns when it installs one.
npx expo run:ios # or run:androidSomething breaks only in a monorepo
Two copies of a native module registering twice. doctor warns when it finds
react-native-reanimated (or friends) under both the app and the workspace root; pin them in
Metro's resolver.extraNodeModules.
A worklet error, or Reanimated refusing to build
Reanimated 4 is New Architecture only. doctor reads your resolved Expo config and fails if
newArchEnabled is off.
add overwrote something I had edited
It asks first — unless you passed --overwrite, or ran non-interactively without it, in which
case it refuses and names the files. --overwrite is for taking the registry's copy on purpose. To
bring a component up to date and keep what you changed, use update instead:
bunx delacour@latest update buttonupdate left conflict markers in a file
You and the registry changed the same lines, and it will not guess between you. Open the file,
keep the side you want from each <<<<<<< local … >>>>>>> registry region, and delete the
markers. Nothing else needs doing — the lock already names the new registry text, so the next
update starts from there.
update skipped a file "not in the lock"
The file was copied in before the lock existed and no longer matches the registry, so there is
nothing to merge it from. At a terminal, update asks what to do with those files once the run is
done. Anywhere else, name the ref it came from with --base <ref>, or take the registry's copy
with add <name> --overwrite.
The registry does not have a component I can see on this site
Your CLI is pinned to the ref it was published from. Take the newest:
bunx delacour@latest add tabs --ref mainSee The registry.
Every className is a type error in a monorepo
Type '{ children: Element; className: string; … }' is not assignable to type
'IntrinsicAttributes & Omit<AnimatedProps<Readonly<ViewProps>>, "ref">'uniwind-env.d.ts is one line — /// <reference types="uniwind/types" /> — and it is what gives a
React Native component a className prop in TypeScript at all. In a shared package it lands beside
the components, outside the app's tsconfig include, and nothing imports it: a declaration file
holding only a triple-slash reference cannot be reached by an import. So the augmentation never
loads for the app.
init writes a copy into the app for you, and doctor fails when it is missing. If you are
adopting a package by hand, add it yourself:
/// <reference types="uniwind/types" />Ref<never>, or two copies of React Native's types
Type 'Ref<never> | undefined' is not assignable to type 'AnimatedComponentRef<typeof View>'A Bun workspace installing with the default isolated layout. Packages sit under
node_modules/.bun/… and are linked from each package, so the shared package resolves React Native
at a different realpath than the app — TypeScript treats them as different modules and generics
collapse to never. Metro cannot follow that layout either.
[install]
linker = "hoisted"A copied component does not typecheck
That is a registry defect rather than something wrong with your project — an import the registry did not account for, or a package it failed to declare. Confirm it against a clean app:
bun --filter delacour run verify:expo --only <component>If that run is clean, the difference is your project: check delacour info for where files landed,
and tsconfig.json for an alias that resolves somewhere unexpected.
The full check list
Prop
Type
When doctor is not enough
bunx delacour@latest infoPrints the resolved config and everything that was detected — package manager, workspace root, app
root, the path aliases found in tsconfig.json, and the absolute directory for each namespace.
Start there when files are landing somewhere you did not expect.