Upgrade to gluestack-ui v2 with Codemod

This guide provides detailed steps to upgrade from gluestack-ui v1 to gluestack-ui v2. With codemod you can automate the process of code transformations, making it easier and faster to migrate your project to gluestack-ui v2. By following this guide, you'll ensure a smooth transition with minimal manual adjustments.

gluestack-ui v1 Usage Scenarios:

gluestack-ui v1 users can be divided into three scenarios:
  • Scenario 1 : Users who imported the gluestack-ui configuration from @gluestack-ui/config.
  • Scenario 2 : Users who exported the gluestack-ui configuration and made modifications to it (gluestack-ui.config.ts).
  • Scenario 3 : Users who exported components as well.

At this time, we fully support migration for users in Scenario 1 and Scenario 2 using codemod.

Overview of Steps to Follow (for Scenario 1 and Scenario 2 Users)


  1. Step
    1
    :
    Initialize gluestack-ui v2: npx gluestack-ui@latest init
  2. Step
    2
    :
    Setup Tailwind CSS: import "@/global.css"
  3. Step
    3
    :
    Add All Components: npx gluestack-ui@latest add --all
  4. Step
    4
    :
    Code Migration: npx @gluestack-ui/v2-codemod@latest <project_dir>

Step 1 : Initialize gluestack-ui v2

Run the below command to setup the project:
npx gluestack-ui@latest init
To refer more about the gluestack-ui v2 installation, check this.
Important Note
Installation using gluestack-ui CLI in Expo projects supports for Expo SDK 50 and above only. For Expo SDK < 49, please refer to the manual installation guide here.

Step 2 : Setup Tailwind CSS

Import global.css / globals.css where Tailwind directives are defined.
import { GluestackUIProvider } from "@/components/ui/gluestack-ui-provider"
import "@/global.css"
export default function App() {
return <GluestackUIProvider>{/* Your code */}</GluestackUIProvider>
}

Step 3 : Add All Components

To add all the components run the following command:
npx gluestack-ui@latest add --all
You can add only the necessary components instead of including all. Check here.
npx gluestack-ui@latest add heading

Step 4 : Code Migration

Codemod

The gluestack-ui v2 migration process has been streamlined with the creation of a codemod. This codemod automates the conversion of your existing v1 code to v2, ensuring a smooth transition. Here’s what the codemod does:
Style Migration:
  • It migrates all your existing stylings in v1 code to the appropriate v2 code.
  • The migrated styles will match the styling conventions used in NativeWind.
Config Migration:
  • If you have a custom v1 configuration, the codemod will also migrate this configuration to be compatible with v2.
Limitations:
  • Descendant Styling ( As it’s not supported in NativeWind at the moment)
  • Value of sx prop is variable

Please proceed with the following steps to continue the migration:

Run the following command :

npx @gluestack-ui/v2-codemod@latest <project_dir>

Limitations (Descendant Styling) :

  • Descendant styling will not be resolved and we’ll keep it as it is.
  • You can update it manually by moving it to the respective element where the style is required
//Before:
import { Box, Text } from "@gluestack-ui/themed"
export default function App() {
return (
<Box bg="$red500" sx={{ _text: { color: "white" } }}>
<Text>Simple Text</Text>
</Box>
)
}
//After:
import { Box } from "@/components/ui/box"
import { Text } from "@/components/ui/text"
//descendant style will remain as it is.
export default function App() {
return (
<Box
className="bg-red-500"
//Todo: Change this manually
sx={{ _text: { color: "white" } }}
>
<Text>Simple Text</Text>
</Box>
)
}
//Manual Changes:
//Update the descendant styling:
import { Box } from "@/components/ui/box"
import { Text } from "@/components/ui/text"
//descendant style will remain as it is.
//color:'white' --> text-white
export default function App() {
return (
<Box className="bg-red-500">
<Text className="text-white">Simple Text</Text>
</Box>
)
}

Examples of some property combinations :


Applying styles in different color modes (light/dark) :
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box sx={{ _dark: { bg: "$primary100" } }} bg="$primary300">
Simple Text
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
export default function App() {
return <Box className="dark:bg-primary-100 bg-primary-300">Simple Text</Box>
}
Applying styles for different media queries (sm/md/lg) using @:
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box sx={{ "@sm": { bg: "$background100" } }} bg="$background500">
Simple Box
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
export default function App() {
return (
<Box className="sm:bg-background-100 bg-background-500">Simple Box</Box>
)
}
Applying styles for different media queries (sm/md/lg) using $ :
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box $sm={{ bg: "$background100" }} bg="$background500">
Simple Box
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
export default function App() {
return (
<Box className="sm:bg-background-100 bg-background-500">Simple Box</Box>
)
}
Applying basic layout stylings :
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box mt="$4" pb="$2">
Simple Box
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
export default function App() {
return <Box className="mt-4 pb-2">Simple Box</Box>
}
Applying basic layout stylings in different color modes :
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box $md-dark={{ mt: "$4" }} $md-light={{ mt: "$2" }} pb="$2">
Simple Box
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
//By default if you don't mention any mode it's take light mode.
export default function App() {
return <Box className="md:dark:mt-4 md:mt-2 pb-2">Simple Box</Box>
}
Applying styles for different action states (hover/active etc..,) :
Before:
import { Box } from "@gluestack-ui/themed"
export default function App() {
return (
<Box $md-hover={{ bg: "$background500" }} $md={{ bg: "$background700" }}>
Simple
</Box>
)
}
After:
import { Box } from "@/components/ui/box"
//If not mentioned any mode explicitly then it's gonna take light mode only.
export default function App() {
return (
<Box className="md:hover:bg-background-500 md:bg-background-700">
Simple
</Box>
)
}
Applying styles for different platforms (mobile/web/android/ios) :
Before:
import { Text } from "@gluestack-ui/themed"
export default function App() {
return (
<Text
sx={{
_ios: {
marginTop: "$1",
},
_android: {
marginTop: "$2",
},
}}
>
gluestack-ui
</Text>
)
}
After:
import { Text } from "@/components/text"
export default function App() {
return <Text className="ios:mt-1 android:mt-2">gluestack-ui</Text>
}
Applying styles for different color modes at different media queries :
Before:
import { Center } from "@gluestack-ui/themed"
export default function App() {
return (
<Center
px="$4"
mb={-0.5}
sx={{
"@base": {
_light: { bg: "$backgroundLight0" },
_dark: { bg: "$backgroundDark800" },
},
"@md": {
py: "$48",
px: "$12",
_light: { bg: "$primary500" },
_dark: { bg: "$primary700" },
},
}}
></Center>
)
}
After:
import { Center } from "@/components/center"
export default function App() {
return (
<Center className="px-4 mb-0.5 bg-background-0 dark:bg-background800 md:py-48 md:px-12 md:bg-primary-500 md:dark:bg-primary-700"></Center>
)
}
Descendant Styling (this type of styling is not supported by NativeWind) :
Before:
import { CheckboxLabel, Text } from "@gluestack-ui/themed"
export default function App() {
return (
<CheckboxLabel
sx={{
bg: "$blue500",
_text: {
fontSize: "$sm",
color: "$primary500",
},
}}
>
<Text>gluestack-ui</Text>
</CheckboxLabel>
)
}
After:
import { CheckboxLabel } from "@/components/checkbox"
import { Text } from "@/components/text"
// we need to remove the descendant styling from parent element and add that
// styling to all the child elements
export default function App() {
return (
<CheckboxLabel className="bg-blue-500">
<Text className="text-sm text-primary-500">gluestack-ui</Text>
</CheckboxLabel>
)
}