Looking for documentation on gluestack-ui v2 with NativeWind? Refer to this link.

New Project

If you are starting with a new project, you can use npx to create a new project with gluestack-ui.
npm create gluestack@1
The above command will create a new nextJs project with @gluestack-ui/themed installed and configured with @gluestack/ui-next-adapter.
You can directly use all the components by directly importing them in your project.
import { Button } from '@gluestack-ui/themed';

Existing Project

If you wish to install gluestack-ui into your existing project, you can proceed with the following steps:

Step 1: Install dependencies

First, install the dependencies of gluestack-ui in your project. This can be done using the following command:
yarn add @gluestack-ui/themed @gluestack-style/react @gluestack/ui-next-adapter react-native-web react-native-svg@13.4.0
OR
npm i @gluestack-ui/themed @gluestack-style/react @gluestack/ui-next-adapter react-native-web react-native-svg@13.4.0

Step 1.5: Default Theme (Optional)

gluestack-ui is intentionally designed as an unstyled library, providing you with the flexibility to style your components as you prefer. However, if you want to use the default theme, you can install @gluestack-ui/config as well.
yarn add @gluestack-ui/config@latest
OR
npm i @gluestack-ui/config@latest

Step 2: Server-side rendering (SSR)

It's also recommended to set up your server-side rendering (SSR) correctly. To do this, you will need to use the flush() function exported by the @gluestack-ui/themed.

Next.js App Routers (which supports React Server Components)

  • For Next.js App Routers we will create a new registry.tsx file in the root of your project and use the flush function from @gluestack-ui/themed:
"use client"
import React, { useRef, useState } from "react"
import { useServerInsertedHTML } from "next/navigation"
import { StyleRegistry, createStyleRegistry } from "styled-jsx"
import { Html, Head, Main, NextScript } from "next/document"
// @ts-ignore
import { AppRegistry } from "react-native-web"
import { flush } from "@gluestack-ui/themed"
export default function StyledJsxRegistry({
children,
}: {
children: React.ReactNode
}) {
// Only create stylesheet once with lazy initial state
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
const isServerInserted = useRef(false)
useServerInsertedHTML(() => {
AppRegistry.registerComponent("Main", () => Main)
const { getStyleElement } = AppRegistry.getApplication("Main")
if (!isServerInserted.current) {
isServerInserted.current = true
const styles = [getStyleElement(), jsxStyleRegistry.styles(), ...flush()]
jsxStyleRegistry.flush()
return <>{styles}</>
}
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
  • We also need to add className="gs" to the <html> element in the layout.tsx file.
  • We also need to wrap children with StyledJsxRegistry in the layout.tsx file.
  • If dark mode needs to be rendered from the server side, you also need to add className="gs gs-dark" to the html element in the layout.tsx file. (optional)
The code in layout.tsx file at this point of time will look like this:
import "./globals.css"
import { Inter } from "next/font/google"
import StyledJsxRegistry from "./registry"
const inter = Inter({ subsets: ["latin"] })
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className="gs">
<body className={inter.className}>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}

Next.js Page Routers

To prevent flickering, the gs class should be attached, which increases the specificity of any inline styles that are being used.
Add this code in your _document.tsx file.
import * as React from "react"
import { Html, Head, Main, NextScript } from "next/document"
import { AppRegistry } from "react-native-web"
import { flush } from "@gluestack-style/react"
function Document() {
return (
<Html className="gs" lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
Document.getInitialProps = async ({ renderPage }: any) => {
AppRegistry.registerComponent("Main", () => Main)
const { getStyleElement } = AppRegistry.getApplication("Main")
const page = await renderPage()
const styles = [getStyleElement(), ...flush()]
return { ...page, styles: React.Children.toArray(styles) }
}
export default Document
If dark mode needs to be rendered from the server side, you also need to add className="gs gs-dark" to the Html element in the _document.tsx file. (optional)

Step 3: Setup @gluestack/ui-next-adapter

To use gluestack-ui components with server-side rendering, you need to configure your project to transpile the modules correctly. The easiest way to do this is by using the withGluestackUI Next.js adapter. This adapter adds the necessary configuration to your project to ensure that your gluestack-ui components are transpiled correctly for server-side rendering.
Make the following changes in next.config.js
/** @type {import('next').NextConfig} */
const { withGluestackUI } = require("@gluestack/ui-next-adapter")
const nextConfig = {
reactStrictMode: true,
transpilePackages: ["@gluestack-ui/themed"],
}
module.exports = withGluestackUI(nextConfig)

Step 4: Setup provider

GluestackUIProvider is a component that makes the aliases and tokens available throughout your app. It uses React's Context API.

Next.js App Routers (which supports React Server Components)

  • For Next.js App Routers we will create a new providers.tsx file in the app folder which will return a client component. Now, add the following code:
// app/providers.tsx
"use client"
import { GluestackUIProvider } from "@gluestack-ui/themed"
import { config } from "@gluestack-ui/config" // Optional if you want to use default theme
export function Providers({ children }: { children: React.ReactNode }) {
return <GluestackUIProvider config={config}>{children}</GluestackUIProvider>
}
This component returns a GluestackUIProvider component which wraps the children with the theme from @gluestack-ui/config file.
  • After creating providers.tsx file, we need to wrap the exported GluestackUIProvider component around the children in layout.tsx file. The code in layout.tsx file at this point of time will look like this:
import "./globals.css"
import { Inter } from "next/font/google"
import { Providers } from "./providers"
import StyledJsxRegistry from "./registry"
const inter = Inter({ subsets: ["latin"] })
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className="gs gs-light">
<body className={inter.className}>
<Providers>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</Providers>
</body>
</html>
)
}

Next.js Page Routers

For Next.js Page Router just add GluestackUIProvider to the root of your app and update _app.tsx as follows:
import "@/styles/globals.css"
import type { AppProps } from "next/app"
import { GluestackUIProvider } from "@gluestack-ui/themed"
import { config } from "@gluestack-ui/config" // Optional if you want to use default theme
export default function App({ Component, pageProps }: AppProps) {
return (
<GluestackUIProvider config={config}>
<Component {...pageProps} />
</GluestackUIProvider>
)
}
This ensures that all components are wrapped with <GluestackUIProvider />, and the theme from @gluestack-ui/config is applied.
This guide should help you get started with gluestack-ui in your expo project. If you run into any issues or have further questions, please refer to the official documentation or community forums.