기획 회의에서 개발자가 말합니다. "그 기능은 React 라이브러리로 충분한데, 라우팅까지 필요하면 Next.js 프레임워크로 가야 하고, 서버는 Node 런타임에 올릴 거예요. 결제는 토스 SDK 쓰면 API 직접 안 건드려도 돼요." 회의록을 적던 당신은 라이브러리·프레임워크·런타임·SDK·API가 각각 무슨 층위인지 헷갈립니다. 이 단어들을 구분하지 못하면 일정 추정도, 인프라 준비도, 개발자와의 대화도 한 박자씩 어긋납니다.
- 1라이브러리와 프레임워크를 "누가 누구를 호출하는가(제어의 역전)"로 구분해 설명할 수 있다
- 2런타임이 "코드가 실행되는 환경"임을 이해하고 인프라 준비와 연결할 수 있다
- 3API와 SDK의 관계를 "규약 vs 그 규약을 쉽게 쓰는 키트"로 설명할 수 있다
- 4기술스택 목록을 층위별(언어/런타임/프레임워크/DB/플랫폼)로 분류해 읽을 수 있다
라이브러리 vs 프레임워크 — 누가 주도권을 쥐는가
확대
위 그림처럼 라이브러리는 내 코드가 필요한 순간에 호출하지만, 프레임워크는 프레임워크가 정해진 자리에 내 코드를 끼워 넣어 실행한다(제어의 역전).
제어의 역전: 라이브러리는 내가 부르고, 프레임워크는 나를 부른다
개발자가 "이건 라이브러리예요"와 "이건 프레임워크예요"를 구분해 말할 때, 그 차이를 모르면 "그게 그거 아닌가요?"가 됩니다. 둘의 결정적 차이는 제어의 주체입니다.
- 라이브러리(Library): 내가 필요할 때 가져다 쓰는 도구 모음. 흐름은 내 코드가 통제합니다. (예: 날짜 계산 라이브러리를 내가 원하는 시점에 호출)
- 프레임워크(Framework): 전체 구조와 실행 흐름을 프레임워크가 쥐고, 정해진 자리에 내 코드를 끼워 넣게 합니다. "Don't call us, we'll call you" — 이것을 제어의 역전(IoC, Inversion of Control) 이라고 부릅니다.
그래서 개발자가 "프레임워크라서 그 틀에 맞춰야 해요"라고 하면, 자유도가 낮은 대신 정해진 구조를 따르므로 예측 가능하고 일관되다는 뜻입니다. 일정 추정 시 "프레임워크 학습 곡선"이 비용으로 잡히는 이유이기도 합니다.
런타임 — 코드가 '실행되는' 환경
확대
위 그림처럼 런타임(아래)부터 API 규약, SDK 도구 키트, 내 애플리케이션 코드(위)까지 층위별로 쌓여 있으며, 각 계층이 분리된 책임을 가진다.
런타임: 작성한 코드가 실제로 돌아가는 엔진/환경
"Node 런타임에 올린다", "Java 17 런타임이 필요하다"는 말을 인프라 담당이 놓치면 배포 직전에 막힙니다. 런타임은 작성된 코드를 실제로 실행하는 환경입니다.
- Node.js: JavaScript를 브라우저 밖(서버)에서 실행하는 런타임
- JVM(Java Virtual Machine): Java/Kotlin 바이트코드를 실행하는 런타임
- CPython: Python 코드를 실행하는 런타임
PM·인프라에게 중요한 점: 런타임 버전은 곧 서버에 설치해야 할 것입니다. "Java 17이 필요한데 서버엔 11만 있다" → 배포 실패. 그래서 컴파일·인터프리터·빌드·런타임에서 다루는 컴파일/빌드와 함께, 런타임 버전은 배포 체크리스트의 단골 항목입니다.
API와 SDK — 규약과 그 규약을 쉽게 쓰는 키트
API는 '대화 규약', SDK는 '그 규약을 포장한 도구 키트'
"결제는 SDK 쓰면 API 직접 안 건드려도 돼요"를 이해하려면 둘의 층위를 봐야 합니다.
- API(Application Programming Interface): "이렇게 요청하면 이렇게 응답한다"는 인터페이스 규약. 예:
POST /payments {amount: 1000}→{status: "paid"}. - SDK(Software Development Kit): 그 API를 특정 언어에서 함수 한 줄로 호출하도록 인증·요청·에러처리를 묶어 둔 키트(라이브러리 + 문서 + 예제).
같은 결제를 붙여도, API를 직접 쓰면 HTTP 요청·서명·재시도를 직접 구현해야 하고, SDK를 쓰면 toss.payments.create(...) 한 줄입니다. 추정에 영향을 줍니다 — SDK가 있으면 연동 공수가 줄고, 없으면 API 직접 연동으로 늘어납니다.
기술스택을 층위로 읽기 — 직접 분류해보기
확대
위 그림처럼 채용공고의 기술 목록을 언어/런타임, 프레임워크/라이브러리, DB/스토리지, 인프라/플랫폼 네 층위로 나누면 인프라 준비물과 배포 구조가 바로 보인다.
개발자가 아니어도 저장소의 package.json(JS/TS) 또는 build.gradle/pom.xml(Java), requirements.txt(Python)를 열면 그 프로젝트가 무엇 위에 서 있는지 보입니다. 의존성 목록을 층위별로 분류해봅니다.
# JavaScript/TypeScript 프로젝트
cat package.json # dependencies 항목을 본다
# 특정 패키지가 트리에서 어디 있는지(설치 여부·버전)
npm ls next react
{
"dependencies": {
"next": "14.2.0", ← 프레임워크(구조·라우팅·빌드 제공)
"react": "18.3.0", ← UI 라이브러리
"axios": "1.6.0", ← HTTP 라이브러리(내가 호출)
"@tosspayments/sdk": "2.1.0" ← 결제사 SDK
}
}
cat package.json- dependencies에서 next/spring-boot-starter/django 처럼 "구조 전체를 제공하는 것"이 있으면 그게 프레임워크 → 학습곡선·구조 제약을 일정에 반영한다
- react/axios/lodash 처럼 "필요할 때 호출하는 것"은 라이브러리 → 교체 비용이 상대적으로 낮다
- 이름에 sdk/client가 들어가면 외부 서비스 연동 키트 → 그 외부 서비스(결제·메일·클라우드) 계정·키 발급이 별도 준비물이다
- 버전 숫자(next 14.2.0)를 메모해 둔다 — 런타임/호환성 논의(시맨틱 버저닝)와 배포 환경 준비의 기준이 된다
상황: PM이 채용공고나 요구사항에 기술 용어를 옮겨 적을 때, 라이브러리/프레임워크를 섞어 쓰면 개발자와의 신뢰에 작은 균열이 생깁니다.
원인: React는 공식적으로 "UI를 만드는 라이브러리"로 소개됩니다(라우팅·데이터fetch·빌드는 별도 도구 조합). 반면 Next.js는 React 위에 구조·라우팅·빌드·서버렌더링을 얹은 프레임워크입니다. 둘을 같은 층위로 부르면 범위가 흐려집니다.
진단 — 한 줄 확인:
npm ls react next
React만 있으면 "라이브러리 + 직접 조합", Next까지 있으면 "프레임워크 기반"입니다.
해결: 공고/요구사항에는 "React 기반 프론트엔드(또는 Next.js)" 처럼 층위를 분리해 적습니다. 확신이 없으면 "프론트엔드 스택: React/Next.js"처럼 스택 나열로 두면 안전합니다.
심화 — 도입하는 날보다 떠나는 날이 비싸다
심화: 프레임워크·런타임·SDK에는 수명과 잠금(lock-in)이 있다
층위를 구분했다면 다음 질문은 '이 선택이 우리를 무엇에 묶는가'입니다. 도구는 고르는 순간이 아니라 업그레이드하거나 떠나야 하는 순간에 진짜 비용을 청구합니다.
- 프레임워크 선택은 구조 잠금입니다: 프레임워크는 제어의 역전으로 코드 전체가 그 틀에 맞춰집니다. 그래서 메이저 버전 업그레이드는 '기능 추가 0개'인데도 몇 주씩 걸리는 마이그레이션이 되고(시맨틱 버저닝의 MAJOR가 프레임워크에선 특히 비쌉니다), 이 비용은 로드맵에 잘 안 보입니다. 도입 검토 때 '커뮤니티가 살아 있는가, 과거 메이저 업그레이드가 얼마나 험했는가'를 함께 보는 이유입니다.
- 런타임에는 수명(EOL)이 있습니다: 런타임은 설치하면 끝이 아니라 지원 종료일이 정해진 소모품입니다. EOL이 지난 런타임은 보안 패치가 멈춰, '잘 돌아가는데 왜 올리냐'가 그대로 보안 리스크가 됩니다. 스택 문서를 읽을 때 버전 숫자만이 아니라 그 버전의 EOL 일정까지 읽어야 인프라 계획이 됩니다(컴파일·인터프리터·빌드·런타임).
- SDK의 편리함에는 그늘이 있습니다: SDK는 연동 공수를 줄이지만, 제공사의 새 API 기능이 SDK에 늦게 반영되기도 하고, SDK에 내장된 재시도·타임아웃 기본값이 장애 시 우리 서비스의 행동(요청 폭주·대기 지연)을 결정합니다. 'SDK 쓰니까 신경 끝'이 아니라, 그 기본값이 무엇인지는 알고 써야 합니다.
- 규모가 선택 기준입니다: 화면 몇 개짜리 내부 도구에 풀 프레임워크를 얹으면, 기능이 아니라 프레임워크 유지보수(버전 추적·보안 패치)가 일이 됩니다. 기술적 우열보다 '누가 몇 명이서 얼마나 오래 유지보수할 것인가'가 먼저입니다.
그래서 성숙한 팀은 프레임워크·런타임·SDK를 코드가 아니라 자산으로 관리합니다 — 버전·EOL·담당자가 적힌 목록이 있고, 업그레이드가 로드맵에 정기 항목으로 올라갑니다.
상황: 결제사가 'v1 API를 3개월 뒤 종료한다'고 공지했습니다. 확인해 보니 우리 서비스의 결제 SDK는 2년 전 붙인 1.x 버전으로 v1 API 전용이고, 현행 SDK 2.x는 메서드 이름·응답 구조·에러 처리 방식이 전면 개편돼 있었습니다. 결제 관련 코드의 상당 부분을 3개월 안에 고쳐 재검증해야 하는 상황입니다.
원인: SDK를 '한 번 붙이면 끝나는 부품'으로 취급해 버전과 지원 종료 일정을 아무도 추적하지 않았습니다. 결제사는 1년 전부터 changelog와 공지로 폐기 예정(deprecated)을 알려 왔지만, 연동이 '잘 돌아가고 있어서' 아무도 보지 않았습니다. 외부 의존성은 우리가 안 바꿔도 상대가 바꿉니다.
진단: 의존성 목록(package.json 등)에서 외부 서비스 SDK들의 현재 버전을 뽑고, 각 제공사의 최신 버전·지원 정책과 비교합니다. '현행 메이저보다 2개 이상 뒤처진 SDK'가 있으면 같은 사고의 후보입니다.
해결: (1) 급한 불: 결제사와 종료 유예를 협의하면서 2.x 마이그레이션을 최우선으로 진행하고, 결제 핵심 흐름의 재검증 시간을 일정에 확보합니다. (2) 재발 방지: 외부 SDK·런타임을 버전·EOL·담당자가 적힌 의존성 자산 목록으로 관리하고, 분기마다 소폭 업그레이드하는 정기 창을 둡니다 — 2년치를 한 번에 점프하면 몇 주가 들지만, 분기마다 따라가면 며칠로 끝납니다(시맨틱 버저닝). (3) 제공사의 공지·changelog를 구독해, 폐기 예고 신호를 사람의 기억이 아니라 프로세스가 받게 합니다.
인프라 엔지니어로서 새 서비스 배포를 준비할 때, 개발팀이 넘긴 "스택 문서"를 층위로 읽으면 준비물이 명확해집니다. 런타임(Node 20 / JVM 17)은 서버·컨테이너 베이스 이미지로, 프레임워크(Spring Boot)는 헬스체크 엔드포인트·포트 관례로, SDK 연동(결제·메일)은 외부 키·아웃바운드 방화벽 허용 목록으로 이어집니다. 용어를 구분하지 못하면 "Java가 필요하다"까지만 알고 버전·빌드 산출물 형식(JAR/WAR)을 놓쳐 배포 당일 막힙니다.
다음 모듈에서는 이 '런타임' 위에서 코드가 어떻게 컴파일·빌드되어 실행 가능한 형태가 되는지를 다룹니다.
용어 식별 실습으로 굳히기: 용어 식별 — 프레임워크 / 라이브러리 / 런타임 / SDK — 대화·공고 문구를 보고 라이브러리·프레임워크·런타임·API/SDK를 가려냅니다.