Overview
Copy component source into your project instead of installing a package.
delacour copies the library's source into your repository. You end up owning
button.tsx — you can read it, edit it, and delete the parts you do not want. There is no
package to upgrade and no release cadence to wait on.
bunx delacour@latest add buttonThat is the whole install — on a project it has not seen before, add does the setup below first.
It writes real files into your app:
src/
├── components/ui/button/ button.tsx, button.variants.ts, index.ts, AGENTS.md, …
├── lib/ cn.ts, tv.ts
└── styles/ tokens.css, theme.css, base.css, index.cssWhich delivery should you use?
Both are supported and both deliver the same files — the registry names the library's own source rather than carrying a copy of it, so the two cannot drift. The choice is about who owns the code.
| Install the package | This CLI | |
|---|---|---|
| Upgrades | bun update | delacour update — merged with your edits |
| Editing a component | Fork or wrap it | Edit the file |
| Import path | @delacour/react-native-ui/button | @/components/ui/button |
| New components | Arrive with the package | delacour add when you want one |
| Bundle | Only the subpaths you import | Only the files you added |
You can start with one and move to the other
The components are identical — the CLI copies the same source the package ships. Running
delacour add button in a project that already installs @delacour/react-native-ui gives you a local
copy to edit; delete the package import and point at the new path.
Why this is not just shadcn for React Native
The copy-in model is shadcn's. What is different is everything Expo makes different, and each of these is a failure that produces no error at all when it goes wrong:
Native modules go through expo install
bun add react-native-reanimated fetches the newest release, which on any older SDK does not
compile. The CLI asks the SDK what it supports.
Metro is wrapped, outermost
withUniwindConfig installs the transform that compiles className. A wrapper applied after
it can replace the transformer and leave every component unstyled.
@source globs use real paths
Tailwind's scanner does not follow the symlink a monorepo creates, and a glob that misses your components strips their classes from the release build.
doctor checks all of it
New Architecture, tsconfigPaths, the gesture root, a competing Tailwind transform, duplicate
native modules. Every check names its own fix.
What the setup will and will not touch
add runs this itself the first time. init is the same thing on its own,
for when the layout has to be chosen rather than inferred.
Writes native-components.json
Where components go, and how they should import each other. See Configuration.
Wires Metro and your Tailwind entry
metro.config.js gets the Uniwind wrapper; global.css gets an @import and the @source
globs, inside a marked block it is safe to re-run over.
Copies the theme and the root provider
The styles item — tokens, palette, and the Uniwind type shim — so a fresh project renders before
you have chosen a single component, and provider, so the gesture root every press needs is one
import away rather than a second command. Of those, theme.css is the file that is yours to
replace; see Theming.
Prints what it will not do
tsconfig.json and app.config.ts are read, never written. Three things need a human, and
delacour doctor re-checks every one of them.