µJS vs Turbo: 같은 아이디어, 다른 철학

발행: (2026년 3월 11일 오후 08:39 GMT+9)
9 분 소요
원문: Dev.to

Source: Dev.to

Cover image for µJS vs Turbo: same idea, different philosophy

Turbo (Hotwire의 일부)와 µJS는 같은 문제를 해결합니다: 프론트엔드를 JavaScript로 다시 작성하지 않고도 서버‑렌더링된 웹사이트를 더 빠르게 느끼게 만드는 것이죠. 두 라이브러리 모두 링크 클릭과 폼 제출을 가로채고, AJAX를 통해 페이지를 가져와 DOM에 삽입합니다.

차이점은 범위, 무게, 그리고 서버 요구사항에 있습니다.

크기

LibrarySize (min + gzip)
µJS~5 KB
Turbo~25 KB

Turbo는 5 배 더 무겁습니다. “페이지를 가져와서 HTML을 교체하는” 것이 주된 역할인 라이브러리라면, 이는 상당히 큰 차이입니다.

빌드 단계

Turbo는 빌드 단계가 필요합니다 – 번들링을 위해 npm 패키지로 배포됩니다.

µJS필요하지 않습니다:

mu.init();

이는 JavaScript 빌드 파이프라인을 의도적으로 피하는 프로젝트(정적 사이트, PHP/Python/Ruby 앱, 혹은 npm + 번들러를 추가하는 것이 오히려 뒤로 가는 단계가 되는 모든 프로젝트)에게 중요한 사항입니다.

서버‑측 요구 사항

µJS는 서버에 아무것도 요구하지 않습니다. 표준 HTTP 요청을 보내고 표준 HTML을 반환받기를 기대합니다. 기존 페이지는 그대로 작동합니다.

Turbo에는 다음과 같은 규칙이 있습니다:

  • Turbo Drive(기본 탐색)는 µJS와 동일하게 작동합니다.
  • Turbo Frames는 서버가 특정 <turbo-frame> 요소를 반환해야 합니다.
  • Turbo Streams(µJS의 패치 모드와 동등함)는 서버가 <template> 태그 안에 콘텐츠를 감싼 <turbo-stream> 커스텀 요소를 반환해야 합니다.

Turbo Streams를 도입하면 서버‑측 HTML 출력이 변경됩니다. Rails와 Hotwire 생태계에서는 헬퍼가 이를 처리해 주지만, 다른 백엔드에서는 직접 구현해야 합니다.

다중‑프래그먼트 업데이트: 패치 모드 vs Turbo Streams

두 라이브러리 모두 단일 응답으로 페이지의 여러 부분을 업데이트할 수 있습니다. 구문이 차이를 보여줍니다.

µJS – 패치 모드

서버는 일반 HTML을 반환합니다. 각 프래그먼트는 mu-patch-targetmu-patch-mode 속성을 가집니다:

<div mu-patch-target="article" mu-patch-mode="replace">
  <h2>Great article!</h2>
</div>

<div mu-patch-target="comments">
  <p>14 comments</p>
</div>

<form mu-patch-target="comment-form">
  <button type="submit">Submit</button>
</form>

Turbo Streams

각 프래그먼트는 <turbo-stream> / <template> 로 감싸야 합니다:

<turbo-stream action="replace" target="article">
  <template>
    <h2>Great article!</h2>
  </template>
</turbo-stream>

<turbo-stream action="append" target="comments">
  <template>
    <p>14 comments</p>
  </template>
</turbo-stream>

<turbo-stream action="replace" target="comment-form">
  <template>
    <form>
      <button type="submit">Submit</button>
    </form>
  </template>
</turbo-stream>

µJS에서는 프래그먼트 자체가 내용입니다. Turbo에서는 각 프래그먼트가 래퍼 구조를 필요로 합니다. µJS 방식은 보일러플레이트가 적고 HTML을 그대로 읽을 수 있습니다.

또 다른 실용적인 장점: µJS의 mu-patch-target 속성은 초기 페이지 로드 시 무시되므로, 일반 페이지 템플릿과 패치 응답에서 동일한 HTML 프래그먼트를 그대로 사용할 수 있습니다.

HTTP 메서드

FeatureTurboµJS
지원되는 메서드GET, POSTGET, POST, PUT, PATCH, DELETE
추가 동사 사용 방법숨겨진 _method 필드 또는 서버 측 관례링크, 버튼 및 폼에 대한 mu-method 속성
<a href="/posts/5" mu-method="delete">Delete</a>

<form action="/api/publish/5" mu-method="patch">
  <button type="submit">Publish</button>
</form>

Turbo는 PUT/PATCH/DELETE에 대한 기본 지원이 없어 우회 방법을 사용해야 하지만, µJS는 이를 바로 사용할 수 있습니다.

트리거와 폴링

Turbo는 링크와 폼만 처리합니다.

µJS는 mu-trigger를 추가하여 모든 요소모든 이벤트에서 fetch를 시작할 수 있게 합니다:

<button mu-trigger="click" mu-url="/refresh" mu-poll="5000">
  5초마다 새로 고침
</button>

실시간: 서버 전송 이벤트 (SSE)

두 라이브러리 모두 SSE를 지원합니다.

  • µJS는 기본 제공되며 동일한 패치 구문을 재사용합니다:
<div mu-patch-target="notifications" mu-patch-mode="append">
  <!-- Server will push <div mu-patch-target="notifications">…</div> fragments -->
</div>

서버는 mu-patch-target 속성을 가진 표준 HTML 조각을 푸시합니다—일반 패치 응답과 동일한 형식입니다. 새로 배울 것이 없습니다.

  • Turbo Streams도 SSE를 통해 전달될 수 있지만, 여전히 <turbo-stream> / <template> 형식으로 작업해야 하며, 서버는 해당 구조를 생성해야 합니다.

TL;DR

항목µJSTurbo (Hotwire)
크기~5 KB~25 KB
빌드 단계번들러가 필요 없음npm 및 번들러 필요
서버 요구사항없음 (일반 HTML 사용 가능)<turbo-frame> / <turbo-stream> 필요 (고급 기능 사용 시)
패치 구문mu-patch-* 속성을 가진 일반 HTML<turbo-stream> 요소로 감쌈
HTTP 메서드GET, POST, PUT, PATCH, DELETEGET, POST (다른 메서드는 우회 필요)
트리거mu-trigger를 모든 이벤트, 폴링, 디바운스에 사용링크와 폼만
SSE 지원내장, 동일한 패치 형식지원하지만 Turbo 전용 마크업 사용

만약 모든 백엔드와 동작하는 작고, 설정이 필요 없는 즉시 사용 가능한 솔루션을 원한다면, µJS가 확실히 승자입니다. 이미 Rails/Hotwire 생태계에 깊이 들어가 있고, 제공하는 풍부한 기능 세트가 필요하다면 Turbo가 더 적합할 수 있습니다.

Turbo가 더 적합할 때

Turbo는 다음 경우에 적합합니다:

  • Rails / Hotwire 생태계에 있다면 — 통합이 깊고, 헬퍼가 성숙했으며, 커뮤니티가 크다.
  • iOS/Android 앱을 위한 Turbo Native가 필요하다면.
  • 팀이 이미 Turbo 관례에 익숙하다면.

Rails 생태계 밖에서는 Turbo의 관례가 생태계 혜택 없이 오히려 부담이 된다.

Summary

기능µJSTurbo
크기~5 KB~25 KB
빌드 단계없음필요
서버 변경 필요 여부아니오프레임 및 스트림을 위해 필요
다중 프래그먼트 업데이트패치 모드 (일반 HTML)Turbo Streams (<turbo-stream>)
HTTP 메서드GET/POST/PUT/PATCH/DELETEGET/POST
모든 이벤트에서 트리거아니오
디바운스 / 폴링내장없음
SSE내장내장
Rails 생태계아니오

µJS는 집중된 라이브러리입니다: 프로젝트에 넣고 mu.init()을 호출하면 서버 변경 없이 사이트에 AJAX 탐색 기능이 추가됩니다. 더 많은 기능이 필요하면 속성을 사용할 수 있고, 필요 없으면 비용을 지불하지 않아도 됩니다.

npm install @digicreon/mujs
0 조회
Back to Blog

관련 글

더 보기 »

JavaScript 소개

소개 오늘 수업에서 짧게 JavaScript에 대해 배웠으므로, 이 블로그에서 JavaScript에 관한 몇 가지 사실을 공유하려 합니다. JavaScript란? JavaScript…