NGINX에서 njs를 사용해 SSR을 구축했습니다. 배운 점

발행: (2026년 4월 9일 오후 04:45 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

Source:

소개

NGINX 내부에 최소한의 SSR 런타임을 직접 구축했고 이제는 프로덕션에서 사용하고 있습니다.
한동안 njs와 함께 NGINX를 사용해 CSP 논스 생성 및 요청 수준 로직과 같은 작업을 수행해 왔습니다. 이 프로젝트는 그 CSP 처리를 확장하는 형태로 시작했으며, 결국 개인 웹사이트에서 실행되는 작은 실험으로 성장했습니다.

저장소:

런타임이 하는 일

  • NGINX + njs (NGINX 내부의 JavaScript)
  • 간단한 컴포넌트‑렌더링 패턴
  • Node.js도, Next.js도 없음 – 오직 NGINX

런타임은 의도적으로 작고 명시적이며, 전체 프레임워크라기보다 렌더링 유틸리티에 가깝다.

렌더링 흐름

전통적인 SSR클라이언트 → Node SSR → HTML
NGINX‑기반 SSR클라이언트 → NGINX (njs) → HTML

아이디어는 간단하다:

  1. 요청 처리 중에 JavaScript를 실행한다 (njs를 통해).
  2. HTML을 즉시 생성한다.
  3. HTML을 NGINX에서 직접 반환한다.

실제로 이것은 문자열‑우선 렌더링 모델이다: 가상 DOM이나 템플릿 엔진 없이 작은 헬퍼 함수를 사용해 순수 문자열로 HTML을 만든다.

NGINX에 대한 내 시각이 바뀐 이유

이전에는 NGINX를 주로 다음과 같이 사용했습니다:

  • 리버스 프록시
  • 헤더와 라우팅을 위한 장소

njs와 작업하면서 NGINX가 또한 다음을 할 수 있음을 알게 되었습니다:

  • 요청 수준 로직 실행
  • 동적 응답 생성
  • 매우 가벼운 렌더링 레이어 역할

최소 환경이라는 제약이 오히려 가치 있는 요소가 되었습니다.

주요 인사이트

  • SSR은 서버에서 HTML을 반환하는 것에 불과합니다. 그 외 모든 것은 그 위에 겹쳐집니다.
  • 프로젝트는 SSR이 실제로 무엇인지우리가 보통 어떻게 구현하는지의 차이를 명확히 했습니다.
  • 런타임을 동기 렌더링만, 외부 I/O 없음, 숨겨진 상태 없음, 결정론적 출력으로 제한함으로써 시스템은:
    • 이해하기 쉬워짐
    • 디버깅이 쉬워짐
    • 더 예측 가능해짐

능력을 제거하는 것이 추상화를 추가하는 것보다 명확성을 향상시킬 수 있습니다.

장점 및 트레이드오프

얻은 것잃는 것
Node.js 런타임 없음전체 JavaScript 런타임
매우 빠른 실행 경로생태계 및 도구
최소한의 움직이는 부품익숙한 디버깅 패턴

이것은 내 사고를 “애플리케이션 수준 설계”에서 “인프라 수준 설계”로 전환시켰다.

통합 장점

모든 것이 NGINX 내부에서 실행되기 때문에 CSP, 헤더, 요청 검증과 같은 문제들이 단일 레이어에 머물러 시스템이 더 일관되게 느껴진다.

개발 워크플로우

구현은 다음과 같이 협업했습니다:

  • A 텍스트 지향 모델 (ChatGPT) for reasoning, structure, and constraints.
  • A 코드 지향 에이전트 (Codex) for the actual implementation.

워크플로우:

  1. Define the system shape.
  2. Use Codex to fill in implementation details.
  3. Validate everything against real runtime behavior.

This separation proved more effective than trying to generate everything in one step.

이 접근 방식을 고려해야 할 때

적합한 경우:

  • 작거나 대부분 정적인 사이트
  • 단순한 렌더링 레이어
  • HTML 및 보안에 대한 엄격한 제어가 필요한 경우
  • 인프라‑레벨 실험

부적합한 경우:

  • 복잡한 프론트엔드 애플리케이션
  • 높은 인터랙티비티 요구
  • 방대한 생태계에 의존하는 팀

NGINX를 설정해 본 적이 있다면, 이 설정이 익숙하게 느껴질 것입니다.

시작하기

  1. NGINX와 njs를 설치합니다.
  2. 저장소를 복제합니다.
  3. 제공된 구성을 로드합니다.
  4. 서버를 실행합니다.

전체 지침:

Conclusion

이 최소 SSR 런타임을 프로덕션에서 구축하고 실행하면서 렌더링을 인프라스트럭처까지 얼마나 밀어넣을 수 있는지, 그리고 제약이 시스템 설계에 어떻게 영향을 미치는지를 명확히 알게 되었습니다. 또한 프론트엔드가 끝나는 지점과 인프라스트럭처가 시작되는 지점에 대한 제 관점을 재정립하게 되었습니다. 때때로 레이어를 제거하는 것이 새로운 레이어를 추가하는 것보다 더 많은 것을 가르쳐 줍니다.

0 조회
Back to Blog

관련 글

더 보기 »

Web Component UI Kit를 만들었습니다.

배경: 나는 어느 날 갑자기 UI kit을 만들기로 결심한 것이 아니다. 내가 만든 대부분의 것들처럼, 이것도 내가 겪은 문제에 대한 해결책으로 시작되었으며, 아무도 사용하지 않을 프로젝트를 위해서였다.