기획 회의에서 개발자가 말합니다. "그 기능은 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) 이라고 부릅니다.
그래서 개발자가 "프레임워크라서 그 틀에 맞춰야 해요"라고 하면, 자유도가 낮은 대신 정해진 구조를 따르므로 예측 가능하고 일관되다는 뜻입니다. 일정 추정 시 "프레임워크 학습 곡선"이 비용으로 잡히는 이유이기도 합니다.
라이브러리: [내 코드] ──호출──> [라이브러리 함수] (내가 흐름을 통제)
프레임워크: [프레임워크] ──호출──> [내 코드(끼워넣음)] (프레임워크가 흐름을 통제)
런타임 — 코드가 '실행되는' 환경
런타임: 작성한 코드가 실제로 돌아가는 엔진/환경
"Node 런타임에 올린다", "Java 17 런타임이 필요하다"는 말을 인프라 담당이 놓치면 배포 직전에 막힙니다. 런타임은 작성된 코드를 실제로 실행하는 환경입니다.
- Node.js: JavaScript를 브라우저 밖(서버)에서 실행하는 런타임
- JVM(Java Virtual Machine): Java/Kotlin 바이트코드를 실행하는 런타임
- CPython: Python 코드를 실행하는 런타임
PM·인프라에게 중요한 점: 런타임 버전은 곧 서버에 설치해야 할 것입니다. "Java 17이 필요한데 서버엔 11만 있다" → 배포 실패. 그래서 [[language-runtime-build]]에서 다루는 컴파일/빌드와 함께, 런타임 버전은 배포 체크리스트의 단골 항목입니다.
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 직접 연동으로 늘어납니다.
기술스택을 층위로 읽기 — 직접 분류해보기
개발자가 아니어도 저장소의 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)를 메모해 둔다 — 런타임/호환성 논의([[semantic-versioning]])와 배포 환경 준비의 기준이 된다
상황: PM이 채용공고나 요구사항에 기술 용어를 옮겨 적을 때, 라이브러리/프레임워크를 섞어 쓰면 개발자와의 신뢰에 작은 균열이 생깁니다.
원인: React는 공식적으로 "UI를 만드는 라이브러리"로 소개됩니다(라우팅·데이터fetch·빌드는 별도 도구 조합). 반면 Next.js는 React 위에 구조·라우팅·빌드·서버렌더링을 얹은 프레임워크입니다. 둘을 같은 층위로 부르면 범위가 흐려집니다.
진단 — 한 줄 확인:
npm ls react next
React만 있으면 "라이브러리 + 직접 조합", Next까지 있으면 "프레임워크 기반"입니다.
해결: 공고/요구사항에는 "React 기반 프론트엔드(또는 Next.js)" 처럼 층위를 분리해 적습니다. 확신이 없으면 "프론트엔드 스택: React/Next.js"처럼 스택 나열로 두면 안전합니다.
인프라 엔지니어로서 새 서비스 배포를 준비할 때, 개발팀이 넘긴 "스택 문서"를 층위로 읽으면 준비물이 명확해집니다. 런타임(Node 20 / JVM 17)은 서버·컨테이너 베이스 이미지로, 프레임워크(Spring Boot)는 헬스체크 엔드포인트·포트 관례로, SDK 연동(결제·메일)은 외부 키·아웃바운드 방화벽 허용 목록으로 이어집니다. 용어를 구분하지 못하면 "Java가 필요하다"까지만 알고 버전·빌드 산출물 형식(JAR/WAR)을 놓쳐 배포 당일 막힙니다.
다음 모듈에서는 이 '런타임' 위에서 코드가 어떻게 컴파일·빌드되어 실행 가능한 형태가 되는지를 다룹니다.