Installation: Expo
Add the native package to an Expo project and render the same components on a device and in a browser.
The components are a separate implementation from the web ones and the same components to write: the names, the props and the colour roles are shared, and the platform decides how each one renders.
@asheeui/native lives in the AsheeUI repository and is not on npm yet, so an
application takes it from there. Everything after that step works the way the web
installations do.
The apps/expo-playground package in the repository is this page, built: it renders every
component in every state, runs on a device and exports to the web.
Before you start
| Requirement | Version | Why |
|---|---|---|
| Expo | SDK 57 | The version the native package is built against |
| React Native | 0.86.3 | The version SDK 57 pairs with |
| NativeWind | 4.2 | The classes a native component states |
| Tailwind CSS | 3.4 | NativeWind 4 compiles the v3 directives |
| Node.js | 18 or newer | The CLI and the bundler |
A version the package was not built against is the first thing to check when a component renders without its styles.
Create a project
If you're starting fresh, scaffold an Expo app:
pnpm create next-app my-appIf you have an existing Expo project, skip to the next step.
Get the packages
The native package is not published, so it is taken from the repository. The packages
inside the repository depend on each other with workspace:*, which resolves inside the
workspace a package belongs to, so an application joins the workspace rather than
installing a copy of it.
package.json
Clone the repository, add your application as a package in it, and install from the workspace root. Nothing is copied into your project in the process: the package ships its source, and the bundler compiles it.
Set up NativeWind
Install the styling layer:
pnpm add nativewind@4.2.7 react-native-css-interop@0.2.7Then point the bundler, Babel and Tailwind at each other.
metro.config.js
babel.config.js
tailwind.config.js
global.css
The application imports that file once, at its entry point:
index.js
A component gains a className from NativeWind, so the platform's types are declared
once:
nativewind-env.d.ts
Those seven values under colors are the theme's roles rather than a palette invented for
one screen: a component states bg-primary and text-foreground, and what those resolve
to is the line above. Change them, and the device, the simulator and the browser change
together, which is the whole of writing the theme once.
Wrap your application
The provider is mounted once, above everything the application renders, and it holds the defaults a component resolves against:
src/App.tsx
Verify it works
Render a few components:
You should see the heading in the theme's typography, a surface with a border and a radius, and a control in the accent colour. If the components render without their styles, the Tailwind content paths and the Metro plugin are the first two places to look.
To run the same application in a browser, set the web bundler in the Expo configuration and export it:
app.json
Where native differs from web
The vocabulary is shared, and a few things are stated the way the platform states them rather than the way a browser does. They are worth knowing before reading the component reference, which documents the web surface.
- A disabled control is
isDisabled. A nativeButtonstates the disabled state asisDisabled, where the webButtonstatesdisabled. Both are the same option, spelled the way each platform spells it. - Direction is a prop, not a breakpoint class.
<Stack direction="row">lays its children out in a row on every screen. A screen that changes direction at a width asksuseBreakpointand passes the answer, because the platform reports the window as a value rather than as a set of class prefixes. - A class is NativeWind's, not Tailwind's. A
classNameon a platform view is a string of classes that the renderer understands or ignores. It is not Tailwind in a browser, so a rule that depends on the cascade behaves differently, and a component's own props are the part that is guaranteed. - The package is not published. The web package is on npm; the native one is taken from the repository, as above, and will be published when its remaining components match the web contracts.
Next steps
- Getting Started: the CLI, the provider and a first component on the web.
- Components: the component reference, whose vocabulary the native package shares, with the differences listed above.
- Theming: what each colour role means and how one theme is declared once for every platform.
- The Expo playground: this page as a working application, including the layout kit. It builds for a device and exports to the web.