AgentStack
SKILL verified MIT Self-run

Gluestack Ui V5:performance

skill-gluestack-agent-skills-performance · by gluestack

Performance optimization and cross-platform patterns for gluestack-ui v5 - covers NativeWind v5 / UniWind, TypeScript, memoization, animations, and best practices.

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add skill-gluestack-agent-skills-performance

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Gluestack Ui V5:performance? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Gluestack UI v5 — Performance & Cross-Platform

This sub-skill focuses on performance optimization, cross-platform compatibility, and React Native best practices for gluestack-ui v5 (NativeWind v5 / UniWind).

Rule 12: Cross-Platform Rendering (Native & Web)

Gluestack UI v5 components are designed to work seamlessly on both React Native (iOS/Android) and Web platforms. Always use Gluestack wrapper components instead of direct React Native imports to ensure cross-platform compatibility.

Critical Rule: Always Use Gluestack Wrappers

NEVER import components directly from react-native when a Gluestack wrapper exists. Gluestack wrappers handle platform-specific differences automatically.

Platform-Specific Component Mapping

| React Native Import | Gluestack Wrapper | Notes | |---------------------|-------------------|-------| | KeyboardAvoidingView from react-native | KeyboardAvoidingView from @/components/ui/keyboard-avoiding-view | Required for web compatibility | | Platform from react-native | Use only when absolutely necessary | Prefer Gluestack's built-in platform handling | | View, Text, etc. | Box, Text from @/components/ui/* | Always use Gluestack components |

Correct Pattern: Cross-Platform Components

// ✅ CORRECT: Using Gluestack KeyboardAvoidingView wrapper
import { KeyboardAvoidingView } from '@/components/ui/keyboard-avoiding-view';
import { Platform } from 'react-native'; // Only when needed for platform-specific logic

  
    {/* Content */}
  

Incorrect Pattern: Direct React Native Imports

// ❌ INCORRECT: Direct import from react-native
import { KeyboardAvoidingView, Platform } from 'react-native';

  {/* This may not work correctly on web */}

Web-Specific Considerations

  1. KeyboardAvoidingView: The Gluestack wrapper handles web gracefully (web doesn't need keyboard avoidance)
  2. SafeAreaView: Works on both native and web (web treats it as a regular View)
  3. ScrollView: Works identically on both platforms
  4. Platform.select: Only use when absolutely necessary; prefer Gluestack's built-in handling

Testing Cross-Platform Compatibility

Always test components on both platforms:

  1. Native: Run npm run ios or npm run android
  2. Web: Run npm run web and verify in browser
  3. Verify: Check that all components render correctly and interactions work on both platforms

Platform-Specific Code (When Necessary)

If you must use platform-specific code, use it sparingly and document why:

// Acceptable: Platform-specific behavior when Gluestack doesn't cover it
import { Platform } from 'react-native';

const keyboardBehavior = Platform.OS === 'ios' ? 'padding' : 'height';

  {/* Content */}

Common Cross-Platform Issues to Avoid

  1. Direct React Native imports - Always use Gluestack wrappers
  2. Platform-specific styling without fallbacks - Ensure web has equivalent styles
  3. Native-only APIs - Check if web alternatives exist
  4. Missing web polyfills - Gluestack handles most of these automatically

Verification Checklist for Cross-Platform

  • [ ] All components imported from @/components/ui/* wrappers
  • [ ] No direct imports from react-native for wrapped components
  • [ ] KeyboardAvoidingView uses Gluestack wrapper
  • [ ] Tested on both native (iOS/Android) and web platforms
  • [ ] All interactions work on both platforms
  • [ ] Styling renders correctly on both platforms
  • [ ] No platform-specific code without documentation

Rule 13: Performance & Best Practices

Follow these best practices to ensure optimal performance, type safety, and maintainability in React Native/Expo applications.

Use TypeScript

Define navigation and prop types for type safety. This catches errors at compile time and improves developer experience.

Correct Pattern
// ✅ CORRECT: Typed component props
interface LoginFormProps {
  readonly onSubmit: (email: string, password: string) => void;
  readonly isLoading?: boolean;
}

const LoginForm = ({ onSubmit, isLoading = false }: LoginFormProps) => {
  // Component implementation
};

// ✅ CORRECT: Typed navigation
import { useRouter } from 'expo-router';

const router = useRouter();
router.push('/login' as any); // Type-safe navigation
Incorrect Pattern
// ❌ INCORRECT: No type definitions
const LoginForm = ({ onSubmit, isLoading }) => {
  // No type safety
};

Memoize Components

Use React.memo and useCallback to prevent unnecessary rerenders, especially for expensive components or frequently re-rendered parent components.

Correct Pattern
// ✅ CORRECT: Memoized component
import React, { useCallback, useState } from 'react';

const ExpensiveComponent = React.memo(({ data, onUpdate }: Props) => {
  // Expensive rendering logic
});

const ParentComponent = () => {
  const [count, setCount] = useState(0);

  // Memoized callback prevents child rerenders
  const handleUpdate = useCallback((value: string) => {
    // Update logic
  }, []);

  return (
    <>
       setCount(count + 1)}>
        Count: {count}
      
      
    
  );
};
When to Memoize
  • Components that receive stable props but parent rerenders frequently
  • Callbacks passed to child components
  • Expensive computations (use useMemo)

Run Animations on UI Thread

Use Reanimated worklets for 60fps animations. This keeps animations smooth by running on the native UI thread instead of the JavaScript thread.

Correct Pattern
// ✅ CORRECT: Using Reanimated worklets
import { useSharedValue, withTiming } from 'react-native-reanimated';
import Animated from 'react-native-reanimated';

const AnimatedBox = Animated.createAnimatedComponent(Box);

const Component = () => {
  const translateX = useSharedValue(0);

  const handlePress = () => {
    // Animation runs on UI thread
    translateX.value = withTiming(100, { duration: 300 });
  };

  return (
    
      
        Animate
      
    
  );
};
Incorrect Pattern
// ❌ INCORRECT: Using Animated API (runs on JS thread)
import { Animated } from 'react-native';

const Component = () => {
  const translateX = new Animated.Value(0);
  // This runs on JavaScript thread, can cause jank
};

Handle Safe Areas

Use SafeAreaView or useSafeAreaInsets to handle device notches, status bars, and home indicators properly.

Correct Pattern
// ✅ CORRECT: Using SafeAreaView
import { SafeAreaView } from '@/components/ui/safe-area-view';

const Screen = () => (
  
    
      {/* Content */}
    
  
);

// ✅ CORRECT: Using useSafeAreaInsets for custom layouts
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const CustomLayout = () => {
  const insets = useSafeAreaInsets();

  return (
    
      {/* Content */}
    
  );
};

Test on Real Devices

Simulator/emulator performance differs from real devices. Always test on physical devices before releasing.

Testing Checklist
  • [ ] Test on real iOS device (iPhone/iPad)
  • [ ] Test on real Android device
  • [ ] Test on different screen sizes
  • [ ] Test with different OS versions
  • [ ] Test performance under load
  • [ ] Test with slow network conditions

Use FlatList for Lists

Never use ScrollView with map for long lists. FlatList provides virtualization, which only renders visible items.

Correct Pattern
// ✅ CORRECT: Using FlatList
import { FlatList } from '@/components/ui/flat-list';

const ItemList = ({ items }: { items: Item[] }) => (
   (
      
        {item.name}
      
    )}
    keyExtractor={(item) => item.id}
    ListEmptyComponent={No items found}
  />
);
Incorrect Pattern
// ❌ INCORRECT: Using ScrollView with map (no virtualization)
import { ScrollView } from '@/components/ui/scroll-view';

const ItemList = ({ items }: { items: Item[] }) => (
  
    {items.map((item) => (
      
        {item.name}
      
    ))}
  
);

Why this is bad: All items are rendered at once, causing performance issues with long lists.

Platform-Specific Code

Use Platform.select for iOS/Android differences. This provides a clean, declarative way to handle platform-specific code.

Correct Pattern
// ✅ CORRECT: Using Platform.select
import { Platform } from 'react-native';

const styles = Platform.select({
  ios: {
    paddingTop: 20,
  },
  android: {
    paddingTop: 0,
  },
  default: {
    paddingTop: 0,
  },
});

  {/* Content */}

// ✅ CORRECT: Platform.select for values
const keyboardBehavior = Platform.select({
  ios: 'padding',
  android: 'height',
  default: 'padding',
});
Incorrect Pattern
// ❌ INCORRECT: Using if/else for platform checks
import { Platform } from 'react-native';

let styles;
if (Platform.OS === 'ios') {
  styles = { paddingTop: 20 };
} else {
  styles = { paddingTop: 0 };
}

Best Practices Summary

| Practice | Why It Matters | When to Use | |----------|---------------|-------------| | TypeScript | Type safety, catch errors early | Always | | React.memo | Prevent unnecessary rerenders | Components with stable props | | useCallback | Stable function references | Callbacks passed to children | | Reanimated worklets | 60fps animations | All animations | | SafeAreaView | Handle device notches/bars | All screens | | FlatList | Virtualization for performance | Lists with 10+ items | | Platform.select | Clean platform-specific code | iOS/Android differences | | Real device testing | Accurate performance metrics | Before release |

Performance Optimization Patterns

Memoized List Item

// ✅ CORRECT: Memoized list item component
interface ItemProps {
  readonly item: Item;
  readonly onPress: (id: string) => void;
}

const ListItem = React.memo(({ item, onPress }: ItemProps) => {
  const handlePress = useCallback(() => {
    onPress(item.id);
  }, [item.id, onPress]);

  return (
    
      
        {item.name}
      
    
  );
});

// Parent component
const ItemList = ({ items }: { items: Item[] }) => {
  const handlePress = useCallback((id: string) => {
    // Handle press
  }, []);

  return (
     (
        
      )}
      keyExtractor={(item) => item.id}
    />
  );
};

Animated Component

// ✅ CORRECT: Using Reanimated for smooth animations
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

const AnimatedBox = Animated.createAnimatedComponent(Box);

const AnimatedCard = () => {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));

  const handlePress = () => {
    scale.value = withSpring(1.1);
  };

  return (
    
      
        Press to animate
      
    
  );
};

Safe Area Handling

// ✅ CORRECT: Proper safe area handling
import { SafeAreaView } from '@/components/ui/safe-area-view';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const Screen = () => {
  const insets = useSafeAreaInsets();

  return (
    
      
        {/* Header */}
        
          Title
        

        {/* Content */}
        
          {/* Content */}
        

        {/* Footer with safe bottom padding */}
        
          
            Submit
          
        
      
    
  );
};

Performance Checklist

  • [ ] TypeScript types defined for all components and props
  • [ ] Expensive components wrapped with React.memo
  • [ ] Callbacks memoized with useCallback
  • [ ] Animations use Reanimated worklets
  • [ ] Safe areas handled with SafeAreaView or useSafeAreaInsets
  • [ ] Long lists use FlatList instead of ScrollView + map
  • [ ] Platform-specific code uses Platform.select
  • [ ] Tested on real devices (not just simulators)
  • [ ] Performance profiled and optimized
  • [ ] Cross-platform compatibility verified (native + web)

Common Performance Pitfalls

❌ Don't: Use ScrollView for Long Lists

// ❌ INCORRECT: No virtualization

  {items.map(item => )}

// ✅ CORRECT: Use FlatList
 }
  keyExtractor={(item) => item.id}
/>

❌ Don't: Create Callbacks Without useCallback

// ❌ INCORRECT: New function on every render
 handlePress(id)}>
  Press

// ✅ CORRECT: Memoized callback
const memoizedPress = useCallback(() => {
  handlePress(id);
}, [id, handlePress]);

  Press

❌ Don't: Use Animated API for Complex Animations

// ❌ INCORRECT: Runs on JavaScript thread
import { Animated } from 'react-native';
const animValue = new Animated.Value(0);

// ✅ CORRECT: Use Reanimated (runs on UI thread)
import { useSharedValue } from 'react-native-reanimated';
const animValue = useSharedValue(0);

v5-Specific Performance Notes

NativeWind v5

  • Pin lightningcss to exactly 1.30.1 in package.json overrides and resolutions. Mismatched versions cause CSS transformation errors and build failures.
  • Tailwind v4 uses CSS-first configuration via global.css — there is no tailwind.config.js overhead.
  • @tailwindcss/postcss handles CSS processing; keep the postcss.config.js file minimal.

UniWind

  • No PostCSS / lightningcss — UniWind processes CSS at Metro/Babel time, eliminating the PostCSS build step entirely. This can reduce build times for Expo projects.
  • Uses :where() selectors for theme scoping, which have zero CSS specificity — no specificity wars between themes.
  • Consider UniWind for simpler Expo-only projects where build-step reduction matters.

Reference

  • Reanimated Documentation: https://docs.swmansion.com/react-native-reanimated/
  • React Native Performance: https://reactnative.dev/docs/performance
  • Expo Router: https://docs.expo.dev/router/introduction/
  • NativeWind v5: https://www.nativewind.dev/

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.