Expo를 설치하고 첫 앱 화면을 실행하려면 어떤 순서로 준비하나요?
Node.js·npm을 확인하고 blank-typescript 템플릿으로 Expo 앱을 만듭니다. 개발 서버를 켜 기기·에뮬레이터·웹에서 연 뒤, App.tsx의 View·Text와 StyleSheet로 화면을 바꿉니다.
적용 조건·범위: Expo 개발 환경 문서는 Expo Go를 학습·빠른 실험용 환경으로 설명합니다. 네이티브 모듈이나 실제 배포를 다루는 프로젝트에서는 프로젝트 전용 development build로 넘어가는 것이 기준입니다. 이 글에서는 기본 컴포넌트 학습이 목적이므로 Expo Go로 시작합니다.
본문 근거: 프로젝트 생성 · Expo 개발 환경 문서 · 개발 서버 실행
이 글에서 배우는 내용
Expo를 처음 시작하는 독자가 개발 환경을 건너뛰지 않도록 Node/npm 확인 → create-expo-app → 개발 서버 실행 → 실제 화면 확인 → 기본 컴포넌트 학습 순서로 진행합니다. 설치만 끝내는 것이 아니라, 내 코드가 기기나 에뮬레이터에서 실제로 열리는 지점까지를 첫 단계로 봅니다.
목차
목차
- 선수 지식과 개발 환경 준비
- 첫 Expo 프로젝트 생성하기
- 실제 기기·에뮬레이터에서 첫 실행 확인하기
- View·Text로 첫 화면 작성하기
- StyleSheet와 Flexbox 읽기
- 작은 실습으로 변경 결과 확인하기
- 다음 학습으로 이어가기
선수 지식과 개발 환경 준비
Expo 공식 시작 문서는 Node.js LTS, 코드 편집기, 터미널을 기본 준비 사항으로 안내합니다. Windows, macOS, Linux에서 프로젝트를 만들 수 있으며, 처음에는 별도의 전역 Expo CLI를 설치할 필요 없이 npx로 시작할 수 있습니다.
터미널
node --version
npm --version
두 명령 모두 버전이 출력되면 기본 준비는 끝났습니다. 명령을 찾을 수 없다는 오류가 나오면 Node.js 공식 사이트에서 LTS 버전을 설치한 뒤 터미널을 다시 열어 확인하세요. npm은 Node.js를 설치하면 함께 설치됩니다.
| 실행 방법 | 처음 사용할 때 | 알아둘 점 |
|---|---|---|
| 실제 Android·iOS 기기 + Expo Go | 가장 빠르게 기본 앱을 확인할 때 | Expo는 실제 기기 개발을 권장하며, 컴퓨터와 기기가 같은 네트워크에 있으면 연결이 편합니다. |
| Android Emulator | PC에서 Android 화면을 반복 확인할 때 | Android Studio와 에뮬레이터 설정이 필요합니다. |
| iOS Simulator | Mac에서 iOS 화면을 확인할 때 | macOS와 Xcode가 필요합니다. Windows에서는 iOS Simulator를 실행할 수 없습니다. |
| 웹 브라우저 | 레이아웃과 코드 변경을 빠르게 확인할 때 | 네이티브 권한·Safe Area·키보드 동작까지 검증한 것은 아닙니다. |
Expo 개발 환경 문서는 Expo Go를 학습·빠른 실험용 환경으로 설명합니다. 네이티브 모듈이나 실제 배포를 다루는 프로젝트에서는 프로젝트 전용 development build로 넘어가는 것이 기준입니다. 이 글에서는 기본 컴포넌트 학습이 목적이므로 Expo Go로 시작합니다.
첫 Expo 프로젝트 생성하기
빈 TypeScript 프로젝트를 하나 만들어 기본 구조부터 확인합니다. create-expo-app 공식 문서에서 제공하는 blank-typescript 템플릿을 사용하므로 Expo Router가 포함된 기본 템플릿과 파일 위치가 다릅니다.
터미널
npx create-expo-app@latest first-screen --template blank-typescript
cd first-screen
npx expo install react-dom react-native-web
첫 명령은 first-screen 폴더에 새 Expo 앱을 만들고 필요한 패키지를 설치합니다. 두 번째 명령으로 프로젝트 폴더에 들어간 뒤, 마지막 명령은 웹 실행에 필요한 의존성을 현재 Expo SDK와 호환되는 버전으로 맞춰 설치합니다. 프로젝트 생성 중 만들어진 package.json과 package-lock.json은 함께 보관하세요.
이 템플릿은 루트 App.tsx를 화면 진입점으로 사용하고 index.ts가 App을 등록합니다. app.json은 앱 이름·아이콘 같은 설정, tsconfig.json은 TypeScript 설정입니다. Router 템플릿을 이미 사용 중이라면 루트 App.tsx가 진입점이 아닐 수 있으므로 기존 라우트 화면 파일을 수정해야 합니다.
실제 기기·에뮬레이터에서 첫 실행 확인하기
코드를 수정하기 전에 생성된 기본 앱이 먼저 열리는지 확인합니다. 프로젝트 루트에서 개발 서버를 시작하세요.
터미널
npx expo start
터미널에 QR 코드와 실행 단축키가 나타납니다. 첫 화면을 확인하는 방법은 다음과 같습니다.
| 대상 | 실행 방법 | 성공 기준 |
|---|---|---|
| 실제 기기 | Expo Go를 설치하고 터미널의 QR 코드를 스캔 | Expo Go 안에서 현재 프로젝트 화면이 열림 |
| Android Emulator | 에뮬레이터를 켠 뒤 터미널에서 a |
에뮬레이터에 프로젝트가 열림 |
| iOS Simulator | Mac에서 Simulator를 준비한 뒤 터미널에서 i |
Simulator에 프로젝트가 열림 |
| 웹 | 터미널에서 w |
브라우저에 프로젝트 화면이 열림 |
실제 기기 연결이 안 되면 먼저 컴퓨터와 휴대폰이 같은 Wi-Fi인지 확인합니다. 공용망이나 공유기 설정 때문에 LAN 연결이 막히는 경우에는 아래처럼 Tunnel을 사용할 수 있습니다. Tunnel은 일반 LAN 연결보다 느릴 수 있으므로 연결 문제가 있을 때만 사용하는 편이 좋습니다.
터미널
npx expo start --tunnel
여기까지 성공했다면 개발 환경 준비는 끝난 것입니다. 이제부터 코드를 바꿨을 때 화면이 갱신되는 개발 흐름을 확인합니다.

View·Text로 첫 화면 작성하기
아래 코드는 외부 이미지나 별도 컴포넌트 없이 실행됩니다. 가장 바깥 View는 화면 전체, 안쪽 View는 흰 카드입니다. 문자열은 각각 Text 안에 넣습니다. HTML처럼 View 바로 아래에 문자열을 그대로 두지 않는 점이 중요합니다.
App.tsx
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.screen}>
<View style={styles.card}>
<Text style={styles.eyebrow}>오늘의 학습</Text>
<Text style={styles.title}>첫 Expo 화면</Text>
<Text style={styles.description}>
View로 묶고 Text로 읽으며 StyleSheet로 배치합니다.
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
backgroundColor: '#eef2f7',
},
card: {
width: '100%',
maxWidth: 420,
padding: 24,
gap: 12,
borderRadius: 16,
backgroundColor: '#ffffff',
},
eyebrow: { fontSize: 14, color: '#3154a5' },
title: { fontSize: 26, fontWeight: '700', color: '#182230' },
description: { fontSize: 16, lineHeight: 24, color: '#475467' },
});
저장한 뒤 앞에서 열어 둔 Expo Go·에뮬레이터·브라우저 화면을 확인합니다. “오늘의 학습”, “첫 Expo 화면”, 설명 문장이 보이면 코드 변경까지 정상적으로 연결된 것입니다. 제목을 한 번 바꿔 저장하고 화면이 다시 갱신되는지도 확인하세요.
StyleSheet와 Flexbox 읽기
React Native 스타일 문서에 따르면 style은 JavaScript 객체를 받으며 속성 이름은 backgroundColor처럼 camelCase로 씁니다. CSS 파일의 선택자를 이 객체에 쓰지 않습니다. padding: 24처럼 길이는 보통 숫자로 지정하며, width: '100%'처럼 비율을 표현하는 지원 속성에는 문자열을 사용합니다.
| 코드 | 화면에서의 역할 | 확인할 점 |
|---|---|---|
| flex: 1 | 부모가 준 공간을 채움 | 자식만 flex를 넣어도 부모 크기가 없는 문제까지 해결되는 것은 아님 |
| justifyContent: ‘center’ | 주축 가운데 배치 | 기본 세로 방향에서는 위아래 가운데 |
| alignItems: ‘center’ | 교차축 가운데 배치 | 기본 세로 방향에서는 좌우 가운데 |
| width: ‘100%’, maxWidth: 420 | 작은 화면에서는 너비를 채우고 큰 화면에서는 제한 | 고정 너비만 사용해 좁은 화면을 넘치지 않게 함 |
| gap: 12 | 카드 안 Text 사이 간격 | 각 글자 자체의 줄간격은 lineHeight가 담당 |
React Native Flexbox 문서에서 기본 flexDirection은 column입니다. 웹 Flexbox의 기본 row를 떠올리면 정렬 방향을 거꾸로 해석하기 쉽습니다. screen의 padding을 늘리면 카드 바깥 여백, card의 padding을 늘리면 카드 안쪽 여백이 변합니다.

작은 실습으로 변경 결과 확인하기
App.tsx의 screen.justifyContent를 flex-start로 바꾸면 카드가 위쪽으로 이동합니다. alignItems만 바꿨는데 차이가 작다면 card의 width: '100%'가 가용 너비를 채우기 때문입니다. card.width를 잠시 '80%'로 바꾸고 center와 flex-start를 비교한 다음 원래 코드로 되돌려 보세요.
Text strings must be rendered within a <Text> component 오류가 나오면 View 바로 아래에 문자열이나 불필요한 문자가 있는지 먼저 확인합니다. 이 오류는 패키지를 재설치하거나 캐시를 지우는 문제가 아니라 화면 구조 문제입니다.
마지막으로 제목을 원하는 문구로 바꾸고, 설명 문장을 두 배 정도 길게 만든 뒤 실제 기기나 에뮬레이터에서 줄바꿈과 카드 높이가 자연스럽게 변하는지 확인합니다. 이 작은 수정까지 성공하면 프로젝트 생성 → 실행 → 코드 변경 → 화면 확인의 기본 개발 루프를 한 번 경험한 것입니다.
다음 학습으로 이어가기
기본 화면을 확인한 뒤에는 타입 검사와 번들 생성도 구분해서 볼 수 있습니다.
터미널
npx tsc --noEmit
npx expo export --platform android --output-dir dist-android
npx expo export --platform web --output-dir dist-web
타입 검사는 TypeScript 오류를 확인하고, expo export는 배포용 JavaScript 번들을 생성합니다. Android export로 생긴 번들은 설치용 APK와 다릅니다. APK를 직접 설치하는 과정은 이 과정 후반의 EAS Build 글에서 별도로 다룹니다.
화면이 열렸다면 다음 글인 Expo Safe Area 사용법으로 이어가세요. 첫 글의 고정 padding은 기기별 노치·상태 표시줄 같은 안전 영역을 대신하지 않으므로, 다음 단계에서 시스템 영역과 콘텐츠 여백을 분리해 학습합니다.
시작·완성 예제 파일
ZIP에는 시작본(starter), 완성본(complete), 실행 안내가 들어 있습니다. 압축을 푼 뒤 README의 준비 사항과 실행 순서를 확인하세요.
이 첫 화면 실습은 개발 서버와 Expo Go·에뮬레이터·웹 중 준비된 실행 환경에서 확인합니다. EAS 계정 연결과 설치용 APK 생성은 뒤의 빌드 회차에서 진행합니다.
문서·검증 기준 (2026-09-16): Expo의 프로젝트 생성, 개발 환경 설정, 개발 서버 실행, create-expo-app 공식 문서를 기준으로 설치·실행 순서를 재검수했습니다. 실제 Android·iOS 기기 실행과 에뮬레이터 구동은 이번 개정에서 직접 수행하지 않았으며, 해당 부분은 공식 문서의 실행 절차를 기준으로 안내합니다.
선택 실습: 할 일 앱에 적용하기
TaskFlow Mobile은 할 일을 관리하는 모바일 앱입니다. 이 선택 실습에서는 기존 앱에 이번 기능을 이어서 적용합니다.
예상 확인: Android Expo Go/에뮬레이터에서는 목록과 수정한 제목이 보이는 것이 목표입니다. 웹은 선택 확인 항목이며 iOS는 별도 기기가 필요합니다.
누적 프로젝트: TaskFlow Mobile
시작 위치: 아래 기존 환경·파일 구성에서 시작합니다. 이 글의 완료 ZIP은 결과 확인용입니다.
기존 첫 화면 starter·complete ZIP에서 starter로 시작합니다. 이 ZIP은 모든 TaskFlow 회차의 누적 완료본이 아닙니다.
실제 첫 화면 ZIP의 starter를 새 폴더에 풀고 README대로 준비합니다. 아래 App.tsx 전체 파일을 저장합니다. 이 글은 누적 과정 첫 회차라 이전 TaskFlow 완료본이 필요 없습니다. 제목을 바꾸면 목록이 바뀌어야 합니다.
전체 파일·코드 보기
App.tsx — 이번 회차 전체 파일
import { Text, View } from 'react-native';
type Task = { id: string; title: string; completed: boolean };
const tasks: Task[] = [{ id: '1', title: '첫 작업', completed: false }];
export default function App() {
return <View style={{ flex: 1, justifyContent: 'center', padding: 24 }}>
<Text>TaskFlow Mobile</Text>
{tasks.map(task => <Text key={task.id}>{task.title}</Text>)}
</View>;
}
다음 회차로 넘길 상태: 위 추가·수정 파일을 적용한 로컬 연습 폴더입니다. 실제 실행한 플랫폼과 결과를 기록하고 원래 독립 ZIP과 구분해 보관합니다.
아래 원래 과제의 확장 방향은 위 전체 파일이 제공하는 범위와 구분해 읽습니다. 아이콘 액션 확장·실제 세션 인증·background tracking은 추가 구현 과제입니다.
회차별 확장 질문과 확인 기준
독자 질문: View와 Text로 만든 첫 화면은 Expo Go에서 어떻게 확인하나요?
앱에서 따라 하기
- Node/npm을 확인하고 blank-typescript 기반 TaskFlow Mobile을 만든 뒤 개발 서버를 엽니다.
- App.tsx에 Task 타입, 예시 작업 목록, View·Text·StyleSheet 화면을 넣고 QR로 Expo Go에 접속합니다.
- 작업 제목을 한 개 바꿔 Fast Refresh 반영 여부를 봅니다.
기기·빌드별 확인
예상 확인: Android Expo Go/에뮬레이터에서는 목록과 수정한 제목이 보이는 것이 목표입니다. 웹은 선택 확인 항목이며 iOS는 별도 기기가 필요합니다.
실행 확인 범위: 위의 예상 동작은 직접 따라 할 때 확인할 기준입니다. Android/iOS 기기·에뮬레이터, 웹 브라우저, development build, EAS 원격 빌드와 APK 설치의 실제 결과는 미확인입니다. 환경별로 실행한 뒤 화면, 오류 로그, 빌드 상태를 각각 확인하세요.
오류 점검과 다음 학습
Metro 연결 실패는 같은 네트워크와 실행 주소를 확인하고, 문자열을 View에 직접 둔 오류는 Text로 감쌉니다.
글 소개·학습 준비·전체 목차
학습 목표·선수 지식: Node.js LTS와 npm이 준비됐는지 확인하고, 새 Expo 프로젝트를 만든 뒤 실제 기기·에뮬레이터·웹 중 하나에서 첫 실행을 확인합니다. 이후 View·Text·StyleSheet로 첫 화면을 직접 수정합니다. React JSX와 TypeScript의 import 문법을 알고 있으면 따라가기 쉽습니다.
이 글이 도움이 되었나요?
읽음 기록
읽음 — / 전체 13개 · 필수 9개
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.