React Native의 패키지 호환 가능한 버전 체크

eeennsu·2026년 5월 11일

React Native

목록 보기
38/92

react-native-version-check 정리 (2026 업데이트)

react-native-version-check는 사용자가 설치한 앱의 버전과 앱스토어/플레이스토어에 올라와 있는 최신 버전을 비교해서 "업데이트가 필요한지" 알려주는 라이브러리다. 주로 "강제 업데이트(Force Update)" 기능을 구현할 때 사용된다.

⚠️ 먼저 알아둘 것: 메인테이너 본인이 "더 이상 모바일 개발을 하지 않아 적극적인 유지보수가 어렵다"고 npm 페이지에 공지한 상태다. 신규 프로젝트라면 아래 더 나은 대안 섹션을 먼저 검토하는 것을 권장한다.

1. 왜 필요한가? (문제 상황)

웹(Web)은 배포하면 모든 유저가 즉시 최신 버전을 보게 되지만, 앱(App)은 유저가 직접 스토어에서 업데이트 버튼을 누르기 전까지는 구버전을 계속 사용한다.

  • 서버 API가 변경됨: 서버는 v2.0 API를 쓰는데, 유저 앱은 v1.0이라 호출이 실패함.
  • 치명적인 버그 수정: 결제 로직 오류를 고쳤는데, 유저가 업데이트를 안 하면 계속 오류가 발생함.
  • 보안 패치: 인증 토큰 처리에 보안 이슈가 있어서 구버전 사용을 막아야 함.

이럴 때 앱을 켜자마자 "새로운 버전이 있습니다. 업데이트해주세요." 팝업을 띄우고 스토어로 보낸다.

2. 핵심 동작 원리

이 라이브러리는 크게 3가지 정보를 가져와서 비교한다.

현재 설치된 버전 (Current Version)

package.json이 아니다. 네이티브 모듈을 통해 다음 값을 읽는다.

  • iOS: Info.plistCFBundleShortVersionString
  • Android: build.gradleversionName

스토어 최신 버전 (Latest Version)

  • iOS: 공식 iTunes Lookup API (https://itunes.apple.com/lookup?bundleId=...)를 호출한다. JSON API이므로 비교적 안정적이다.
  • Android: Play Store 웹페이지를 크롤링(scraping)해서 버전 정보를 파싱한다. ← 여기가 자주 깨지는 지점이다.

업데이트 필요 여부 (Need Update)

위 두 버전을 semver로 비교해서 { isNeeded: boolean, ... } 형태로 반환한다.

3. 사용법 (TypeScript)

설치 후, 보통 앱 진입점(App.tsx, Splash Screen 등)에서 검사한다.

import { Linking, Alert } from 'react-native';
import VersionCheck from 'react-native-version-check';

type UpdateResult = {
  isNeeded: boolean;
  currentVersion: string;
  latestVersion: string;
  storeUrl: string;
};

const checkUpdate = async (): Promise<void> => {
  try {
    const update = (await VersionCheck.needUpdate()) as UpdateResult | null;

    if (!update?.isNeeded) return;

    Alert.alert(
      '업데이트 알림',
      '새로운 버전이 출시되었습니다. 앱을 업데이트해주세요.',
      [
        {
          text: '업데이트 하러 가기',
          onPress: () => Linking.openURL(update.storeUrl),
        },
      ],
      { cancelable: false }, // 뒤로가기/바깥터치로 안 닫히게 → 강제성 부여
    );
  } catch (error) {
    // ⚠️ 핵심: 버전 체크 실패가 앱 사용을 막으면 안 된다.
    // 네트워크 오류, 스토어 파싱 실패 등은 조용히 통과시킨다 (fail-open).
    console.warn('[VersionCheck] failed:', error);
  }
};

fail-open인가?

  • 사용자가 비행기 모드일 수도 있다.
  • Play Store HTML 구조가 바뀌어서 파싱이 깨진 상태일 수도 있다.
  • 이런 경우 "업데이트 확인 실패"로 앱을 막으면 클레임 폭주한다. 차라리 통과시키고, 정말 막아야 하는 경우는 서버 API(아래 7번 참조)로 판단한다.

4. 강제 vs 권장 업데이트 분리하기

needUpdate()는 "업데이트가 있는지" 여부만 알려준다. "이 버전 미만은 무조건 차단"과 "선택적으로 권장"을 나누려면 자체 서버 API와 조합해야 한다.

import VersionCheck from 'react-native-version-check';
import semver from 'semver';

type VersionPolicy = {
  minVersion: string;     // 이 미만은 강제 업데이트
  latestVersion: string;  // 이 미만은 권장 업데이트
  storeUrl?: string;
};

const enforceVersionPolicy = async (): Promise<'force' | 'recommend' | 'ok'> => {
  const current = VersionCheck.getCurrentVersion(); // "1.2.0"

  // 1) 자체 서버에서 정책 받아오기
  const policy: VersionPolicy = await fetch('/api/version-policy').then((r) =>
    r.json(),
  );

  if (semver.lt(current, policy.minVersion)) return 'force';
  if (semver.lt(current, policy.latestVersion)) return 'recommend';
  return 'ok';
};

이렇게 하면 스토어 크롤링에 의존하지 않고, 우리 서버에서 유연하게 제어할 수 있다.

5. 주의할 점 (실무에서 겪는 함정)

스토어 반영 지연 (가장 흔한 클레임)

스토어에 새 빌드를 올리면 전 세계 CDN에 퍼지는 데 수십 분에서 몇 시간이 걸린다.

  • 라이브러리는 "최신 버전 있음"이라고 하는데, 막상 유저가 스토어에 가면 "열기" 버튼만 있고 "업데이트" 버튼이 없는 상황이 자주 발생한다.
  • 출시 직후 1~2시간은 강제 업데이트를 켜지 말고, 점진적 롤아웃과 맞추는 것이 안전하다.

Play Store 크롤링의 불안정함

Google이 Play Store 웹페이지 HTML을 변경할 때마다 라이브러리가 깨질 수 있다. 실제로 issue tracker에 "Parse Error. Your app's play store page doesn't seem to have latest app version info" 류의 보고가 반복적으로 올라온다. iOS는 공식 API라서 이 문제에서 자유롭다.

국가별 버전 불일치

한국 스토어엔 v1.0.1이 떴는데, 미국 스토어엔 아직 v1.0.0일 수 있다. 단계적 출시(Staged Rollout)를 쓸 때 특히 문제가 된다. country 옵션으로 명시할 수 있지만, 사용자의 스토어 국가가 디바이스 설정과 다를 수도 있다.

캐싱 이슈

일부 안드로이드 단말은 Play Store 캐시 때문에 업데이트 버튼이 늦게 뜬다. 라이브러리 잘못이 아닌 OS/스토어 이슈다.

6. 장단점 요약

항목평가
구현 난이도⭐ 매우 쉬움
iOS 안정성⭐⭐⭐⭐ 공식 API 사용
Android 안정성⭐⭐ 크롤링 방식, Google 변경 시 깨짐
유지보수 상태⭐⭐ 메인테이너가 활발한 유지보수 어렵다고 공지
강제 업데이트 UX⭐⭐ 스토어 외부로 보낼 뿐, 인앱 업데이트 X



7. 더 나은 대안 (2026 기준)

(A) Android: Google In-App Update API + iOS: 스토어 리다이렉트

sp-react-native-in-app-updates가 현재 RN 진영에서 사실상 표준이다.

  • Android에서는 Google의 공식 Play Core 라이브러리를 사용 → 크롤링 없음, 안정적
  • 앱 내부에서 다이얼로그/다운로드가 진행되므로 사용자가 스토어를 떠날 필요 없음
  • Flexible(백그라운드 다운로드, 사용자가 계속 사용) / Immediate(전체 화면 차단) 두 가지 UX 지원
  • iOS는 별도 API가 없어서 결국 스토어 리다이렉트(react-native-siren 기반)
import SpInAppUpdates, { IAUUpdateKind } from 'sp-react-native-in-app-updates';

const inAppUpdates = new SpInAppUpdates(__DEV__);

const checkUpdate = async () => {
  const result = await inAppUpdates.checkNeedsUpdate();
  if (result.shouldUpdate) {
    inAppUpdates.startUpdate({
      updateType: IAUUpdateKind.IMMEDIATE, // 또는 FLEXIBLE
    });
  }
};

단점: 테스트하려면 반드시 Play Console의 Internal Testing 트랙에 업로드된 빌드여야 한다. 로컬 디버그 빌드로는 동작 확인 불가.

(B) 자체 서버 API (가장 확실한 방식)

스토어 상황에 의존하지 않고 우리가 100% 제어할 수 있다.

GET /api/version-policy?platform=ios&appVersion=1.2.0

Response:
{
  "minVersion": "1.2.0",       // 이 미만은 강제 업데이트
  "latestVersion": "1.3.0",    // 이 미만은 권장 업데이트  
  "storeUrl": "https://...",
  "message": "결제 모듈 개선 업데이트가 있습니다."
}

장점:

  • 스토어 반영 지연과 무관하게 우리 서버 배포 타이밍에 맞춰 제어
  • A/B 테스트, 점진적 차단 등 정교한 정책 가능
  • iOS/Android 동일한 로직

(C) OTA 업데이트 (보조 수단)

스토어 심사 없이 JS 번들만 교체하는 방식. CodePush(Microsoft, 2025년 EOL 예정 이슈 있음 — 확인 필요)나 EAS Update가 대표적이다. 네이티브 변경이 없는 버그 픽스에 한해 사용하고, 위 (A)/(B)와 병행한다.




8. 결론: 어떻게 골라야 하나

상황추천 방식
빠르게 프로토타입에 붙이고 싶다react-native-version-check (간단한 경우)
프로덕션 앱, Android 인앱 업데이트 UX 원함sp-react-native-in-app-updates
강제/권장 업데이트를 우리가 100% 제어하고 싶다자체 서버 API + 위 둘 중 하나 병행
네이티브 변경 없는 긴급 버그 픽스OTA (EAS Update 등)

실무 권장 조합: 자체 서버 정책 API를 메인 로직으로 두고, Android는 sp-react-native-in-app-updates로 인앱 업데이트 UX를 제공, OTA는 보조 채널로 운영하는 것이 가장 안전하다.

profile
이력서 https://resume.eunsu.pro

0개의 댓글