Claude
Skills
Sign in
Back

gluestack-ui-v4:validation

Included with Lifetime
$97 forever

Validation checklist and anti-patterns for gluestack-ui v4 - use for code review, checking implementation quality, and identifying common mistakes.

Design

What this skill does


# Gluestack UI v4 - Validation & Anti-Patterns

This sub-skill focuses on validating implementations, identifying anti-patterns, and ensuring code quality for gluestack-ui v4.

## Validation Checklist

When reviewing code, check for:

### Component Usage

- [ ] Component usage verified against official v4 docs at `https://v4.gluestack.io/ui/docs/components/${componentName}/`
- [ ] All React Native primitives replaced with Gluestack components
- [ ] Components imported from local `@/components/ui/` directory
- [ ] GluestackUIProvider wraps the app

### Component Props vs className

- [ ] **Component props used instead of className when available:**
  - [ ] VStack/HStack use `space` prop instead of `gap-*` className
  - [ ] Button uses `variant` and `size` props instead of className
  - [ ] Heading/Text use `size` prop instead of `text-*` className
  - [ ] Heading/Text use `bold` prop instead of `font-bold` className
  - [ ] Other component props used where applicable

### Styling

- [ ] **CRITICAL: All colors use ONLY semantic tokens** - NO exceptions:
  - [ ] No `typography-*` tokens (use `text-foreground`, `text-muted-foreground`)
  - [ ] No `neutral-*` tokens (use semantic equivalents)
  - [ ] No `gray-*` or `slate-*` tokens (use semantic equivalents)
  - [ ] No numbered colors: `red-500`, `blue-600`, `green-400`
  - [ ] No arbitrary values: `[#3b82f6]`, `[#DC2626]`
  - [ ] No opacity utilities (use alpha values: `/70`, `/90`)
- [ ] All spacing values use the standard scale (no arbitrary values)
- [ ] No inline styles where className can be used
- [ ] Dark mode support using `dark:` prefix (semantic tokens ensure compatibility)
- [ ] Variants defined using `tva` when needed
- [ ] className properly merged in custom components

### Compound Components

- [ ] **Compound components used correctly:**
  - [ ] InputIcon always wrapped in InputSlot (CRITICAL)
  - [ ] ButtonText used for all button text content
  - [ ] FormControl sub-components used (FormControlLabel, FormControlError, etc.)
  - [ ] Card sub-components used (CardHeader, CardBody, CardFooter)
  - [ ] Checkbox sub-components used (CheckboxIndicator, CheckboxIcon, CheckboxLabel)
  - [ ] All other component sub-components as per official docs

### Icons

- [ ] Icons follow priority: pre-built icons → Lucide Icons → createIcon for custom icons
- [ ] Icons imported from `@/components/ui/icon`

### Cross-Platform Compatibility

- [ ] **Cross-platform compatibility verified:**
  - [ ] All components use Gluestack wrappers (no direct react-native imports)
  - [ ] KeyboardAvoidingView uses Gluestack wrapper
  - [ ] Tested on both native and web platforms
  - [ ] All interactions work on both platforms

### Performance & Best Practices

- [ ] **Performance & best practices:**
  - [ ] TypeScript types defined for components and props
  - [ ] Expensive components memoized with React.memo
  - [ ] Callbacks memoized with useCallback when needed
  - [ ] Animations use Reanimated worklets (not Animated API)
  - [ ] Safe areas handled with SafeAreaView or useSafeAreaInsets
  - [ ] Long lists use FlatList (not ScrollView + map)
  - [ ] Platform-specific code uses Platform.select
  - [ ] Tested on real devices (not just simulators)

## Anti-Patterns to Avoid

### ❌ Don't: Mix React Native and Gluestack Components

```tsx
// ❌ INCORRECT: Mixing React Native and Gluestack components
import { View, Text } from "react-native";
import { Button } from "@/components/ui/button";

<View>
  <Text>Mixed usage</Text>
  <Button>Click</Button>
</View>
```

**Why it's bad**: Loses theming, accessibility, and cross-platform consistency.

**Correct approach**:
```tsx
// ✅ CORRECT: Use Gluestack components consistently
import { Box } from "@/components/ui/box";
import { Text } from "@/components/ui/text";
import { Button, ButtonText } from "@/components/ui/button";

<Box>
  <Text>Consistent usage</Text>
  <Button>
    <ButtonText>Click</ButtonText>
  </Button>
</Box>
```

### ❌ Don't: Use Non-Semantic Color Tokens

**STRICTLY PROHIBITED** - You MUST use ONLY semantic tokens for ALL colors.

```tsx
// ❌ PROHIBITED: Generic typography tokens
<Text className="text-typography-900">Heading</Text>
<Text className="text-typography-700">Body</Text>
<Text className="text-typography-500">Muted</Text>

// ❌ PROHIBITED: Neutral color tokens
<Box className="bg-neutral-100">Card</Box>
<Text className="text-neutral-600">Text</Text>
<Box className="border-neutral-300">Border</Box>

// ❌ PROHIBITED: Gray/Slate color scales
<Box className="bg-gray-50">Background</Box>
<Text className="text-gray-900">Content</Text>
<Box className="border-gray-200">Border</Box>

// ❌ PROHIBITED: Numbered color tokens
<Box className="bg-blue-600">Primary</Box>
<Text className="text-red-500">Error</Text>
<Box className="border-green-400">Success</Box>

// ❌ PROHIBITED: Arbitrary color values
<Box className="bg-[#3b82f6]">Arbitrary</Box>
<Text className="text-[#DC2626]">Error</Text>

// ❌ PROHIBITED: Inline color styles
<Box style={{ backgroundColor: '#fff' }}>White</Box>
<Text style={{ color: 'red' }}>Error</Text>

// ❌ PROHIBITED: Opacity utilities
<Text className="text-black opacity-70">Muted</Text>
<Box className="bg-blue-600 bg-opacity-90">Transparent</Box>
```

**Why it's bad**:
- ❌ Breaks theming and dark mode
- ❌ Creates maintenance debt
- ❌ Violates design system
- ❌ Inconsistent colors across app

**Correct approach**:
```tsx
// ✅ CORRECT: Use ONLY semantic tokens
<Text className="text-foreground">Heading</Text>
<Text className="text-foreground">Body</Text>
<Text className="text-muted-foreground">Muted</Text>

<Box className="bg-muted">Card</Box>
<Text className="text-muted-foreground">Text</Text>
<Box className="border-border">Border</Box>

<Box className="bg-background">Background</Box>
<Text className="text-foreground">Content</Text>
<Box className="border-border">Border</Box>

<Box className="bg-primary">Primary</Box>
<Text className="text-destructive">Error</Text>
<Box className="border-primary">Success</Box>

// ✅ CORRECT: Alpha values instead of opacity
<Text className="text-foreground/70">Muted</Text>
<Box className="bg-primary/90">Transparent</Box>
```

### ❌ Don't: Skip Sub-Components

```tsx
// ❌ INCORRECT: ButtonText is required
<Button>Click Me</Button>

// ❌ INCORRECT: InputIcon not wrapped in InputSlot
<Input>
  <InputIcon as={MailIcon} />
  <InputField />
</Input>

// ❌ INCORRECT: Missing FormControl sub-components
<FormControl>
  <Text>Email</Text>
  <InputField />
</FormControl>
```

**Why it's bad**: Components won't render correctly, breaks styling and accessibility.

**Correct approach**:
```tsx
// ✅ CORRECT: Proper sub-component usage
<Button>
  <ButtonText>Click Me</ButtonText>
</Button>

// ✅ CORRECT: InputIcon wrapped in InputSlot
<Input>
  <InputSlot>
    <InputIcon as={MailIcon} />
  </InputSlot>
  <InputField />
</Input>

// ✅ CORRECT: FormControl with proper sub-components
<FormControl>
  <FormControlLabel>
    <FormControlLabelText>Email</FormControlLabelText>
  </FormControlLabel>
  <Input>
    <InputField />
  </Input>
</FormControl>
```

### ❌ Don't: Use Inline Styles When className Works

```tsx
// ❌ INCORRECT: Inline styles for static values
<Box style={{ padding: 16, backgroundColor: '#fff' }} />
<Text style={{ fontSize: 18, fontWeight: 'bold' }} />
```

**Why it's bad**: Bypasses optimization, breaks theming, harder to maintain.

**Correct approach**:
```tsx
// ✅ CORRECT: Use className
<Box className="p-4 bg-background" />
<Text size="lg" bold className="text-foreground" />
```

### ❌ Don't: Use Arbitrary Spacing Values

```tsx
// ❌ INCORRECT: Arbitrary spacing values
<Box className="p-[13px] m-[27px]" />
<Box style={{ padding: 13, margin: 27 }} />
<VStack className="gap-[15px]" />
```

**Why it's bad**: Creates maintenance burden, inconsistent spacing across app.

**Correct approach**:
```tsx
// ✅ CORRECT: Use spacing scale
<Box className="p-3 m-6" />
<VStack space="lg" />
```

### ❌ Don't: Use className for Compon

Related in Design