05. 프레임워크를 만드는 사람들
05. 프레임워크를 만드는 사람들
이 문서에서 배우는 것
- React, Svelte, Vue, Express, Linux를 만든 사람들의 실제 이야기
- 이들의 공통점: "천재여서"가 아니라 "고통스러워서"
- "만드는 것"과 "잘 사용하는 것"은 완전히 다른 능력임을 이해
- 라이브러리 사용법을 익히는 과정이 곧 문제를 깊이 이해하는 과정
PM의 요구사항... 은 없었다
"React를 만들어주세요"라고 요청한 PM은 없었습니다.
"Facebook 뉴스피드의 알림 뱃지 버그를 고쳐주세요"라는 요청이 있었을 뿐입니다.
프레임워크는 "만들겠다"는 기획에서 탄생하지 않았습니다. "이 고통을 더 이상 참을 수 없다"는 절박함에서 탄생했습니다.
React — Jordan Walke
배경
누구: Jordan Walke
소속: Facebook 광고 팀 엔지니어
시기: 2011년
나이: 20대 중반그가 겪은 고통
Facebook 뉴스피드의 일상:
월요일: "채팅 뱃지가 사라지지 않는 버그" → 고침
화요일: "댓글 수가 안 맞는 버그" → 고침
수요일: "좋아요 누르면 다른 곳의 숫자가 안 바뀌는 버그" → 고침
목요일: "월요일에 고친 채팅 뱃지 버그가 다시 나옴" → ???
금요일: "이건 구조적인 문제야. 코드를 수정해서는 해결이 안 돼."해결 과정
Jordan의 사고 과정:
1. "DOM을 수동으로 업데이트하는 한, 이 버그는 반복될 수밖에 없어"
2. "서버(PHP/XHP)에서는 이런 문제가 없는데... 왜지?"
3. "매번 처음부터 새로 그리니까!"
4. "브라우저에서도 매번 새로 그리면 안 될까?"
5. "진짜 DOM을 매번 새로 만들면 느리니까... 가상으로 먼저 만들고 비교하자"// Jordan이 주말에 만든 FaxJS 프로토타입의 핵심 아이디어
// (실제 코드가 아닌 개념 설명용)
// 이전: "바뀐 곳을 찾아서 수정"
function updateBadge(oldCount, newCount) {
// oldCount와 newCount를 비교해서 DOM을 수정...
// 이 비교 로직이 모든 컴포넌트에 필요
}
// Jordan의 아이디어: "매번 처음부터 선언하고, 비교는 프레임워크가"
function Badge({ count }) {
// 그냥 현재 상태를 선언만 하면 됨
if (count === 0) return null;
return <span className="badge">{count}</span>;
// 이전 상태와의 비교? 프레임워크가 알아서 함
}결과
React를 만든 사람: 1명 (Jordan Walke)
React를 사용하는 개발자: 수백만 명 (전 세계)
React 기반 웹사이트: Facebook, Instagram, Netflix, Airbnb, Twitter, ...
시작은 "주말에 만든 프로토타입"이었습니다.Svelte — Rich Harris
배경
누구: Rich Harris
소속: The Guardian (영국 뉴스 매체) 인터랙티브 팀
시기: 2016년
역할: 뉴스 기사에 인터랙티브 데이터 시각화를 만드는 개발자그가 겪은 고통
뉴스 매체 인터랙티브 개발자의 현실:
기사 하나에 인터랙티브 차트가 필요
→ React를 쓰면?
→ React 라이브러리만 40KB+ (gzip)
→ 독자의 환경: 오래된 폰, 느린 3G, 선진국이 아닌 지역
→ 차트 하나 보여주려고 40KB를 로드하라고?
"프레임워크 자체가 콘텐츠보다 무겁다"Rich Harris의 고민:
React의 Virtual DOM 비교 알고리즘:
상태 변경 → 전체 Virtual DOM 재생성 → 이전과 비교 → 차이점 DOM에 반영
"잠깐, 어떤 상태가 어떤 DOM에 영향을 주는지는
코드를 쓰는 시점에 이미 알 수 있잖아?"
"런타임에 매번 비교할 필요 없이,
컴파일 시점에 정확한 업데이트 코드를 만들어주면 되지 않나?"해결 과정
React의 접근:
런타임에 비교 (Virtual DOM diffing)
→ 브라우저에서 React 라이브러리가 실행되어야 함
→ 라이브러리 크기가 필요
Svelte의 접근:
컴파일 타임에 분석
→ 빌드 시점에 "count가 바뀌면 이 span을 업데이트" 코드를 미리 생성
→ 런타임에 프레임워크가 필요 없음
→ 번들 크기가 극적으로 작음<!-- Svelte — 컴파일러가 분석해서 최적의 업데이트 코드를 생성 -->
<script>
let count = 0;
function increment() {
count += 1; // 이 변수가 바뀌면 아래 {count}를 업데이트하라는 코드가 컴파일 시 생성됨
}
</script>
<button on:click={increment}>
클릭 횟수: {count}
</button>// Svelte 컴파일러가 생성하는 코드 (개념적 설명)
// 개발자가 작성하는 게 아니라, 컴파일러가 자동으로 만들어줌
function update() {
// "count가 바뀌면 이 텍스트 노드를 업데이트"
// → Virtual DOM 비교 없이 직접 업데이트
if (changed.count) {
textNode.data = `클릭 횟수: ${count}`;
}
}결과
Svelte의 번들 크기 비교:
간단한 투두 앱:
React: ~45KB (React + ReactDOM)
Svelte: ~3KB (프레임워크 런타임 없음, 컴파일된 코드만)
Rich Harris의 원래 목표:
"Guardian 독자들이 느린 폰에서도 인터랙티브 기사를 볼 수 있게"
→ 달성
결과적으로:
"프레임워크가 사라지는 프레임워크"라는 새로운 패러다임을 열었습니다.Vue — Evan You
배경
누구: Evan You (尤雨溪)
소속: Google Creative Lab (크리에이티브 실험 프로젝트)
시기: 2013~2014년
배경: 디자인 + 코딩을 함께 하는 크리에이티브 기술자그가 겪은 고통
Evan You의 일상 (Google Creative Lab):
크리에이티브 프로젝트를 만들어야 함
→ Angular 1.x를 사용
→ 간단한 프로토타입에 Angular의 모든 개념을 이해해야 함
Angular 1.x에서 "안녕하세요" 표시:
1. 모듈 정의
2. 컨트롤러 정의
3. $scope에 데이터 바인딩
4. 디렉티브 이해
5. 의존성 주입 이해
... 너무 많은 개념// Angular 1.x — 간단한 일에도 많은 보일러플레이트
var app = angular.module('myApp', []);
app.controller('GreetingController', ['$scope', function($scope) {
$scope.name = 'World';
$scope.greeting = function() {
return 'Hello, ' + $scope.name + '!';
};
}]);<div ng-app="myApp" ng-controller="GreetingController">
<input ng-model="name">
<p>{{ greeting() }}</p>
</div>Evan의 생각:
"나는 Angular의 양방향 데이터 바인딩은 좋아.
하지만 모듈, 컨트롤러, 의존성 주입... 이건 너무 무거워.
React의 컴포넌트 개념도 좋아.
하지만 JSX를 배워야 하고, 설정이 복잡해.
두 세계의 좋은 점만 합치면 안 되나?"해결 과정
Evan You의 접근:
Angular의 좋은 점: 양방향 바인딩, 템플릿 문법
React의 좋은 점: 컴포넌트 시스템, Virtual DOM
빼고 싶은 것: Angular의 복잡함, React의 높은 진입장벽
→ Vue.js 탄생<!-- Vue — "점진적 프레임워크" -->
<!-- HTML 파일에 스크립트 하나만 추가하면 바로 사용 가능 -->
<div id="app">
<input v-model="name">
<p>Hello, {{ name }}!</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: '#app',
data: {
name: 'World'
}
});
</script>Vue의 철학:
"필요한 만큼만 사용하라"
단순한 페이지: <script> 태그 하나로 시작
중간 규모: 싱글 파일 컴포넌트 (.vue)
대규모 앱: Vue Router + Vuex/Pinia + CLI
서버 렌더링: Nuxt.js
→ 시작은 쉽게, 필요하면 확장결과
특이점: Vue는 대기업이 아닌 개인이 만듦
React — Facebook (대기업)
Angular — Google (대기업)
Vue — Evan You (개인)
Evan You는 풀타임으로 Vue를 개발하기 위해
2016년 Patreon 후원을 시작 → 성공
→ 개인 오픈소스 프로젝트가 대기업과 경쟁할 수 있다는 증거
중국, 한국, 일본 등 아시아에서 특히 인기
→ "문서가 잘 되어 있고 진입장벽이 낮다"Express — TJ Holowaychuk
배경
누구: TJ Holowaychuk
소속: 프리랜서 개발자 (독학)
시기: 2010년
특이사항: 대학교를 가지 않음, 독학으로 프로그래밍그가 겪은 고통
TJ가 좋아했던 것: Ruby의 Sinatra 프레임워크
Sinatra — 놀라울 정도로 간결한 웹 프레임워크:
# Ruby/Sinatra
get '/hello/:name' do
"Hello, #{params[:name]}!"
end
→ 이게 웹 서버의 전부
→ 설정 파일 없음, 보일러플레이트 없음
TJ의 고민:
"Node.js에서도 이렇게 간결하게 웹 서버를 만들 수 없을까?"// Node.js 기본 — http 모듈만으로 서버 만들기
var http = require('http');
var server = http.createServer(function(req, res) {
// URL 파싱을 직접 해야 함
var url = require('url').parse(req.url, true);
if (req.method === 'GET' && url.pathname === '/hello') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, ' + url.query.name);
} else if (req.method === 'POST' && url.pathname === '/users') {
// Body 파싱을 직접 해야 함
var body = '';
req.on('data', function(chunk) { body += chunk; });
req.on('end', function() {
var data = JSON.parse(body);
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ id: 1, name: data.name }));
});
} else {
res.writeHead(404);
res.end('Not Found');
}
});
server.listen(3000);// Express — TJ가 만든 해결책
var express = require('express');
var app = express();
app.get('/hello', function(req, res) {
res.send('Hello, ' + req.query.name);
});
app.post('/users', function(req, res) {
res.status(201).json({ id: 1, name: req.body.name });
});
app.listen(3000);결과
Express가 Node.js 생태계에 미친 영향:
Node.js 서버 프레임워크의 사실상 표준이 됨
npm에서 가장 많이 다운로드되는 패키지 중 하나
수많은 후속 프레임워크의 영감:
Koa (TJ가 Express 이후 만든 것)
Fastify, Hapi, NestJS, ...
시작: "Ruby의 Sinatra가 좋아서 Node.js용으로 만들었다"Linux — Linus Torvalds
배경
누구: Linus Torvalds
소속: 헬싱키 대학교 (대학생)
시기: 1991년
나이: 21세그가 겪은 고통
1991년 컴퓨터 전공생의 현실:
운영체제 수업에서 MINIX를 사용
→ MINIX: 교육용 OS (Andrew Tanenbaum 교수가 만듦)
→ 실제 사용하기에는 기능이 부족
상용 Unix를 쓰고 싶음
→ 가격: 수천 달러 (학생이 살 수 없음)
Linus의 요구사항:
1. 터미널 에뮬레이터가 제대로 동작했으면
2. 파일 시스템을 MINIX 대신 내가 원하는 대로
3. 그냥... 쓸 만한 OS가 있으면 좋겠다유명한 Usenet 게시물 (1991년 8월 25일)
From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
Newsgroups: comp.os.minix
Subject: What would you like to see most in minix?
Hello everybody out there using minix -
I'm doing a (free) operating system (just a hobby, won't be
big and professional like gnu) for 386(486) AT clones.
[...]
It is NOT portable (uses 386 task switching etc), and it
probably never will support anything other than AT-harddisks,
as that's all I have :-(.
───────────────────────────────────────────
"취미로 만들고 있고, GNU처럼 크고 전문적이지는 않을 거예요"
"386 이외에는 지원 안 할 거예요, 그게 내가 가진 전부라서"
→ 이것이 Linux의 시작
→ 현재: 세계 서버의 90%+, 안드로이드, 슈퍼컴퓨터 전부가 Linux결과
"취미 프로젝트"의 현재:
서버: 전 세계 서버의 90% 이상
모바일: Android = Linux 커널 기반 → 30억+ 기기
클라우드: AWS, Azure, GCP의 대부분
슈퍼컴퓨터: TOP500 중 100%
IoT: 라우터, TV, 냉장고, 자동차
만든 사람: 1명 (시작)
기여자: 수만 명 (현재)
영향: 인류 IT 인프라의 기반공통점: 천재라서가 아니라, 고통스러워서
┌──────────────┬─────────────────────────────────────────────┐
│ 기술 │ 만든 이유 │
├──────────────┼─────────────────────────────────────────────┤
│ React │ "DOM 동기화 버그를 매일 고치는 게 지겨워서" │
│ Svelte │ "프레임워크가 콘텐츠보다 무거운 게 말이 안 돼서"│
│ Vue │ "Angular가 간단한 일에 너무 복잡해서" │
│ Express │ "Node.js 기본 http로 서버 만드는 게 너무 번거로워서"│
│ Linux │ "쓸 만한 OS가 없고, 살 돈도 없어서" │
├──────────────┼─────────────────────────────────────────────┤
│ 공통점 │ "자기가 겪는 문제가 너무 고통스러워서" │
└──────────────┴─────────────────────────────────────────────┘프레임워크 탄생의 공식:
고통 (일상에서 반복되는 문제)
+
통찰 (더 나은 방법이 있을 것 같다는 직감)
+
실행 (직접 만들어보기)
=
프레임워크이들은 "프레임워크를 만들겠다"고 시작한 게 아닙니다. "이 고통을 해결하겠다"고 시작했고, 그 해결책이 프레임워크가 된 것입니다.
"만드는 것" vs "잘 사용하는 것"
규모의 차이
React를 만든 사람: 1명 (Jordan Walke)
React에 기여한 사람: 수천 명
React를 사용하는 개발자: 수백만 명
만든 사람 기여자 사용자
● ●●●●● ●●●●●●●●●●●●●
(1명) (수천 명) ●●●●●●●●●●●●●
●●●●●●●●●●●●●
●●●●●●●●●●●●●
(수백만 명)완전히 다른 능력
프레임워크를 만드는 능력:
• 문제를 깊이 이해하는 능력
• 추상화를 설계하는 능력
• 런타임, 컴파일러, 알고리즘 지식
• 수년간의 유지보수 의지
프레임워크를 잘 사용하는 능력:
• 적절한 도구를 선택하는 능력
• 도구의 철학을 이해하고 따르는 능력
• 요구사항을 도구에 맞게 구조화하는 능력
• 한계를 알고 우회하는 능력
→ 둘 다 가치 있는 능력이며, 대부분의 개발자에게는
"잘 사용하는 능력"이 더 직접적인 가치를 만들어냅니다.비유: 요리사와 칼
요리사의 능력:
✅ 좋은 칼을 골라 잘 사용하는 것
✅ 재료의 특성을 이해하는 것
✅ 불의 세기를 조절하는 것
✅ 맛의 균형을 맞추는 것
요리사에게 불필요한 능력:
❌ 칼을 직접 만드는 것
❌ 프라이팬을 직접 주조하는 것
❌ 오븐을 직접 설계하는 것
좋은 요리사 = 좋은 도구를 이해하고 잘 쓰는 사람
≠ 도구를 직접 만드는 사람마찬가지로:
좋은 개발자 = React/Svelte를 이해하고 잘 쓰는 사람
≠ React/Svelte를 직접 만드는 사람
좋은 개발자:
"이 상황에서는 React보다 Svelte가 적합하겠다" (도구 선택)
"이 컴포넌트는 서버에서 렌더링하는 게 좋겠다" (도구 활용)
"이 성능 문제는 useMemo로 해결할 수 있다" (도구 깊은 이해)
프레임워크 제작자:
"Virtual DOM 대신 컴파일러 기반으로 하면 어떨까" (새 도구 발명)
→ 이것은 다른 종류의 일라이브러리 사용법을 익히는 것 = 문제를 깊이 이해하는 것
React를 배우면서 알게 되는 것들
React를 배우는 과정:
useState를 배울 때
→ "상태 관리"가 왜 중요한지 이해
→ 불변성(immutability)의 가치를 체감
useEffect를 배울 때
→ "부수 효과"와 "순수 함수"의 차이를 이해
→ 컴포넌트 생명주기를 이해
Context를 배울 때
→ "prop drilling" 문제를 인식
→ 전역 상태 vs 지역 상태의 경계를 이해
React Query를 배울 때
→ 서버 상태와 클라이언트 상태의 차이를 이해
→ 캐싱, 무효화, 낙관적 업데이트의 개념을 이해표면적으로: "React API를 외우는 것"
실제로는: "UI 개발의 근본 문제들을 이해하는 것"
useState → 상태 관리
useEffect → 부수 효과 관리
useMemo → 성능 최적화
useContext → 의존성 관리
Suspense → 비동기 처리
Server Components → 서버/클라이언트 경계
→ 이 개념들은 React 이후의 어떤 프레임워크를 쓰더라도 유효Svelte를 배우면서 알게 되는 것들
Svelte를 배우는 과정:
반응성 선언($:)을 배울 때
→ "파생 상태"의 개념을 이해
→ 스프레드시트처럼 "이 값이 바뀌면 저 값도 바뀐다"
스토어를 배울 때
→ Observable 패턴의 핵심을 이해
→ 구독(subscribe)/해제(unsubscribe)의 메모리 관리
컴파일러 출력을 살펴볼 때
→ "프레임워크가 실제로 무슨 코드를 만드는지" 이해
→ 추상화 아래에서 일어나는 일을 이해즉, 프레임워크를 배우는 것은:
"이 API는 이렇게 쓰면 됩니다" (표면)
↓ 깊이 들어가면
"이 문제는 이런 구조로 해결할 수 있습니다" (본질)
↓ 더 깊이 들어가면
"소프트웨어 설계의 핵심 원리를 체화합니다" (성장)그래서 어떻게 해야 하나?
"나도 프레임워크를 만들어야 하나?"
→ 만들 필요 없습니다. (만들고 싶다면 환영!)
→ 대부분의 가치는 "잘 사용하는 것"에서 나옵니다.
"그냥 API만 외우면 되나?"
→ API를 외우는 것은 시작일 뿐입니다.
→ "왜 이 API가 이렇게 생겼는지"를 이해하면
새로운 프레임워크를 만났을 때도 빠르게 적응할 수 있습니다.
"프레임워크를 깊이 이해하려면?"
→ 이 튜토리얼 시리즈에서 해온 것처럼
"역사"와 "맥락"을 아는 것이 가장 효과적입니다. 만드는 사람 (1명)
│
│ "이 문제가 너무 고통스러워"
│
▼
프레임워크 탄생
│
│ "이 도구가 좋네"
│
▼
잘 쓰는 사람 (수백만 명)
│
│ "왜 이렇게 만들었을까?"
│
▼
문제를 깊이 이해
│
│ "이런 문제를 나도 겪네..."
│
▼
더 나은 개발자로 성장시니어 개발자의 한마디
후배: "저도 React 같은 걸 만들어봐야 '진짜' 개발자인 건가요?"
시니어: "아니. React를 만드는 건 '칼을 만드는 장인'이고, React로 서비스를 만드는 건 '칼을 쓰는 요리사'야. 미슐랭 셰프가 칼을 직접 만들진 않잖아. 좋은 칼을 잘 쓰는 거지. 개발도 마찬가지야."
후배: "그러면 프레임워크를 배울 때 뭘 중점적으로 봐야 할까요?"
시니어: "API 사용법은 기본이고, '왜 이렇게 설계했는지'를 이해하려고 해봐.
useState가 왜 배열을 반환하는지,useEffect의 의존성 배열이 왜 필요한지. 이런 '왜'를 이해하면, 내년에 완전히 새로운 프레임워크가 나와도 일주일이면 적응할 수 있어. 반대로 API만 외우면 프레임워크가 바뀔 때마다 처음부터 다시 시작해야 하고."
핵심 정리
- 프레임워크를 만든 사람들의 공통점: "천재라서"가 아니라 "자기가 겪는 문제가 너무 고통스러워서" 해결책을 만들었다
- 실제 사례:
- React(Jordan Walke) — DOM 동기화 버그에 지쳐서
- Svelte(Rich Harris) — 프레임워크가 콘텐츠보다 무거워서
- Vue(Evan You) — Angular가 간단한 일에 너무 복잡해서
- Express(TJ Holowaychuk) — Ruby의 Sinatra처럼 간결한 Node.js 서버를 원해서
- Linux(Linus Torvalds) — 쓸 만한 OS가 없어서
- 만드는 것 vs 사용하는 것: 완전히 다른 능력이며, 둘 다 가치 있다
- 비유: 요리사가 칼을 직접 만들 필요 없음 — 좋은 칼을 잘 쓰는 것이 요리사의 능력
- 깊이 이해하기: 프레임워크 사용법을 익히는 과정은 곧 "UI 개발의 근본 문제들"을 이해하는 과정
- 핵심 교훈: "왜 이렇게 만들었는지"를 이해하면, 어떤 새 프레임워크가 나와도 빠르게 적응할 수 있다
이것으로 "왜 이 기술들이 존재하는가" 시리즈를 마칩니다. 근본 문제(01) → React 탄생(02) → SoC 재정의(03) → 나선형 진화(04) → 만드는 사람들(05). 이 흐름을 이해하면, 앞으로 어떤 새로운 프레임워크가 등장하더라도 "왜 이게 나왔는지"를 직관적으로 파악할 수 있을 것입니다.