Varför NativeWind har blivit standardvalet för React Native-styling
Styling i React Native har länge varit ett ämne som delar communityn. Inline-objekt med StyleSheet.create? Styled components? Utility-first CSS? Alla har haft sina fans — och diskussionerna har ibland blivit ganska heta.
Men 2026 har en tydlig vinnare dykt upp. Enligt State of React Native-undersökningen använder över 42% av alla React Native-utvecklare NativeWind, vilket gör det till den överlägset mest populära tredjepartslösningen för styling. Och ärligt talat, det förvånar mig inte alls.
Anledningen är enkel: NativeWind låter dig skriva Tailwind CSS-klasser direkt i dina React Native-komponenter och kompilerar dem vid byggtid till optimerade StyleSheet.create-objekt. Du får alltså Tailwinds produktivitet utan att betala med prestanda. Ganska svårslaget.
I den här guiden går vi igenom allt: installation med Expo SDK 55, dark mode, prestandajämförelser med alternativ som Tamagui och StyleSheet, komponentbibliotek som NativewindUI och React Native Reusables, och en titt framåt mot NativeWind v5.
Installation av NativeWind v4 med Expo SDK 55
NativeWind v4 är den stabila produktionsversionen i april 2026. Installationen kräver ett par steg, men inget av dem är särskilt krångligt. Häng med.
Steg 1: Installera paket
Börja med att installera NativeWind och dess beroenden:
npm install nativewind react-native-reanimated react-native-safe-area-context
npm install --dev tailwindcss@^3.4.17 prettier-plugin-tailwindcss@^0.5.11
Notera att vi installerar Tailwind CSS 3.x här — inte v4. Version 4 hör till NativeWind v5 (mer om det längre ner).
Steg 2: Konfigurera tailwind.config.js
Skapa filen tailwind.config.js i projektets rot:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./App.tsx",
"./app/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
"./screens/**/*.{js,jsx,ts,tsx}",
],
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
};
Det kritiska här är content-arrayen — den måste inkludera alla mappar som innehåller filer med Tailwind-klasser. Missar du en mapp genereras inga stilar för de filerna, och du kan sitta och felsöka ett bra tag innan du fattar vad som gick fel. Lita på mig, det har hänt de flesta.
Steg 3: Skapa global.css
Skapa filen global.css i projektets rot:
@tailwind base;
@tailwind components;
@tailwind utilities;
Steg 4: Konfigurera Babel
Nu till babel.config.js — det här steget är obligatoriskt för att NativeWind ska kunna transformera JSX korrekt:
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
};
};
Båda raderna krävs i v4. Glömmer du jsxImportSource fungerar inte className-propen. Glömmer du nativewind/babel kompileras inte klasserna. Två saker att hålla koll på, helt enkelt.
Steg 5: Konfigurera Metro
Uppdatera metro.config.js:
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const config = getDefaultConfig(__dirname);
module.exports = withNativeWind(config, { input: "./global.css" });
Viktigt: withNativeWind måste vara det sista steget — modifiera inte config-objektet efter detta anrop. Det är en vanlig fälla som vi återkommer till i felsökningssektionen.
Steg 6: Importera CSS i din entry-fil
I app/_layout.tsx (eller App.tsx om du inte kör Expo Router):
import "./global.css";
import { Stack } from "expo-router";
export default function RootLayout() {
return ;
}
Verifiera installationen
Okej, vi har gjort alla steg. Men hur vet vi att det faktiskt fungerar? NativeWind har en smidig verifieringsfunktion:
import { verifyInstallation } from "nativewind";
import { View, Text } from "react-native";
export default function TestScreen() {
// Anropa i development för att verifiera
if (__DEV__) {
verifyInstallation();
}
return (
NativeWind fungerar!
);
}
Om något är felkonfigurerat ger verifyInstallation() tydliga felmeddelanden i konsolen. Väldigt uppskattat när man inte kan lista ut varför stilarna vägrar dyka upp.
Grundläggande styling med NativeWind
Om du har erfarenhet av Tailwind CSS på webben kommer du att känna igen syntaxen direkt. Skillnaden är att NativeWind mappar Tailwind-klasser till React Natives StyleSheet-egenskaper istället för CSS. I praktiken märks det knappt.
Layout med Flexbox
React Native använder Flexbox som standard, och NativeWind gör det ännu smidigare att jobba med:
import { View, Text } from "react-native";
export default function LayoutExample() {
return (
{/* Horisontell rad med mellanrum */}
Titel
Detalj
{/* Centrerat innehåll */}
Välkommen
{/* Bottom bar med padding */}
Hem
Sök
Profil
);
}
Kort-komponent med skugga och rundade hörn
Här är en typisk kortkomponent — den sortens byggblock man behöver i nästan varje app:
import { View, Text, Image, Pressable } from "react-native";
interface CardProps {
title: string;
description: string;
imageUrl: string;
onPress: () => void;
}
export function Card({ title, description, imageUrl, onPress }: CardProps) {
return (
{title}
{description}
);
}
Plattformsspecifik styling
NativeWind stödjer plattformsvarianter som gör det riktigt smidigt att anpassa stilar per plattform — utan villkorlig logik:
Plattformsanpassad text
Dark mode med NativeWind
Mörkt läge är i princip ett krav för moderna mobilappar vid det här laget, och NativeWind gör implementationen förvånansvärt enkel med dark:-varianten. Jag blev genuint positivt överraskad första gången jag testade det.
Konfigurera systembaserat dark mode
Lägg till i app.json:
{
"expo": {
"userInterfaceStyle": "automatic"
}
}
Med denna inställning följer appen automatiskt enhetens ljus/mörker-inställning. Du behöver inte sätta darkMode: 'class' i tailwind.config.js — NativeWind hanterar detta åt dig.
Använda dark:-varianten
import { View, Text, ScrollView } from "react-native";
export default function ThemedScreen() {
return (
Inställningar
Hantera dina appinställningar
Notifikationer
Aktivera push-notiser för uppdateringar
);
}
Ser du mönstret? Du anger bara ljust läge som standard och lägger till dark:-prefix för mörklägesvarianten. Rent och enkelt.
Manuell temväxling
Vill du låta användaren välja tema oberoende av systeminställningen? Använd NativeWinds colorScheme-API:
import { View, Text, Pressable } from "react-native";
import { useColorScheme, colorScheme } from "nativewind";
export function ThemeToggle() {
const { colorScheme: currentScheme } = useColorScheme();
const toggleTheme = () => {
colorScheme.set(currentScheme === "dark" ? "light" : "dark");
};
return (
{currentScheme === "dark" ? "Ljust läge" : "Mörkt läge"}
);
}
colorScheme.set() accepterar "light", "dark" eller "system". Vill du spara användarens val mellan sessioner? Kombinera med @react-native-async-storage/async-storage så behåller appen inställningen vid omstart.
Anpassade CSS-variabler för teman
För mer avancerad temahantering (tänk varumärkesfärger som ändras mellan ljust och mörkt) kan du definiera CSS-variabler i global.css:
:root {
--color-primary: #3b82f6;
--color-surface: #ffffff;
--color-on-surface: #111827;
}
.dark {
--color-primary: #60a5fa;
--color-surface: #0f172a;
--color-on-surface: #f9fafb;
}
Referera sedan till variablerna i din Tailwind-konfiguration:
// tailwind.config.js
module.exports = {
// ...
theme: {
extend: {
colors: {
primary: "var(--color-primary)",
surface: "var(--color-surface)",
"on-surface": "var(--color-on-surface)",
},
},
},
};
Nu kan du använda dina tema-färger direkt i komponenterna:
Automatiskt temad text
Klicka här
Det här upplägget skalar riktigt bra om du har flera teman eller behöver stödja vitlabelade appar.
Prestandajämförelse: NativeWind vs Tamagui vs StyleSheet
Den kanske vanligaste frågan: kostar NativeWind prestanda? Det korta svaret: nej, praktiskt taget inte.
Benchmarkresultat (250 vyer, iPhone 11, produktionsläge)
Community-benchmarks från react-native-style-libraries-benchmark ger ganska intressanta siffror:
- Restyle (Shopify): 625 ms — 12% snabbare än StyleSheet
- Tamagui: 680 ms — 4,3% snabbare
- NativeWind v4: 705 ms — 0,8% snabbare
- StyleSheet.create (baseline): 711 ms
- twrnc: 729 ms — 2,4% långsammare
- Dripsy: 799 ms — 12,3% långsammare
NativeWind v4 presterar alltså inom 1% av rå StyleSheet — och i det här testet till och med marginellt snabbare. Varför? Jo, NativeWind kompilerar Tailwind-klasser vid byggtid till StyleSheet.create-objekt. Ingen runtime-parsning av klassnamn i produktionsläge.
Startpåverkan (iPhone 15 Pro)
- StyleSheet.create: ~0 ms overhead
- Tamagui (kompilerad): ~1 ms
- NativeWind v4 (kompilerad): ~2 ms
- twrnc (runtime): ~8–15 ms per render
Skillnaden märks framför allt med runtime-bibliotek som twrnc, som parserar klassnamn vid varje rendering. NativeWind och Tamagui slipper det tack vare byggtidskompilering.
När väljer du vad?
Så, vilken lösning passar dig bäst? Här är en snabb sammanfattning:
- NativeWind — bäst om du redan kan Tailwind CSS, vill ha snabb prototyping och byggtidskompilering. Störst community med 42% adoption.
- Tamagui — bäst för design-system med strikta tokens, cross-platform web+native med optimerande kompilator. Marginellt bättre prestanda under hög belastning.
- StyleSheet.create — bäst för maximal kontroll utan beroenden. Perfekt för delade bibliotek och komponentpaket.
- twrnc — bäst för snabb prototyping utan byggtidskonfiguration. Men undvik det i prestandakritiska listor med många element.
Komponentbibliotek med NativeWind-stöd
En stor fördel med att NativeWind blivit så dominant är ekosystemet av komponentbibliotek som vuxit upp kring det. Du behöver sällan bygga allt från scratch.
NativewindUI
NativewindUI är ett komponentbibliotek med 30+ komponenter och en community på över 3 000 utvecklare. Det som gör det unikt (och ärligt talat riktigt snyggt) är att komponenterna renderar med plattformsspecifik design — iOS-komponenter ser ut som iOS, Android-komponenter följer Material Design.
Du hittar allt från Action Sheet och Avatar till Bottom Tabs, Alert och Adaptive Search Header. Plus professionella mallar för vanliga flöden som autentisering och checkout, vilket kan spara rejält med utvecklingstid.
React Native Reusables
React Native Reusables beskrivs ofta som "shadcn/ui för React Native" — det vill säga copy-paste-komponenter som du äger helt och hållet. Biblioteket har 8 000+ utvecklare och bygger på RN Primitives för tillgänglighet.
Komponentlistan är imponerande: Accordion, Alert Dialog, Avatar, Badge, Button, Card, Checkbox, Collapsible, Dialog, Dropdown Menu, Input, Label, Popover, Progress, Radio Group, Select, Separator, Skeleton, Switch, Tabs, Text, Textarea, Toggle, Tooltip — och fler. Totalt 30+ komponenter.
Installation sker via CLI, och du väljer precis vilka komponenter du behöver:
npx @react-native-reusables/cli add button card input
Alla komponenter stödjer dark mode direkt ur lådan, fungerar på Android, iOS och web, och kan anpassas helt efter dina behov. Det är en riktigt trevlig utvecklarupplevelse.
gluestack-ui v2
gluestack-ui v2 drivs av NativeWind under huven och erbjuder ett bredare utbud av färdigbyggda komponenter med inbyggda varianter. Benchmarks visar att det lägger på 30–70 ms overhead vid 1 000 komponenter jämfört med rå React Native — helt acceptabelt för de allra flesta appar.
Styla tredjepartskomponenter
En vanlig utmaning är att styla komponenter som inte har inbyggt stöd för className. NativeWind löser det med cssInterop och remapProps.
cssInterop för tredjepartskomponenter
import { cssInterop } from "nativewind";
import { BlurView } from "expo-blur";
import MapView from "react-native-maps";
// Mappa className till style-propen
cssInterop(BlurView, { className: "style" });
cssInterop(MapView, { className: "style" });
// Nu kan du använda Tailwind-klasser direkt
Blurrad bakgrund
Ganska smidigt, eller hur? Bara en rad kod så har du Tailwind-stöd på vilken komponent som helst.
remapProps för komplexa mappningar
Vissa komponenter har flera stilprops. Använd remapProps när du vill mappa className till en specifik prop:
import { remapProps } from "nativewind";
import { LinearGradient } from "expo-linear-gradient";
remapProps(LinearGradient, { className: "style" });
NativeWind v5: Vad som komma skall
NativeWind v5 är i förhandsversion just nu och representerar den största omskrivningen sedan v2. Låt oss kika på det viktigaste.
Minimikrav
- Tailwind CSS 4.1+
- React Native 0.81+
- React Native Reanimated 4+
- New Architecture aktiverat
Som du ser sätter v5 ribban högre vad gäller krav. Det är inte något man uppgraderar till i förbifarten.
Viktigaste förändringarna
CSS-first konfiguration: Tailwind v4 tar bort tailwind.config.js till förmån för konfiguration direkt i CSS. Det ser ut så här:
/* global.css i v5 */
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";
@import "nativewind/theme";
Babel-konfiguration förenklad: I v5 behöver du inte längre nativewind/babel eller jsxImportSource. En ny import-rewrite-mekanism ersätter JSX-transformen. Två konfigurationssteg mindre att hålla koll på.
PostCSS krävs: Skapa postcss.config.mjs:
export default {
plugins: {
"@tailwindcss/postcss": {},
},
};
Nytt styled() API: cssInterop och remapProps ersätts av ett enhetligt API — mycket renare:
import { styled } from "nativewind";
// Ersätter cssInterop
styled(MyComponent, { className: "style" });
// Ersätter remapProps
styled(MyComponent, { className: "style" }, { passThrough: true });
Plattformsmediafrågor: Istället för ios: och android: som klasser stödjer v5 mediafrågor i CSS:
@media ios {
.header { padding-top: 44px; }
}
@media android {
.header { padding-top: 24px; }
}
CSS-animationer via Reanimated 4: NativeWinds egna animeringsmotor ersätts av Reanimated CSS-animationer. Ett steg mot en mer standardbaserad approach.
Ska du migrera till v5 nu?
Kort svar: nej, inte ännu. NativeWind v5 är fortfarande i förhandsversion och inte redo för produktion. Stanna på v4 för produktionsappar och börja bekanta dig med förändringarna i din egen takt. När v5 når stabil release blir migreringen betydligt smidigare om du redan förstår koncepten.
Vanliga misstag och felsökning
Under åren har vissa problem dykt upp om och om igen i NativeWind-communityn. Här är de vanligaste — och hur du löser dem snabbt.
Stilar appliceras inte alls
Det här är nog det vanligaste problemet. Checklista:
- Rensa Metro-cachen:
npx expo start -c - Kontrollera att
global.cssimporteras i din entry-fil - Kör
verifyInstallation()— den pekar oftast ut exakt vad som saknas - Kontrollera att
content-arrayen itailwind.config.jsinkluderar alla relevanta mappar
Textfärg fungerar inte på View
Den här biter många nykomlingar. React Native kaskaderar inte stilar som CSS gör. text-red-500 på en <View> har ingen effekt — klassen måste sitta direkt på <Text>-komponenten.
Stilar appliceras intermittent
Ett känt problem (GitHub issue #924) där stilar ibland inte appliceras vid första Metro-start. Lösningen är att starta om Metro-servern med cache-rensning. Inte idealiskt, men problemet är spårat och åtgärdas.
React Native Web-konflikter
Om React Native Web-stilar överskriver dina Tailwind-klasser, lägg till i tailwind.config.js:
module.exports = {
important: "html",
// ...
};
Metro-konfigurationsfel
Det här är den fälla jag nämnde tidigare. Se till att withNativeWind wrappar din slutgiltiga konfiguration:
// FEL - modifierar config efter withNativeWind
const config = getDefaultConfig(__dirname);
const nwConfig = withNativeWind(config, { input: "./global.css" });
nwConfig.resolver.sourceExts.push("svg"); // Problem!
// RÄTT - modifiera innan withNativeWind
const config = getDefaultConfig(__dirname);
config.resolver.sourceExts.push("svg");
module.exports = withNativeWind(config, { input: "./global.css" });
Ordningen spelar roll. Modifiera alltid config-objektet innan du wrappar det.
Praktiskt exempel: Profilskärm med NativeWind
Dags att knyta ihop säcken med en komplett profilskärm. Den här använder dark mode, responsiv layout och de kortkomponenter vi pratat om:
import { View, Text, Image, ScrollView, Pressable } from "react-native";
import { useColorScheme, colorScheme } from "nativewind";
import { Ionicons } from "@expo/vector-icons";
function SettingsRow({
icon,
label,
value,
}: {
icon: string;
label: string;
value?: string;
}) {
return (
{label}
{value && (
{value}
)}
);
}
export default function ProfileScreen() {
const { colorScheme: scheme } = useColorScheme();
return (
{/* Profilheader */}
Anna Svensson
[email protected]
{/* Inställningssektioner */}
{/* Temväxlare */}
colorScheme.set(scheme === "dark" ? "light" : "dark")
}
className="mx-4 mb-8 items-center rounded-xl bg-indigo-600 py-3 active:bg-indigo-700"
>
Byt till {scheme === "dark" ? "ljust" : "mörkt"} läge
);
}
Vanliga frågor
Är NativeWind långsammare än StyleSheet.create?
Nej. NativeWind v4 kompilerar Tailwind-klasser vid byggtid till StyleSheet.create-objekt. Benchmarks visar att prestandan ligger inom 1% av rå StyleSheet — i vissa tester till och med marginellt snabbare. Du betalar i princip ingen prestandakostnad.
Kan jag använda NativeWind med Expo Router?
Absolut. NativeWind fungerar sömlöst med Expo Router och Expo SDK 55. Importera bara global.css i din rotlayout (app/_layout.tsx) så är du igång. Alla skärmar och komponenter i router-strukturen kan använda Tailwind-klasser direkt.
Vad är skillnaden mellan NativeWind och twrnc?
Största skillnaden är kompileringsmodellen. NativeWind kompilerar vid byggtid, medan twrnc parserar klassnamn vid runtime. Det ger NativeWind en tydlig prestandafördel — särskilt i långa listor och komplex UI. NativeWind har dessutom ett bredare ekosystem med komponentbibliotek som NativewindUI och React Native Reusables.
Hur migrerar jag från StyleSheet.create till NativeWind?
Det fina är att du inte behöver migrera allt på en gång. NativeWind fungerar sida vid sida med StyleSheet.create. Börja med nya komponenter och konvertera befintliga gradvis. Att blanda className med style-propen fungerar problemfritt — NativeWind mergear stilarna automatiskt.
Behöver jag uppgradera till NativeWind v5?
Inte ännu. NativeWind v5 är i förhandsversion och kräver React Native 0.81+, Reanimated 4+ och New Architecture. Stanna på v4 för produktionsappar. Börja bekanta dig med v5:s förändringar — framför allt CSS-first konfiguration och det nya styled()-API:et — så att du är redo när den stabila versionen väl släpps.