단일 파일 웹앱이란
단일 파일 웹앱은 HTML, CSS, JavaScript가 모두 하나의 .html 파일 안에 들어있는 애플리케이션이다. 빌드 과정이 없고, 브라우저에서 바로 열 수 있다. 설치도 배포도 필요 없다.
이 접근법은 내부 도구, 개인 유틸리티, 프로토타입 제작에서 특히 강력하다. 이메일에 첨부하거나 USB에 넣어서 전달할 수 있고, 인터넷 없이도 동작한다.
- 사내 계산 도구, 견적서 생성기 같은 내부 유틸리티
- 인터넷 연결 없는 환경에서 쓰는 오프라인 도구
- 빠른 프로토타입 또는 데모용 앱
- 설치 불가 환경(공용 PC, 제한된 네트워크)에서의 도구
아키텍처 설계
단일 파일이라고 해서 구조가 없어야 하는 건 아니다. 오히려 파일 하나에 모든 것을 담기 때문에 구조를 더 신경 써야 한다.
기본 구조
모듈화 전략
파일은 하나지만 코드는 모듈로 나눠야 한다. IIFE(즉시 실행 함수)나 객체 리터럴 패턴으로 영역을 분리하면 유지보수가 훨씬 수월해진다. 상태 관리, UI 렌더링, 데이터 저장을 각각 별도 객체로 분리하는 것을 권장한다.
파일 크기가 커지면 개발 중에는 여러 파일로 분리하고, 배포할 때만 하나로 합치는 빌드 스크립트를 만드는 방법도 있다. 단순한 cat 명령어만으로도 충분하다.
셀프 업데이트 구현
단일 파일 앱에서 가장 흥미로운 부분이다. 앱이 자기 자신의 최신 버전을 서버에서 확인하고, 새 버전이 있으면 다운로드를 안내하는 구조를 만들 수 있다.
버전 번호 내장
앱 내부에 현재 버전을 상수로 선언한다. const APP_VERSION = '1.2.0'; 형태로 관리하면 된다.
서버에 최신 버전 정보 배치
JSON 파일 하나에 최신 버전과 다운로드 URL을 기록해 서버에 올려둔다. 앱이 실행될 때 이 JSON을 fetch로 확인한다.
비교 후 알림 표시
내장 버전과 서버 버전을 비교해서, 차이가 있으면 업데이트 안내 배너를 표시한다. 강제 업데이트가 아니라 사용자 선택에 맡기는 것이 UX 측면에서 좋다.
데이터 영속성 확보
단일 파일 앱에서 데이터 저장은 localStorage가 가장 현실적인 선택이다. 용량은 약 5MB로 제한되지만, 대부분의 내부 도구에는 충분하다.
| 저장 방식 | 용량 | 적합한 상황 |
|---|---|---|
| localStorage | ~5MB | 설정, 소량 데이터, 상태 보존 |
| IndexedDB | 수백MB+ | 대량 구조화 데이터, 바이너리 파일 |
| File System API | 디스크 여유분 | 파일 직접 저장/읽기 (Chromium 한정) |
데이터 백업과 복원 기능도 반드시 넣어야 한다. JSON으로 내보내고 가져오는 기능이면 충분하다. 브라우저를 바꾸거나 PC를 바꿀 때 데이터를 잃어버리는 문제를 예방할 수 있다.
한계와 대안
단일 파일 웹앱이 만능은 아니다. 규모가 커지면 유지보수가 어려워지고, 팀 협업에는 적합하지 않다.
언제 다른 방식을 선택할 것인가
- 코드가 3,000줄을 넘어가면 모듈 번들러 도입을 고려해야 한다
- 여러 명이 동시에 작업해야 하면 일반 프로젝트 구조가 낫다
- 외부 API 인증이 필요하면 서버가 결국 필요하다
- 복잡한 라우팅이 필요하면 SPA 프레임워크가 적합하다
Electron이나 Tauri로 데스크탑 앱으로 패키징하면 파일 시스템 접근, 시스템 트레이 같은 네이티브 기능을 추가할 수 있다. 단일 파일로 시작한 도구가 성장하면 자연스럽게 넘어갈 수 있는 경로다.
마무리
단일 파일 웹앱은 "가장 단순한 배포"의 극단에 있다. 복잡한 빌드 파이프라인 없이, 파일 하나를 전달하면 끝이다. 작은 도구, 내부 유틸리티, 빠른 프로토타입에 이 방식은 여전히 유효하다.
중요한 건 이 접근법의 한계를 알고 쓰는 것이다. 작을 때는 단일 파일로, 커지면 구조를 갖춘 프로젝트로 전환하면 된다. 도구의 라이프사이클에 맞게 유연하게 대응하는 것이 실력이다.