--- id: wiki-2026-0508-react-native-web-desktop title: React Native Web — Desktop category: 10_Wiki/Topics status: verified canonical_id: self aliases: [React Native Web Desktop, RNW Desktop, Universal RN] duplicate_of: none source_trust_level: A confidence_score: 0.85 verification_status: applied tags: [react-native, react-native-web, desktop, cross-platform, frontend] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: TypeScript framework: React Native Web --- # React Native Web — Desktop ## 매 한 줄 > **"매 한 codebase 의 mobile + desktop"**. React Native Web (RNW) 매 RN component 를 DOM 으로 render — Expo Web 또는 standalone Vite/Next.js 셋업으로 매 desktop browser target. 2026 기준 Expo Router v4 + RN 0.76 New Architecture 매 stable, Bridgeless 매 web 의 hot reload 빠름. Tamagui / NativeWind 매 styling 의 cross-platform. ## 매 핵심 ### 매 왜 desktop 의 RNW - 매 mobile-first 의 enterprise dashboard / electron 대체. - 매 single team / single component library. - Server-side render (Next.js + RNW 0.19+) 매 SEO 가능. - Tablet / iPad split-view 의 fluid layout. ### 매 vs alternatives - **Electron**: 매 heavy bundle, native shell, 매 different mental model. - **Tauri**: 매 Rust + WebView — 매 React but 매 RN component X. - **PWA + responsive**: 매 web-first, mobile compromise. - **RNW**: 매 mobile-first, desktop adapt. ### 매 응용 1. Expo Router universal app — iOS + Android + Web (single team). 2. Internal tool / admin — RN component library 재사용. 3. Linear/Notion-style desktop app — RNW + Tauri shell. 4. Marketing site + app — same brand component. ## 💻 패턴 ### Expo Router universal entry ```tsx // app/_layout.tsx import { Stack } from "expo-router"; import { useDeviceOrientation } from "@react-native-community/hooks"; export default function Layout() { return ( ); } ``` ### Platform-specific file (`.web.tsx`) ```tsx // FilePicker.tsx (mobile) // FilePicker.web.tsx (desktop) // FilePicker.web.tsx import { useRef } from "react"; import { Pressable, Text } from "react-native"; export function FilePicker({ onPick }: { onPick: (f: File) => void }) { const inputRef = useRef(null); return ( <> inputRef.current?.click()}> Pick file e.target.files?.[0] && onPick(e.target.files[0])} /> ); } ``` ### Responsive layout (useWindowDimensions) ```tsx import { View, useWindowDimensions } from "react-native"; export function Layout({ children }: { children: React.ReactNode }) { const { width } = useWindowDimensions(); const isDesktop = width >= 1024; return ( {isDesktop && } {children} ); } ``` ### Keyboard shortcuts (web only) ```tsx import { useEffect } from "react"; import { Platform } from "react-native"; export function useShortcut(key: string, handler: () => void) { useEffect(() => { if (Platform.OS !== "web") return; const fn = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === key) { e.preventDefault(); handler(); } }; window.addEventListener("keydown", fn); return () => window.removeEventListener("keydown", fn); }, [key, handler]); } ``` ### Hover state (`Pressable` web-only) ```tsx import { Pressable, Text } from "react-native"; ({ backgroundColor: pressed ? "#e0e0e0" : hovered ? "#f0f0f0" : "white", padding: 12, borderRadius: 8, })} > {() => Hover me (web)} ``` ### Tamagui styling (cross-platform) ```tsx import { Button, Stack, Text } from "tamagui"; export function Card() { return ( Title ); } ``` ### Next.js + RNW (SSR setup) ```js // next.config.js const { withExpo } = require("@expo/next-adapter"); module.exports = withExpo({ transpilePackages: ["react-native", "react-native-web", "expo"], experimental: { forceSwcTransforms: true }, }); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Mobile + desktop, same product | Expo Router universal | | Native desktop window/menu | Electron / Tauri (RNW inside Tauri OK) | | Heavy animations | Reanimated 4 (web target supported) | | Styling | Tamagui / NativeWind | | SSR/SEO | Next.js + RNW | | Mobile only | plain RN (no RNW) | **기본값**: Expo Router + Tamagui — 매 mobile-first, desktop 매 responsive breakpoint. ## 🔗 Graph - 부모: [[React Native]] - 변형: [[Expo Router]] - 응용: [[Universal-App]] - Adjacent: [[Tauri]] · [[Electron]] ## 🤖 LLM 활용 **언제**: mobile-first product 의 desktop site, internal tool with RN library, universal team. **언제 X**: desktop-only 의 native window/menu/system tray — 매 Electron/Tauri. ## ❌ 안티패턴 - **`document.getElementById` 직접 사용**: 매 mobile crash. Platform.OS gate 필수. - **Mobile-only 라이브러리 import**: 매 web bundle 의 fail. `.web.tsx` split. - **Fixed pixel layout**: 매 desktop wide screen 매 broken. Flex / max-width. - **No keyboard navigation**: 매 desktop a11y 폭망. ## 🧪 검증 / 중복 - Verified (Expo SDK 51+ docs, react-native-web 0.19+ docs, Tamagui docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Expo Router, .web.tsx, hover/shortcut, Tamagui, Next adapter 패턴 |