Expo React Native Web 사용법: 앱을 웹으로 확장하기

2026.04.22·수정 2026.07.20·약 11분

핵심 답 먼저

Expo 앱은 React Native Web을 통해 웹으로 실행할 수 있습니다. 다만 모든 네이티브 코드가 자동으로 브라우저에서 동작하는 것은 아닙니다. React Native 기본 컴포넌트와 웹 지원 라이브러리는 공유하고, 네이티브 전용 모듈·브라우저 DOM·접근성·라우팅 차이는 Platform 분기나 .web.tsx 파일로 격리해야 합니다. 개발 실행은 npx expo start --web, 배포용 내보내기는 npx expo export --platform web이 기준입니다.

React Native Web과 Expo는 어떻게 연결되는가

React Native Web은 View, Text, Pressable 같은 React Native 컴포넌트를 브라우저의 React DOM 요소로 연결합니다. Expo의 웹 개발 공식 문서는 React Native Web을 여러 플랫폼에서 코드를 재사용할 때 적합한 선택으로 설명합니다. 웹뷰에 앱 화면을 넣는 방식이 아니라, 같은 React 컴포넌트가 웹 대상 코드로 번들링되는 방식입니다.

Expo와 React Native Web이 공용 컴포넌트를 브라우저 DOM으로 연결하는 구조
구성 요소 역할 확인할 점
React Native 공용 컴포넌트와 API 계약 해당 API가 웹 구현을 제공하는지
React Native Web React Native API를 DOM·CSS로 연결 네이티브와 다른 이벤트·스타일·접근성 동작
Expo CLI·Metro 웹 의존성 설치, 개발 서버, 번들·내보내기 프로젝트 Expo SDK와 맞는 패키지 버전
Expo Router Android·iOS·웹 공용 파일 기반 라우팅 웹 출력 방식, 정적 경로, 서버 기능 경계

새 프로젝트와 기존 프로젝트에서 웹 실행하기

최신 Expo 템플릿은 웹 구성을 포함하지만, 기존 프로젝트에서는 웹 의존성이 빠져 있을 수 있습니다. 일반 npm install로 임의 버전을 고정하기보다 npx expo install을 사용해 현재 Expo SDK와 호환되는 버전을 설치합니다. 공식 문서의 현재 기본 명령은 다음과 같습니다.

# 기존 프로젝트에 웹 의존성이 없다면 설치
npx expo install react-dom react-native-web @expo/metro-runtime

# 브라우저 개발 서버
npx expo start --web

# 배포용 웹 산출물 생성
npx expo export --platform web

실행되지 않을 때 먼저 볼 항목

  • npx expo-doctor로 Expo SDK와 의존성 정합성을 확인합니다.
  • 오류가 난 패키지가 웹을 지원하는지 패키지 공식 문서와 React Native Directory를 확인합니다.
  • 브라우저 전역 객체인 window·document를 모듈 최상위에서 읽어 서버·정적 렌더링을 깨뜨리지 않았는지 봅니다.
  • 네이티브 전용 권한이나 하드웨어 API를 화면 첫 렌더에서 바로 호출하지 않았는지 확인합니다.

공용 UI는 지원되는 최소 교집합으로 작성한다

공유 화면의 중심은 React Native 컴포넌트와 StyleSheet로 두고, 플랫폼별 기능은 가장자리로 밀어냅니다. 웹에서는 마우스뿐 아니라 키보드와 스크린리더 사용자를 고려해야 하므로 누를 수 있는 요소에 역할과 접근 가능한 이름을 제공합니다.

import { Pressable, StyleSheet, Text, View } from 'react-native';

export function ProductCard({ onOpen }: { onOpen: () => void }) {
  return (
    <View style={styles.card} role="article">
      <Text role="heading" aria-level={2} style={styles.title}>
        공용 상품 카드
      </Text>
      <Pressable
        onPress={onOpen}
        role="button"
        aria-label="상품 상세 열기"
        style={styles.button}
      >
        <Text>상세 보기</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  card: { gap: 12, padding: 16 },
  title: { fontSize: 20, fontWeight: '700' },
  button: { minHeight: 44, justifyContent: 'center' },
});

React Native Web 접근성 문서rolearia-* 속성이 의미 있는 HTML과 접근성 정보로 연결되는 방식을 설명합니다. 네이티브에서 보인다고 웹의 키보드 초점·링크 의미·헤딩 구조까지 자동으로 맞는 것은 아닙니다.

작은 차이는 Platform, 큰 차이는 .web 파일로 분리한다

공식 Platform 문서에서 브라우저의 Platform.OS 값은 web입니다. 간격이나 이벤트처럼 작은 차이는 Platform.select로 처리할 수 있습니다. 구현 자체가 다르면 조건문을 길게 늘이기보다 플랫폼 파일을 나누는 편이 안전합니다.

import { Platform, StyleSheet } from 'react-native';

export const styles = StyleSheet.create({
  page: {
    padding: Platform.select({ web: 24, default: 16 }),
    maxWidth: Platform.OS === 'web' ? 960 : undefined,
    width: '100%',
    alignSelf: 'center',
  },
});
ShareButton.tsx         # Android·iOS 기본 구현
ShareButton.web.tsx     # 브라우저 Web Share API 또는 복사 대체 구현

import ShareButton from './ShareButton';
# 같은 import가 플랫폼에 맞는 파일을 선택

React Native Web의 멀티플랫폼 설정 문서도 작은 차이는 Platform, 큰 차이는 *.web.js 같은 플랫폼 파일로 분리하도록 안내합니다.

네이티브 전용 모듈은 대체 동작을 설계한다

문제 유형 웹에서의 증상 대응
네이티브 모듈만 제공 모듈 해석 실패 또는 런타임 오류 .web.tsx 대체 구현, 동적 로딩, 기능 비활성화
파일·카메라·위치 권한 차이 권한 UX와 반환값이 다름 웹 API 지원 여부 탐지와 거부·미지원 상태 UI
DOM 라이브러리 사용 네이티브 번들에서 document 오류 웹 전용 파일 안으로 격리
터치 제스처만 검증 키보드로 조작 불가 초점, Enter·Space, 접근 가능한 이름 검증
공용 코드와 웹 전용 코드의 분리 기준 및 검증 흐름

라우팅·레이아웃·접근성은 웹 기준을 따로 검증한다

앱 화면 이동과 웹 URL은 요구사항이 다릅니다. 새로고침해도 같은 경로가 열리는지, 브라우저 뒤로 가기와 직접 URL 접근이 되는지, 정적 호스팅에서 경로 재작성 설정이 맞는지 확인해야 합니다. 파일 기반 공용 라우팅이 필요하면 Expo Router 공식 문서를 기준으로 설계합니다.

  • 레이아웃: 390px 모바일, 태블릿, 1440px 데스크톱에서 가로 스크롤과 과도한 최대 폭을 확인합니다.
  • 입력: 터치·마우스·키보드로 같은 핵심 작업을 완료할 수 있는지 봅니다.
  • 의미: 헤딩, 버튼, 링크, 폼 레이블이 브라우저 접근성 트리에 전달되는지 확인합니다.
  • URL: 깊은 경로 직접 진입, 새로고침, 404 처리, 공유 링크를 검증합니다.
  • SEO: 검색 유입이 필요한 페이지는 클라이언트 전용 SPA와 정적 HTML 출력의 차이를 검토합니다.

single·static·server 출력과 서버 기능의 경계

Expo 웹사이트 배포 공식 문서는 Expo Router 웹 출력 방식을 다음처럼 구분합니다. 프로젝트 버전에 따라 지원 상태가 달라질 수 있으므로 실제 Expo SDK 문서와 app.json을 함께 확인합니다.

web.output 산출물 적합한 상황
single 단일 SPA HTML 앱형 화면, 호스팅의 모든 경로 재작성 가능
static 경로별 정적 HTML SEO·초기 HTML이 중요한 공개 콘텐츠
server 클라이언트와 서버 번들 API Routes 등 서버 실행이 필요한 경우
{
  "expo": {
    "web": {
      "bundler": "metro",
      "output": "static"
    }
  }
}
# dist 디렉터리에 웹 산출물 생성
npx expo export --platform web

# 생성 결과를 로컬에서 프로덕션 방식으로 확인
npx expo serve

정적 파일만 올리는 호스팅은 서버 API를 실행하지 못합니다. 비밀키를 클라이언트 코드에 넣어 서버 기능처럼 사용해서도 안 됩니다. API Routes를 쓰려면 Expo API Routes 공식 문서에 따라 server 출력과 호스팅 런타임을 준비해야 합니다.

브라우저와 모바일을 함께 검증하는 체크리스트

  1. expo-doctor와 타입 검사를 통과시키고 웹 번들 오류를 0건으로 만듭니다.
  2. Chrome·Safari·Firefox 중 지원 대상 브라우저에서 핵심 경로를 직접 실행합니다.
  3. Android·iOS에서도 공용 컴포넌트의 회귀가 없는지 같은 시나리오를 확인합니다.
  4. 키보드만으로 메뉴, 폼, 모달, 주요 버튼을 조작하고 초점 표시를 확인합니다.
  5. 직접 URL·새로고침·뒤로 가기·404와 배포된 정적 자산 경로를 확인합니다.
  6. 네이티브 전용 기능은 미지원·권한 거부·API 실패 상태에서도 복구 가능한 UI를 제공합니다.

결론과 내부 학습 경로

결론: Expo Web 전환 가능 여부는 화면 개수보다 의존성의 웹 지원, 플랫폼 API 격리, URL·접근성·배포 방식에서 결정됩니다. 공용 UI를 먼저 실행하고 네이티브 전용 기능을 목록화한 뒤, 작은 차이는 Platform, 큰 차이는 .web.tsx로 분리하는 순서가 가장 안전합니다.

  1. Expo Router 사용법으로 공용 URL과 Stack·Tabs 구조를 설계합니다.
  2. Expo Safe Area 사용법으로 모바일 화면 여백 차이를 처리합니다.
  3. Expo WebBrowser 사용법으로 외부 링크와 로그인 복귀 흐름을 정리합니다.
  4. Expo EAS Build 오류 해결에서 로컬과 원격 빌드 환경 차이를 점검합니다.

이 글이 마음에 드세요?

RSS 피드를 구독하세요!

“Expo React Native Web 사용법: 앱을 웹으로 확장하기”에 대한 1개의 생각

댓글 남기기