크로스플랫폼 프레임워크
고친 사람 github-actions[bot]
크로스플랫폼 프레임워크는 코드 한 벌로 여러 운영체제에서 도는 앱을 만들게 해 줍니다. iPhone 앱과 Android 앱을 따로 짜지 않고 한 번 짜서 둘 다에 올립니다. 운영체제마다 다른 부분은 프레임워크가 맡아 맞춰 줍니다.
쉽고 빠른 이해
무슨 일을 하는 도구인가 — 앱 코드를 한 번 짜면 iPhone 과 Android 양쪽에서 돌게 해 줍니다. 쇼핑 앱의 상품 목록 화면을 한 번 만들면 두 운영체제의 앱에 같은 화면이 뜹니다.
왜 이렇게 하나 — 운영체제마다 앱을 짜는 언어와 도구가 다릅니다. 따로 짜면 같은 기능을 두 번 만들고 두 번 고칩니다. 한쪽만 고치면 두 앱의 동작이 어긋납니다.
어떻게 도나
- 개발자는 프레임워크가 정한 언어 하나로 화면과 로직을 짭니다
- 프레임워크가 그 코드를 운영체제마다 도는 앱으로 묶어 냅니다
- 버튼을 그리거나 카메라를 여는 일은 프레임워크가 운영체제에 맞게 바꿔 부릅니다
대가 — 운영체제가 새 기능을 내놓으면 프레임워크가 따라올 때까지 기다립니다. 앱 용량이 커집니다. 문제를 찾을 곳도 하나 늘어납니다. 운영체제 전용 기능은 결국 그 운영체제의 언어로 따로 짭니다.
언제 고르나 — iPhone 과 Android 에 함께 낼 앱을 적은 개발자로 만들 때 고릅니다. 한 운영체제에만 낼 앱이나 운영체제 기능을 깊이 쓰는 앱에는 맞지 않습니다.
상세
나라마다 콘센트 모양이 다릅니다. 여행자는 충전기를 나라 수만큼 사지 않습니다. 충전기는 하나만 들고 가서 그 나라 콘센트에 맞는 어댑터를 끼웁니다.
크로스플랫폼 프레임워크(cross-platform framework)는 앱 개발에서 이 어댑터를 맡습니다. 충전기가 개발자가 짠 앱 코드입니다. 콘센트가 iPhone 이나 Android 같은 운영체제입니다.
플랫폼은 앱이 올라가 도는 바탕을 말합니다. 대개 운영체제를 가리킵니다. iPhone 의 iOS, Android, 데스크톱의 Windows · macOS · Linux, 그리고 웹 브라우저가 저마다 하나의 플랫폼입니다. 크로스플랫폼은 이 플랫폼 여럿을 가로지른다는 뜻입니다.
프레임워크는 앱의 뼈대를 미리 짜 둔 코드 묶음입니다. 개발자는 그 뼈대가 정한 곳에 자기 코드를 끼워 넣습니다. 백엔드의 Spring 이 같은 모양입니다. 요청은 Spring 이 받습니다. 개발자는 컨트롤러만 짜 넣습니다.
이 절은 운영체제마다 앱을 따로 짜던 사정에서 출발합니다. 그다음 프레임워크가 화면을 그리는 세 방식과 운영체제 기능을 부르는 통로를 봅니다. 끝으로 한 벌로 짜서 치르는 값과 이 방식을 고르는 경우를 봅니다.
운영체제마다 따로 짜던 앱
운영체제를 만든 회사는 앱을 짜는 언어와 도구를 함께 내놓습니다. iPhone 앱은 대개 Swift 로, Android 앱은 대개 Kotlin 으로 짭니다.
이렇게 운영체제마다 그 회사의 도구로 짠 앱을 네이티브 앱이라고 부릅니다. 네이티브 앱은 운영체제가 내주는 화면 부품과 기능을 바로 씁니다. 버튼 하나도 운영체제가 내준 버튼입니다.
문제는 두 운영체제에 같은 앱을 낼 때 생깁니다. 로그인 화면을 Swift 로 한 번, Kotlin 으로 한 번 짭니다. 대개 팀도 둘로 나뉩니다. 한쪽만 고치면 두 앱의 동작이 어긋납니다.
크로스플랫폼 프레임워크는 이 두 벌을 한 벌로 줄입니다. 개발자는 프레임워크가 정한 언어 하나로 짭니다. 운영체제마다 다른 부분은 프레임워크가 맡습니다.
JVM 과 닮은 생각
백엔드 개발자에게는 익숙한 생각입니다. Java 코드는 JVM(Java Virtual Machine, 자바 가상 머신) 위에서 돕니다. JVM 이 운영체제마다 따로 있어서 같은 코드가 Windows 에서도 Linux 에서도 돕니다.
크로스플랫폼 프레임워크도 앱 코드와 운영체제 사이에 끼어 차이를 감춥니다. 다른 점은 감출 것에 화면이 들어간다는 것입니다. 서버 코드는 파일과 네트워크를 주로 다룹니다. 앱은 버튼 모양과 화면 전환, 터치에 반응하는 방식까지 운영체제마다 다릅니다.
화면을 그리는 세 방식
프레임워크마다 크게 갈리는 것은 화면을 누가 그리느냐입니다. 방식은 셋으로 나뉩니다. 웹 화면을 띄우는 방식, 운영체제의 화면 부품을 빌리는 방식, 프레임워크가 직접 그리는 방식입니다. 아래 세 소절이 하나씩 풀고 끝에 한 그림으로 모읍니다.
웹뷰에 웹 화면을 띄우는 방식
웹뷰는 운영체제가 내주는 작은 브라우저 창입니다. 앱은 이 창을 빌려 자기 안에 끼워 넣습니다. 이 방식은 화면을 웹 페이지로 만듭니다. HTML(HyperText Markup Language, 웹 페이지의 뼈대를 적는 언어)과 JavaScript 로 짠 화면을 웹뷰에 띄웁니다.
웹 개발자가 가진 기술을 바로 씁니다. 대신 버튼과 화면 전환이 웹 페이지처럼 움직입니다. 그래서 운영체제의 앱과 손에 닿는 느낌이 다릅니다. 이렇게 만든 앱을 하이브리드 앱이라고 부르기도 합니다.
운영체제의 화면 부품을 빌리는 방식
화면 부품은 버튼, 글자 입력 칸, 목록처럼 화면을 이루는 낱개 조각입니다. 운영체제는 이 부품을 저마다 내줍니다. 이 방식에서는 개발자가 「버튼을 놓아라」라고 적으면 프레임워크가 그 운영체제의 버튼을 만들어 놓습니다.
iPhone 에서는 iPhone 의 버튼이, Android 에서는 Android 의 버튼이 뜹니다. 그래서 앱이 운영체제마다 그 운영체제다운 모양을 띱니다. 두 운영체제의 부품이 조금씩 달라서 같은 코드가 양쪽에서 미세하게 다르게 보이기도 합니다.
앱 코드와 운영체제 사이에는 브리지가 섭니다. 브리지는 서로 다른 두 언어 사이에서 호출을 넘겨 주는 연결 코드입니다. 예를 들어 React Native 는 앱 코드를 JavaScript 로 짭니다. 운영체제의 부품은 Swift 나 Kotlin 쪽에 있습니다. 브리지가 둘 사이에서 「버튼을 만들어라」 같은 요청을 옮겨 줍니다.
프레임워크가 직접 그리는 방식
이 방식은 운영체제의 화면 부품을 쓰지 않습니다. 대신 프레임워크가 렌더링 엔진을 앱에 싣고 다닙니다. 렌더링 엔진은 버튼의 테두리와 글자까지 화면의 점 하나하나를 직접 칠하는 코드입니다.
운영체제에게서 빌리는 것은 빈 그림판 한 장뿐입니다. 그래서 어느 운영체제에서든 화면이 점 단위까지 똑같이 나옵니다.
대가로 운영체제의 버튼을 흉내 내어 그려야 합니다. 운영체제가 버튼 모양을 바꾸면 프레임워크가 그 모양을 따로 따라 그립니다.
세 방식에서 앱 코드가 화면에 닿기까지 무엇을 거치는지 한 그림에 놓으면 아래와 같습니다.
flowchart TD
subgraph W["웹 화면을 띄우는 방식"]
W1["앱 코드"] --> W2["웹뷰"] --> W3["웹 페이지가 그린 버튼"] --> W4["화면"]
end
subgraph N["화면 부품을 빌리는 방식"]
N1["앱 코드"] --> N2["브리지"] --> N3["운영체제의 버튼"] --> N4["화면"]
end
subgraph D["직접 그리는 방식"]
D1["앱 코드"] --> D2["렌더링 엔진"] --> D3["엔진이 칠한 버튼"] --> D4["화면"]
end
W4 ~~~ N1
N4 ~~~ D1
세 경로는 버튼을 누가 만드느냐에서 갈립니다. 웹 화면을 띄우는 방식은 웹뷰라는 창 하나만 운영체제에서 빌립니다. 그 안의 버튼은 웹 페이지가 그립니다. 직접 그리는 방식은 빈 그림판만 빌리고 버튼은 엔진이 칠합니다.
그래서 두 방식은 운영체제의 화면 부품을 거치지 않습니다. 브리지를 쓰는 방식만 운영체제의 버튼을 그대로 가져다 씁니다.
운영체제 기능을 부르는 통로
앱은 화면 말고도 카메라, 위치, 푸시 알림, 파일 저장 같은 운영체제 기능을 씁니다. 이 기능은 운영체제마다 부르는 방법이 다릅니다.
프레임워크는 자주 쓰는 기능을 호출 하나로 감싸 줍니다. 개발자가 「사진을 찍어라」 하나만 부르면 프레임워크가 운영체제에 맞는 방법으로 바꿔 부릅니다. 이렇게 감싼 기능을 플러그인으로 따로 받아 붙이게 하는 프레임워크가 많습니다.
프레임워크가 감싸 주지 않은 기능도 있습니다. 홈 화면 위젯이나 운영체제가 막 내놓은 기능이 그렇습니다. 이때는 그 기능을 쓰는 코드를 Swift 와 Kotlin 으로 따로 짜서 프레임워크에 연결합니다. 이 부분만큼은 운영체제마다 따로 짭니다.
어디까지 한 벌로 짜나
모든 크로스플랫폼 프레임워크가 화면까지 한 벌로 짜게 하지는 않습니다. 화면 뒤의 로직만 한 벌로 짜는 방식도 있습니다. 로직은 서버에서 데이터를 받아 오고, 값을 검사하고, 저장하는 코드를 말합니다.
이 방식에서 화면은 운영체제마다 네이티브로 짭니다. 서버와 주고받는 코드나 계산 규칙은 한 번만 씁니다. 화면은 운영체제답게 두고 어긋나기 쉬운 로직만 하나로 묶는 셈입니다.
대표 프레임워크
앞의 방식들이 이름난 프레임워크에서 어떻게 나뉘는지 표로 놓으면 아래와 같습니다.
| 프레임워크 | 짜는 언어 | 한 벌로 짜는 것 | 화면을 그리는 방식 |
|---|---|---|---|
| Flutter | Dart | 화면과 로직 | 직접 그린다 |
| React Native | JavaScript | 화면과 로직 | 운영체제의 화면 부품을 빌린다 |
| Kotlin Multiplatform | Kotlin | 로직 | 운영체제마다 네이티브로 짠다 |
| Apache Cordova | JavaScript | 화면과 로직 | 웹뷰에 띄운다 |
| Electron | JavaScript | 화면과 로직 | 웹 화면을 띄운다 |
Electron 은 모바일이 아니라 데스크톱 앱을 겨냥합니다. 운영체제가 내주는 웹뷰를 쓰지 않고 브라우저 엔진을 앱 안에 싣고 다닙니다. 브라우저 엔진은 웹 페이지를 읽어 화면에 그리는 브라우저의 핵심 코드입니다. 렌더링 엔진의 한 종류입니다. 나머지 넷은 iPhone 과 Android 를 함께 겨냥합니다.
한 벌로 짜면 치르는 값
두 벌을 한 벌로 줄이는 대신 앱 코드와 운영체제 사이에 프레임워크가 하나 더 끼어듭니다. 치르는 값은 대부분 여기서 나옵니다.
| 치르는 값 | 까닭 |
|---|---|
| 운영체제의 새 기능을 바로 못 쓴다 | 프레임워크가 그 기능을 감쌀 때까지 기다린다 |
| 앱 용량이 커진다 | 렌더링 엔진이나 JavaScript 를 돌리는 실행기를 앱에 싣는다 |
| 화면 반응이 느려질 수 있다 | 브리지를 건너거나 엔진이 그리는 단계가 한 번 더 낀다 |
| 문제를 찾을 곳이 는다 | 버그가 내 코드와 프레임워크와 운영체제 중 어디서 났는지 가려야 한다 |
| 운영체제다운 모양에서 벗어날 수 있다 | 직접 그리는 방식은 흉내 낸 부품을 쓴다 |
| 프레임워크에 묶인다 | 프레임워크 개발이 멈추면 앱을 다른 도구로 옮겨 짜야 한다 |
이 값은 앱마다 무게가 다릅니다. 목록과 입력 폼이 대부분인 앱은 거의 느끼지 못합니다. 그래픽이 많거나 운영체제 기능을 깊이 쓰는 앱은 크게 느낍니다.
쓰는 경우와 안 쓰는 경우
iPhone 과 Android 에 함께 낼 앱을 적은 개발자로 만들 때 이 방식을 고릅니다. 목록, 입력 폼, 서버에서 받은 데이터 보여 주기가 대부분인 앱이면 프레임워크가 감싼 기능만으로 거의 끝납니다. 웹 프런트엔드를 짜던 팀은 JavaScript 로 짜는 프레임워크에서 배운 것을 이어 씁니다.
한 운영체제에만 낼 앱이면 줄일 두 벌이 없습니다. 운영체제 기능을 깊이 쓰는 앱도 맞지 않습니다. 홈 화면 위젯이나 운영체제가 막 내놓은 기능이 중심이면 결국 대부분을 따로 짭니다.
3D 게임처럼 그래픽이 중심인 앱은 대개 게임 엔진으로 만듭니다. 게임 엔진도 여러 운영체제에 한 벌로 내보내 줍니다.
설치 없이 브라우저에서 써도 되는 앱이면 프로그레시브 웹 앱이 또 다른 길입니다. 웹 사이트를 홈 화면에 붙여 앱처럼 쓰게 하는 방식입니다.
관련 항목
크로스플랫폼 프레임워크가 겨냥하는 플랫폼
iOS · Android · Windows · macOS · Linux · 웹 브라우저
크로스플랫폼 프레임워크를 구현한 제품
Flutter · React Native · Kotlin Multiplatform · Compose Multiplatform · .NET MAUI · Xamarin · Electron · Tauri · Qt · Ionic · Capacitor · Apache Cordova
크로스플랫폼 프레임워크와 맞세워지는 개발 방식
네이티브 앱 · 하이브리드 앱 · 웹 앱 · 프로그레시브 웹 앱
크로스플랫폼 프레임워크 대신 쓰는 운영체제 전용 화면 프레임워크
SwiftUI · UIKit · Jetpack Compose · Android SDK
크로스플랫폼 프레임워크를 이루는 구성 요소
렌더링 엔진 · 웹뷰 · 브리지 · 플러그인 · 위젯 · 자바스크립트 엔진 · 네이티브 모듈
크로스플랫폼 프레임워크로 앱을 짜는 언어
Dart · JavaScript · TypeScript · Kotlin · C++
크로스플랫폼 프레임워크가 속하는 상위 분류
프레임워크 · UI 툴킷 · 모바일 개발 · 사용자 인터페이스 · SDK
코드 한 벌을 여러 환경에 올리는 다른 수단
JVM · 가상 머신 · 크로스 컴파일 · 이식성 · 게임 엔진
크로스플랫폼 앱을 짜고 내보내는 데 쓰는 기술
다른 이름: Cross-platform framework · 크로스 플랫폼 프레임워크 · 멀티플랫폼 프레임워크