No-Build 선언문: 번들러 없이 배포하기
다음은 빌드 도구를 버려야 한다는 주장이 아닙니다. 빌드 도구를 제거했을 때 어떤 결과가 나타나는지에 대한 측정입니다.
blakecrosley.com은 FastAPI + Jinja2 + HTMX + Alpine.js + 순수 CSS로 운영됩니다. webpack 없음. Vite 없음. Rollup 없음. TypeScript 컴파일러 없음. Babel 없음. PostCSS 없음. Tailwind 없음. package.json 없음. node_modules/ 없음. 이 사이트는 14개의 인터랙티브 JavaScript 컴포넌트가 포함된 33개의 블로그 포스트, 20개의 가이드, 9개 언어 번역을 제공하며, Lighthouse에서 100/100/100/100을 기록합니다.
요약
HTMX 커뮤니티에는 옹호론이 충분합니다. 부족한 것은 증거입니다. 여기에 제시된 수치는 상당한 콘텐츠, 인터랙티브 기능, 국제화를 갖추면서도 빌드 도구를 단 하나도 사용하지 않는 프로덕션 사이트에서 나온 것입니다. 트레이드오프는 솔직하게 다루며, 결론의 범위는 좁습니다: 1인 개발자나 소규모 팀이 운영하는 콘텐츠 중심 사이트에서 빌드 도구는 존재하지 않는 문제를 해결하면서 실제로 존재하는 문제를 만들어냅니다. 공유 컴포넌트 라이브러리와 디자인 시스템 패키지를 갖춘 대규모 팀에서는 빌드 도구가 그 복잡성에 걸맞은 가치를 제공합니다. 그 경계선은 논쟁이 시사하는 것보다 훨씬 명확합니다.
기술 스택
Backend: FastAPI + Jinja2 (server-rendered HTML)
Frontend: HTMX + Alpine.js + Bootstrap 5 (CDN)
Styles: Plain CSS with custom properties
JavaScript: Vanilla JS, IIFE-scoped per component
Deployment: Railway (git push → live)
CDN: Cloudflare (caching, Workers, D1)
트랜스파일링 없음. 트리 셰이킹 없음. 핫 모듈 교체 없음. 소스맵 없음. 작성한 JavaScript가 곧 배포되는 JavaScript입니다.
수치로 보는 결과
추정치가 아닌 실제 측정값입니다:
| 지표 | blakecrosley.com | 일반적인 Next.js 프로젝트 (저자 추정)1 |
|---|---|---|
| 의존성 | Python 패키지 18개 | npm 패키지 300개 이상 |
| 빌드 설정 파일 | 0개 | 5-8개 (next.config, tsconfig, postcss, tailwind, eslint, babel 등) |
node_modules/ 크기 |
존재하지 않음 | 150-400 MB |
| 설치 시간 | pip install -r requirements.txt: 8초 |
npm install: 30-90초 |
| 빌드 단계 | 없음 | next build: 15-60초 |
| 배포 파이프라인 | git push → 약 40초 후 배포 완료 |
git push → 설치 → 빌드 → 배포: 2-5분 |
| CSS 파일 | 14개 파일, 10,300줄 (순수 CSS) | Tailwind/Sass에서 생성, 출력 크기 다양 |
| JS 파일 | 33개 파일, 10,061줄 (사람이 읽을 수 있는 코드) | 번들링, 압축, 청크 분할: 프로덕션에서 읽기 불가능 |
| Lighthouse 성능 | 100 | 다양 (최적화 작업 없이는 보통 70-90) |
18개의 Python 패키지에는 FastAPI, Jinja2, Pydantic, SQLAlchemy 및 14개의 기타 패키지가 포함됩니다. 그중 빌드 도구는 없습니다. 컴파일러도 없습니다. 번들러도 없습니다.2
포기해야 하는 것들
솔직함을 위해 실제 비용을 나열해야 합니다. 이 비용들은 실재합니다.
TypeScript 없음. 이 프로젝트의 모든 .js 파일은 순수 JavaScript입니다. 타입 오류는 컴파일러가 아닌 테스트와 Claude Code의 분석이 잡아냅니다. 이 방식은 1인 개발자에게는 효과적입니다. 10명이 모듈 간 컴포넌트 인터페이스를 공유하는 팀에서는 효과적이지 않을 것입니다.
핫 모듈 교체 없음. CSS 파일을 변경하면 브라우저를 수동으로 새로고침합니다. HTMX의 hx-boost가 네비게이션을 충분히 빠르게 만들어주기 때문에 전체 새로고침도 견딜 만합니다. 30초마다 시각적 디테일을 반복 수정하는 프로젝트에서는 HMR이 의미 있는 시간을 절약해 줄 것입니다.
트리 셰이킹 없음. 제가 작성한 JavaScript의 모든 바이트가 브라우저로 전송됩니다. 유틸리티 라이브러리에서 함수 하나만 가져오려 해도 전체 파일이 함께 전송됩니다. 이 제약이 규율을 강제합니다: 대규모 유틸리티 모듈 대신 작고 집중된 파일을 만들게 됩니다. 14개의 인터랙티브 컴포넌트는 자체 완결적이어야 하기 때문에 평균 300-700줄입니다.3
npm 컴포넌트 라이브러리 없음. Radix 없음, shadcn/ui 없음, Headless UI 없음. 모든 인터랙티브 요소(보이드 시뮬레이션, 해밍 코드 시각화, 합의 시뮬레이터)는 직접 구축했습니다. 이 접근법은 인터랙티브 컴포넌트가 범용 UI 패턴이 아닌 특정 교육 목적을 위해 존재하기 때문에 가능합니다.
npm 디자인 시스템 토큰 없음. 제 디자인 시스템은 전적으로 CSS 커스텀 프로퍼티로 존재합니다. 다른 프로젝트에서 패키지로 가져올 수 없습니다. 단일 사이트 시스템에서는 이 제약이 수용 가능합니다. 다수의 제품을 운영하는 조직에서는 그렇지 않습니다.
이 다섯 가지 트레이드오프는 1인 개발자가 운영하는 콘텐츠 중심 사이트에서는 수용 가능합니다. 15명 규모의 엔지니어링 팀이 운영하는 SaaS 제품에서는 수용 불가능할 것입니다.
얻게 되는 것들
빌드 실패 제로. 배포 파이프라인은 git push입니다. 피어 의존성 충돌로 npm install이 실패할 일이 없습니다. 제가 건드리지 않은 파일의 TypeScript 오류로 next build가 실패할 일이 없습니다. Dependabot PR이 전이적 의존성을 업그레이드해서 빌드가 깨질 일이 없습니다.4
소스 보기로 디버깅. 브라우저에서 실행되는 JavaScript는 제가 작성한 JavaScript 그 자체입니다. 소스맵이 필요 없습니다. 컴파일된 출력에서 원본 소스로의 매핑이 필요 없습니다. 프로덕션에서 버그가 발생하면 배포된 파일을 직접 읽으면 됩니다.
즉각적인 로컬 시작. uvicorn app.main:app --reload은 2초 이내에 시작됩니다. 페이지를 보여주기 전에 설치, 컴파일, 번들링을 수행하는 npm run dev가 필요 없습니다.
Dependabot 노이즈 제로. package-lock.json이 없으므로 semver, ansi-regex, glob-parent 같은 패키지를 업데이트하는 주간 PR이 없습니다. 직접 가져온 적도 없지만 의존성 트리의 세 단계 깊이에 존재하는 패키지들입니다.
미래 보장. 이 사이트는 10년 후에도 작동할 것입니다. HTML은 HTML입니다. CSS는 CSS입니다. JavaScript는 JavaScript입니다. Webpack 4 → 5 마이그레이션도, Create React App 지원 중단도, Next.js App Router 마이그레이션도 없습니다. 플랫폼 자체가 표준입니다.5
아키텍처로서의 HTMX
HTMX에 대한 논의는 문법에 집중됩니다: hx-get, hx-swap, hx-target. 이것은 잘못된 프레임입니다. 아키텍처적 통찰의 핵심은 서버 렌더링된 HTML이 곧 API라는 것입니다.
전통적인 SPA 방식:
Browser → fetch('/api/users') → JSON → React renders HTML → DOM update
HTMX 방식:
Browser → GET /users (hx-get) → Server renders HTML fragment → DOM swap
서버가 최종 표현을 반환합니다. 클라이언트 측 상태 관리 없음, 직렬화/역직렬화 없음, 하이드레이션 없음. Jinja2 템플릿 자체가 컴포넌트입니다. FastAPI 엔드포인트 자체가 API입니다. 세 개의 레이어가 아닌 하나의 레이어입니다.6
이 패턴은 복리 엔지니어링 원칙에 직접적으로 대응됩니다: 각 인프라 구성 요소가 정확히 하나의 일을 하며, 구성 요소들이 간섭 없이 조합됩니다. 템플릿은 HTML을 렌더링합니다. 라우트는 그것을 반환합니다. HTMX가 그것을 삽입합니다. 이 구성 요소들을 조율하는 빌드 단계가 없는 이유는 조율이 필요하지 않기 때문입니다.
순수 CSS로 충분합니다
제 디자인 시스템은 10개의 색상 토큰, 13단계의 타입 스케일, 8개의 간격 값을 사용하며, 모두 CSS 커스텀 프로퍼티입니다:
:root {
--color-bg-dark: #000000;
--color-text-primary: #ffffff;
--color-text-secondary: rgba(255,255,255,0.65);
--spacing-sm: 1rem;
--spacing-md: 1.5rem;
--font-size-lg: 1.25rem;
}
Sass 컴파일 단계 없음. 유틸리티를 생성하는 Tailwind 설정 없음. 커스텀 문법을 변환하는 PostCSS 플러그인 없음. 브라우저가 이 값들을 직접 읽습니다.7
이 사이트의 아름다움과 브루탈리즘 미학(절대 검정 위의 흰색과 4단계 불투명도)은 제약에서 탄생합니다. 색상 팔레트에 의존할 수 없을 때, 타이포그래피가 위계를 담당합니다. 컴포넌트 그림자에 의존할 수 없을 때, 여백이 구조를 만듭니다. 제약 자체가 디자인입니다.8
CLS 해결 과정
Lighthouse 최적화 과정에서 no-build의 실질적인 비용 하나가 드러났습니다: 크리티컬 CSS 추출에 커스텀 Python 스크립트가 필요했습니다. Next.js 프로젝트에서는 프레임워크가 이를 자동으로 처리합니다.
구체적인 버그: 모바일 미디어 쿼리가 CSS 커스텀 프로퍼티를 오버라이드했습니다(--gutter: 48px → --gutter: 24px). 크리티컬 CSS에는 데스크톱 값이 포함되었지만 모바일 오버라이드는 포함되지 않았습니다. 모바일에서 히어로가 48px 패딩으로 렌더링된 후 전체 스타일시트가 로드되면서 24px로 변경되어, CLS 0.493이 발생했습니다.
수정은 Python 12줄이었습니다. 조사에는 3시간이 걸렸습니다. 빌드 도구였다면 이를 자동으로 처리했을 것입니다.
솔직한 계산: 빌드 도구는 수동으로 할 수 있는 작업을 자동화하지만, 수동 방식은 문제가 발생했을 때 디버깅 시간이 필요합니다. 핵심 질문은 자동화의 비용(복잡성, 의존성, 빌드 실패, 마이그레이션 부담)이 수동 비용(간헐적인 디버깅 세션)을 초과하는지 여부입니다.
이 사이트에서는 수동 비용이 더 낮았습니다. 3년간 CLS 버그 1건, 디버깅 3시간. 대안(빌드 파이프라인 유지)은 의존성 업데이트, 호환성 문제, 설정 관리에 누적적으로 더 많은 시간을 소비했을 것입니다.
이 방식을 사용하지 말아야 할 때
no-build 접근법이 적합하지 않은 경우:
대규모 팀. TypeScript의 가치는 팀 규모에 비례하여 증가합니다.9 10명의 개발자가 컴포넌트 인터페이스를 공유할 때, 컴파일 타임 타입 검사는 런타임 테스트로는 너무 늦게 발견되는 통합 버그를 방지합니다. 1인 개발자는 전체 시스템을 머릿속에 담고 있을 수 있습니다. 팀은 그렇게 할 수 없습니다.
디자인 시스템 패키지. 여러 제품이 디자인 시스템을 소비한다면, 적절한 버전 관리, 트리 셰이킹, 빌드 파이프라인을 갖춘 npm 패키지여야 합니다. 단일 스타일시트의 CSS 커스텀 프로퍼티는 저장소 간에 조합되지 않습니다.
복잡한 클라이언트 상태. 애플리케이션이 풍부한 클라이언트 측 상태를 가지고 있다면(드래그 앤 드롭 인터페이스, 실시간 협업, 오프라인 우선 데이터) React나 Svelte 같은 프레임워크가 그 복잡성에 걸맞은 가치를 제공합니다. HTMX는 클라이언트 상태를 서버 왕복으로 대체하는데, 이는 지연 시간이 중요해질 때까지만 유효합니다.
npm 생태계 라이브러리. Radix 프리미티브, Framer Motion, TanStack Query가 필요하다면 빌드 파이프라인이 필요합니다. 세 가지 모두 번들러를 전제로 합니다. 번들러 없이 사용하는 것은 고통스럽거나 불가능합니다.
경계선은 논쟁이 시사하는 것보다 단순합니다: 애플리케이션이 주로 서버에서 렌더링하는 콘텐츠라면 빌드 도구는 오버헤드입니다. 애플리케이션이 주로 클라이언트에서 관리하는 상태라면 빌드 도구는 인프라입니다.
핵심 요점
1인 개발자와 소규모 팀을 위해:
-
증거는 주장이 아니라 사이트 자체입니다. blakecrosley.com은 33개의 포스트, 14개의 인터랙티브 컴포넌트, 20개의 가이드, 9개 언어를 빌드 도구 없이 완벽한 Lighthouse 점수로 제공합니다. 이 수치는 검증 가능합니다.
-
no-build의 솔직한 비용은 간헐적인 디버깅입니다. CLS 버그 수정에 3시간이 걸렸습니다. 빌드 도구였다면 자동으로 처리했을 것입니다. 3년간 누적 디버깅 시간은 빌드 파이프라인이 요구했을 누적 유지보수 시간보다 훨씬 적었습니다.
-
제약이 디자인을 만듭니다. 색상 없음은 타이포그래피가 위계를 담당하도록 강제했습니다. 빌드 도구 없음은 단순하고 자체 완결적인 JavaScript를 강제했습니다. 최고의 제약은 필요해지기 전에 스스로 선택하는 것입니다.
기술 스택을 평가하는 팀 리더를 위해:
-
빌드 도구는 팀 규모의 문제를 해결합니다. TypeScript, 트리 셰이킹, 컴포넌트 라이브러리는 여러 개발자가 인터페이스를 공유할 때 그 복잡성에 걸맞은 가치를 제공합니다. 콘텐츠 중심 사이트를 구축하는 1인 개발자에게는 이러한 문제가 존재하지 않습니다.
-
HTMX의 진정한 기여는 아키텍처적입니다. API로서의 서버 렌더링 HTML은 클라이언트 상태 관리, 직렬화, 하이드레이션을 제거합니다. 문법은 통찰에 비하면 부차적입니다.
이 글은 블로그의 디자인 섹션과 엔지니어링 섹션을 연결합니다. 디자인 결정은 아름다움과 브루탈리즘, 스타트업을 위한 디자인 시스템, 타입 스케일에서 다룹니다. 엔지니어링 측정값은 Lighthouse 완벽 점수와 복리 엔지니어링에서 확인할 수 있습니다. 바이브 코딩 포스트에서는 이 철학이 AI 보조 개발에 어떻게 적용되는지 탐구합니다.
-
“일반적인 Next.js 프로젝트” 열은 저자의 5개 이상의 Next.js 프로젝트 경험(2021-2024)과 커뮤니티에서 보고된 일반적 수치를 반영합니다. 구체적인 수치(300개 이상의 패키지, 150-400 MB node_modules)는 Node.js 커뮤니티에서 흔히 보고되는 수치와 일치합니다. 개별 프로젝트에 따라 크게 다를 수 있습니다. 이 수치는 저자의 추정치이며 독립적으로 검증된 벤치마크가 아닙니다. ↩
-
2026년 2월 기준 전체 의존성 목록: fastapi, uvicorn, starlette, pydantic, pydantic-settings, jinja2, markdown, pygments, beautifulsoup4, lxml, nh3, resend, python-dotenv, python-multipart, slowapi, httpx, sqlalchemy, analytics-941. 빌드 도구 제로. 컴파일러 제로. 번들러 제로. ↩
-
평균 컴포넌트 크기(300-700줄)는 2026년 2월 기준
/static/js/의 14개 인터랙티브 JS 파일에서 측정되었습니다. 크기 범위는 240줄(signal-calculator.js)에서 690줄(boids-simulation.js)까지입니다. ↩ -
저자의 Next.js 프로젝트 유지보수 경험에 기반하면, JavaScript 생태계는 활발한 프로젝트에 대해 월 15-25개의 Dependabot PR을 생성하며, 대부분은 개발자가 직접 가져온 적 없는 전이적 의존성을 업데이트합니다. 이 수치는 직접 관찰에 의한 추정치이며 독립적으로 검증된 벤치마크가 아닙니다. ↩
-
웹 플랫폼(HTML, CSS, JavaScript)은 30년간 하위 호환성을 유지해 왔습니다. 1996년의 페이지도 Chrome 2026에서 여전히 렌더링됩니다. 팀 버너스리는 이를 설계 원칙으로 표현했습니다: “브라우저는 하위 호환성을 가져야 하며, 이전 버전의 언어를 읽을 수 있어야 한다.” w3.org/DesignIssues/Principles 참조. ↩
-
HTMX 창시자 Carson Gross는 이를 “하이퍼미디어를 애플리케이션 상태의 엔진으로”(HATEOAS)라고 표현합니다. htmx.org 에세이와 Gross, Stepinski, Cotter의 Hypermedia Systems (2023)을 참조하세요: hypermedia.systems. ↩
-
CSS Custom Properties(CSS 변수)는 전 세계 브라우저의 97% 이상에서 지원됩니다. 출처: caniuse.com/css-variables. 사용하는 데 컴파일 단계가 필요하지 않습니다. ↩
-
“제약을 디자인 도구로 활용하는” 원칙에는 오랜 역사가 있습니다. 찰스 임스: “디자인은 대부분 제약에 달려 있다.” 영화의 도그마 95 운동은 도구를 제거하는 것(인공 조명 금지, 후반 작업 금지)이 덜 정직한 스토리텔링이 아닌 더 정직한 스토리텔링을 만든다는 것을 증명했습니다. en.wikipedia.org/wiki/Dogme_95 참조. ↩
-
2024 Stack Overflow 개발자 설문조사에서 TypeScript는 4번째로 인기 있는 언어이자 가장 인기 있는 JavaScript 상위 집합으로, 팀 규모에 비례하여 채택률이 증가하는 것으로 나타났습니다. survey.stackoverflow.co/2024/ 참조. ↩