Skip to content

Instantly share code, notes, and snippets.

@leedc0101
Created March 31, 2026 01:30
Show Gist options
  • Select an option

  • Save leedc0101/85604f9b45a5dddceacccff81bcf68f9 to your computer and use it in GitHub Desktop.

Select an option

Save leedc0101/85604f9b45a5dddceacccff81bcf68f9 to your computer and use it in GitHub Desktop.
frontend-briefing-2026-03-31-KST

frontend-briefing-2026-03-31-KST

번역일: 2026-03-31 KST

오늘 선별한 글은 6개다. 커뮤니티에서 먼저 걸러진 글 위주로 묶었고, 공식 소스는 실무 영향이 큰 2개만 보강했다.

포함된 글

  1. Pretext – DOM 없이 텍스트 높이를 측정하는 순수 JS 레이아웃 라이브러리

    • 원문: https://github.com/chenglou/pretext
    • 발견 경로: GeekNews, Lobsters, HN
    • 포인트: 가변 높이 텍스트 UI, virtualization, layout shift 방지 같은 문제를 DOM reflow 없이 푸는 접근.
  2. Fully Local Code Embeds

  3. Pidgey – A type-safe job queue for Next.js that runs on your database

    • 원문: https://www.pidgey.dev/
    • 발견 경로: HN
    • 포인트: Next.js 앱 안에서 SQLite/Postgres/Redis 기반 백그라운드 잡을 타입 안전하게 다루는 방법.
  4. typed-fetch – A type-safe HTTP client that never throws

  5. Next.js Across Platforms: Adapters, OpenNext, and Our Commitments

    • 원문: https://nextjs.org/blog/nextjs-across-platforms
    • 발견 경로: HN를 통해 확인, 공식 소스 보강
    • 포인트: Next.js를 Vercel 바깥 인프라에서 안정적으로 돌리기 위한 공식 Adapter API와 테스트 체계.
  6. Announcing TypeScript 6.0

원문 제목: Pretext – Pure JavaScript/TypeScript library for multiline text measurement & layout 원문 링크: https://github.com/chenglou/pretext 번역일: 2026-03-31 KST

한국어 번역

Pretext는 여러 줄 텍스트의 측정과 레이아웃 계산을 위해 만든 순수 JavaScript/TypeScript 라이브러리다. 빠르고 정확하며, 개발자가 평소 크게 의식하지 않는 다양한 언어와 이모지, 양방향 문자까지 지원한다. DOM, Canvas, SVG, 앞으로는 서버 사이드 렌더링까지 염두에 두고 설계됐다.

핵심 아이디어는 단순하다. 보통 브라우저에서 텍스트가 몇 줄을 차지하는지, 높이가 얼마나 되는지 알려면 getBoundingClientRect()offsetHeight 같은 DOM 측정에 의존한다. 문제는 이 방식이 layout reflow를 유발한다는 점이다. 브라우저에서 reflow는 가장 비싼 작업 중 하나다. Pretext는 이 지점을 우회한다. 브라우저의 폰트 엔진을 기준점으로 삼아 자체적인 텍스트 측정 로직을 수행하고, 이후에는 DOM 없이 계산만으로 줄 수와 높이를 얻는다.

기본 사용 방식은 prepare()layout() 두 단계다.

  • prepare()는 한 번만 수행하는 준비 작업이다.
    • 공백을 정규화한다.
    • 텍스트를 세그먼트로 나눈다.
    • 줄바꿈/결합 규칙을 적용한다.
    • Canvas를 이용해 세그먼트 폭을 측정한다.
    • 이후 재사용 가능한 내부 핸들을 만든다.
  • layout()은 반복 호출되는 뜨거운 경로(hot path)다.
    • 이미 계산된 폭 캐시를 바탕으로 순수 산술만 수행한다.
    • 주어진 maxWidth, lineHeight에 맞춰 높이와 줄 수를 계산한다.

즉, 같은 텍스트와 같은 폰트 설정이라면 준비 단계는 한 번만 하고, 리사이즈가 일어나도 layout()만 다시 돌리면 된다. 그래서 리스트 리사이즈, responsive layout, virtualization 같은 상황에서 유리하다.

라이브러리는 일반적인 텍스트뿐 아니라 white-space: pre-wrap 스타일에 가까운 텍스트도 지원한다. 즉, textarea처럼 스페이스, 탭, 줄바꿈을 보존해야 하는 상황에서도 사용할 수 있다.

현재 벤치마크 기준으로 저자는 공유된 500개 텍스트 배치에서 다음 정도의 수치를 제시한다.

  • prepare() 약 19ms
  • layout() 약 0.09ms

이 구조가 중요한 이유는, 브라우저 UI에서 "텍스트 높이"는 생각보다 많은 문제의 마지막 퍼즐이기 때문이다.

Pretext가 강조하는 활용처는 다음과 같다.

  1. 정확한 virtualization / occlusion
    • 추정치나 임시 캐시 없이 실제 텍스트 높이를 더 정확하게 계산할 수 있다.
  2. 유저랜드 레이아웃
    • masonry, JS 기반 flex 유사 레이아웃, CSS만으로 애매했던 레이아웃 미세 조정에 도움을 준다.
  3. 개발 시 검증
    • 버튼 레이블이나 UI 텍스트가 줄을 넘는지 브라우저 없이 체크할 수 있다.
  4. layout shift 감소
    • 새 텍스트가 로드되기 전에 높이를 예측해서 스크롤 앵커가 튀는 현상을 줄일 수 있다.

고급 API도 있다.

  • prepareWithSegments()는 더 풍부한 내부 구조를 돌려준다.
  • layoutWithLines()는 줄 단위 결과를 직접 얻을 수 있다.
  • walkLineRanges()는 문자열을 실제로 만들지 않고 각 줄의 폭과 커서를 순회할 수 있다.
  • layoutNextLine()은 줄마다 폭이 달라지는 경우, 예를 들어 이미지 주위를 감싸며 텍스트를 흘리는 레이아웃에 쓸 수 있다.

즉, 단순히 “텍스트 높이 얼마야?”만 해결하는 도구가 아니라, 브라우저 바깥에서 텍스트 레이아웃 엔진의 일부를 사용자 코드로 끌어오는 시도에 가깝다.

주의점도 있다. 이 라이브러리는 완전한 폰트 렌더링 엔진을 지향하지는 않는다. 기본 타깃은 다음 조합이다.

  • white-space: normal
  • word-break: normal
  • overflow-wrap: break-word
  • line-break: auto

또한 macOS에서 system-ui는 정확한 결과를 위해 안전하지 않으므로, 명시적인 폰트 이름 사용을 권장한다.

정리하면, 이 글의 핵심은 이거다. 가변 높이 텍스트가 많은 UI에서 DOM 측정은 병목이 되기 쉽고, Pretext는 그 병목을 사전 계산 + 순수 산술 경로로 치환한다. 채팅, 피드, 문서 뷰어, 캔버스 렌더링, 브라우저 밖 사전 검증 같은 실무 영역에서 꽤 쓸모 있어 보인다.

원문 제목: Fully Local Code Embeds 원문 링크: https://www.aleksandrhovhannisyan.com/blog/local-code-embeds/ 번역일: 2026-03-31 KST

한국어 번역

글쓴이는 예전부터 Markdown 문서 안에 인터랙티브한 코드 샌드박스를 넣고 싶었지만, CodePen이나 CodeSandbox 같은 외부 iframe 서비스에 의존하고 싶지 않았다. 그런 서비스는 공유에는 좋지만, 로컬 문서와 외부 사이트를 오가며 수정해야 하고, 대개 JavaScript도 많이 로드한다는 불편함이 있었다.

처음에는 iframe srcdoc 속성을 활용하는 방식에서 힌트를 얻었다. 보통 iframe은 src로 외부 페이지를 가리키지만, srcdoc은 iframe 내부 문서를 문자열 형태의 HTML로 직접 넣을 수 있게 해준다.

예를 들면 이런 식이다.

<iframe srcdoc="<!doctype html><body>...</body>"></iframe>

하지만 이걸 직접 손으로 쓰는 건 비현실적이다. HTML/CSS/JS를 한 줄 문자열로 합쳐야 하고, 따옴표나 <, > 같은 문자도 직접 이스케이프해야 한다. 가독성도, 문서 작성 경험도 나빠진다.

글쓴이는 2022년에 Eleventy용 플러그인으로 이 문제를 한 번 풀었다. Markdown fenced code block을 빌드 타임에 iframe으로 컴파일하는 방식이었다. 잘 동작했지만, 특정 프레임워크 문법에 묶인다는 한계가 있었다. 유지보수 중단이나 프레임워크 교체를 생각하면 지나치게 의존적인 설계였다.

그래서 이번에는 프레임워크 비의존적이고, HTML과 클라이언트 JavaScript만 있으면 어디서나 쓸 수 있는 방법을 찾았다. 결과물이 local-iframe이라는 웹 컴포넌트다.

사용 방식은 꽤 직관적이다.

<code-demo>
  <template>
    <button>Click me!</button>
    <style>button { padding: 0.5rem }</style>
    <script>...</script>
  </template>
</code-demo>

핵심 트릭은 <template> 태그다. 브라우저는 page load 시점에 template 내부 내용을 실제로 파싱해 실행하지 않는다. 덕분에 바깥 문서가 오염되지 않는다. 웹 컴포넌트는 나중에 이 template의 inner HTML을 읽어 iframe srcdoc에 넣고, 최종적으로 격리된 로컬 코드 데모를 만든다.

이 방식의 장점은 분명하다.

  1. 문서 작성 경험이 좋다
    • HTML/CSS/JS를 원래 형태로 적을 수 있다.
    • syntax highlighting을 그대로 누릴 수 있다.
  2. 외부 서비스 의존이 줄어든다
    • 문서와 데모가 같은 로컬 워크플로 안에 있다.
  3. 가볍다
    • 글에 따르면 minified 기준 클라이언트 JS가 4kB 미만이다.
  4. 프레임워크 비의존적이다
    • HTML과 JS가 되는 곳이면 쓸 수 있다.

또한 API도 유연하다. 템플릿을 컴포넌트 자식으로 넣을 수도 있고, 별도의 <template id="...">를 만들어 참조할 수도 있다. 그리고 fit-content 같은 속성으로 내부 iframe 높이에 맞춰 바깥 컴포넌트 크기를 조절할 수도 있다.

글쓴이는 여기서 더 나아가 커스텀 렌더링도 소개한다. 자신의 블로그에서는 코드 데모 하단에 콘솔 출력 영역을 붙이고 싶었다. 그래서 기본 컴포넌트를 그대로 쓰는 대신 LocalIframe 클래스를 상속한 뒤 _render() 메서드를 오버라이드했다. 이 메서드는 templateHtml을 받아 최종 iframe 문서 구조를 문자열로 반환한다.

즉, 라이브러리는 두 가지 사용 방식을 준다.

  • 자동 등록된 기본 웹 컴포넌트를 바로 import해서 쓴다.
  • LocalIframe을 상속해 자신만의 렌더링/출력 UI를 가진 커스텀 컴포넌트를 만든다.

글 속 예시에서는 console.log, console.error를 가로채 iframe 아래쪽 콘솔 패널에 출력하고, 타임스탬프까지 붙인다. 심지어 unhandledrejection도 잡아서 표시한다.

여기서 흥미로운 디테일은 클릭 이벤트 처리다. 어떤 데모는 window, document, body 등에 캡처링 이벤트 리스너를 걸어 둔다. 그런데 콘솔 패널 안을 클릭해도 상위 캡처링 핸들러가 먼저 실행되면, 콘솔 UI를 조작하는 클릭이 데모 로직에 섞여 버린다. 글쓴이는 이 문제를 피하려고 가장 높은 수준인 window에 캡처링 리스너를 등록해, 콘솔 영역에서 발생한 클릭은 별도로 무시하는 방식으로 처리했다.

마지막 메시지는 꽤 분명하다. 콘텐츠는 가능한 한 직접 소유하라. 외부 코드 임베드 서비스와 프레임워크 고유 문법에 덜 묶이면, 문서와 데모를 훨씬 오래 유지할 수 있다. 이 접근의 제한도 있다. CodePen처럼 TypeScript나 JSX를 바로 처리하진 못한다. 하지만 순수 HTML/CSS/JS 데모를 많이 다루는 기술 블로그나 문서 사이트라면 충분히 현실적인 트레이드오프다.

정리하면, 이 글은 “외부 playground를 박아 넣는 것” 대신 웹 표준만으로 로컬 문서 친화적인 코드 데모 시스템을 만드는 방법을 보여준다. 기술 블로그, 디자인 시스템 문서, 사내 지식 베이스 같은 곳에서 꽤 실용적이다.

원문 제목: Background jobs without the infrastructure / Pidgey 원문 링크: https://www.pidgey.dev/ 번역일: 2026-03-31 KST

한국어 번역

Pidgey는 Next.js를 위한 타입 안전한 잡 큐(job queue) 를 표방한다. 핵심 메시지는 간단하다. “백그라운드 잡 때문에 굳이 별도 인프라를 먼저 늘리지 말자.”

대부분의 잡 큐는 Redis나 별도의 매니지드 서비스를 요구한다. 하지만 많은 웹앱은 이미 데이터베이스를 갖고 있다. Pidgey는 이 점을 활용해, 로컬에서는 SQLite로 시작하고, 운영에서는 Postgres로 올리거나, 더 높은 처리량이 필요하면 Redis를 선택할 수 있게 한다. 중요한 건 코드는 거의 그대로 유지되고, 백엔드만 바꿀 수 있다는 점이다.

글이 짚는 불편은 세 가지다.

  1. 추가 인프라 부담
    • 잡 큐를 붙이려면 Redis나 외부 서비스가 필요해지는 경우가 많다.
  2. 로컬 개발의 번거로움
    • Docker, 터널, 모킹 서버 같은 준비 작업이 늘어난다.
  3. 솔루션 고착
    • 한 번 특정 큐 솔루션에 묶이면 옮기기 어렵다.

Pidgey는 이 문제를 “파일 기반 잡 + 타입 추론 + 유연한 어댑터” 조합으로 푼다.

예시는 이런 식이다.

  • jobs/send-email.ts 같은 파일에서 잡을 정의한다.
  • pidgey.defineJob()으로 이름과 핸들러를 선언한다.
  • 다른 곳에서는 enqueue()만 호출해 잡을 넣는다.

즉, Next.js 라우트처럼 파일 단위로 잡을 관리하는 감각이다. 코드 구조가 단순하고, 팀원이 읽기 쉽다.

Pidgey가 강조하는 기능은 다음과 같다.

  • File-Based Jobs: 파일 하나당 잡 하나. 자동 탐색.
  • Type-Safe: 잡 정의부터 enqueue까지 TypeScript 타입 추론 유지.
  • Flexible Backends: SQLite / Postgres / Redis 선택 가능.
  • Self-Hosted: 인프라와 데이터 통제권을 직접 가짐.
  • Automatic Retries: 지수 백오프 포함 재시도.
  • Dead Letter Queue: 실패한 잡 보존.
  • Delayed Jobs: 나중 실행 예약.
  • Easy Testing: 핸들러를 일반 함수처럼 테스트 가능.

설정도 비교적 직관적이다. 예를 들어 SQLite를 쓰려면 pidgey.config.ts에서 adapter를 sqlite로 두고 파일명을 지정하면 된다. worker 설정에서 잡 디렉토리와 concurrency도 줄 수 있다.

로컬 개발에서는 SQLite가 특히 매력적이다.

  • 의존성 추가가 거의 없다.
  • 파일 기반이라 다루기 쉽다.
  • 작은 서비스나 초기 단계 제품에서 운영 복잡도를 크게 줄인다.

운영으로 갈수록 선택지는 넓어진다.

  • Postgres: 이미 DB가 Postgres라면 가장 자연스럽다.
  • Redis: 처리량이 높아지면 더 적합할 수 있다.

이 글이 실무적으로 주는 인상은 이렇다. 요즘 Next.js 앱은 서버 액션, 웹훅, 이메일 발송, 후처리, 캐시 재생성, 비동기 동기화 작업이 점점 많아진다. 그런데 제품 초기에 “큐 시스템을 먼저 크게 깔아야 하나?”가 늘 부담이다. Pidgey는 그 지점에서 앱 내부 개발 경험을 최대한 Next.js스럽게 유지하면서, 백그라운드 작업을 한 단계 늦게 복잡하게 만들 수 있게 해준다.

즉, “잡 큐는 필요하지만 인프라 증설은 아직 이르다”는 팀에게 꽤 맞는 도구다. 반대로 초고처리량 시스템이라면 결국 Redis나 더 전문화된 큐로 갈 가능성이 크겠지만, 그마저도 같은 API로 시작해 점진적으로 올릴 수 있다는 게 장점이다.

원문 제목: typed-fetch – A type-safe HTTP client that never throws 원문 링크: https://github.com/pbpeterson/typed-fetch 번역일: 2026-03-31 KST

한국어 번역

typed-fetch는 TypeScript용 HTTP 클라이언트로, 기본 철학은 아주 분명하다. 에러를 예외(exception)로 던지지 말고 값(value)으로 다뤄라. Go의 에러 처리 스타일에서 영감을 받았고, 내부적으로는 네이티브 Fetch API 위에 얇게 올라간 래퍼다.

문제의식은 일반적인 fetch() 사용 경험에서 출발한다. 전통적인 패턴에서는 try/catch 안에서 네트워크 에러, 파싱 에러, HTTP 상태 에러가 한데 섞이기 쉽다. 특히 FE/BFF 코드에서는 “404 응답”과 “네트워크 장애”를 다르게 처리해야 하는 경우가 많은데, 기본 fetch만으로는 이 흐름이 깔끔하지 않다.

typed-fetch는 이렇게 바꾼다.

const { response, error } = await typedFetch<User[]>('/api/users');

if (error) {
  // 에러는 null이 아닌 값으로 온다.
} else {
  // response는 null이 아님이 타입으로 보장된다.
}

즉, 성공과 실패를 서로 배타적인 union 결과로 돌려주기 때문에, 코드 흐름이 더 명시적이다.

이 라이브러리가 내세우는 특징은 다음과 같다.

  • Never throws: 모든 에러를 값으로 돌려준다.
  • Fully typed: 응답 타입뿐 아니라 상태 코드와 상태 텍스트도 타입화한다.
  • Built on Fetch: 서명과 감각이 기본 fetch와 가깝다.
  • 40 HTTP error classes: 400~511 표준 HTTP 에러를 전용 클래스로 제공한다.
  • NetworkError 분리: 연결 실패, DNS, timeout 등 네트워크 계층 에러를 구분한다.
  • Type guards 제공: isHttpError(), isNetworkError().
  • Generic error bodies: error.json<T>()로 에러 응답 바디를 타입 안전하게 파싱.

예를 들어 POST 요청에서 400 Bad Request를 기대한다면, BadRequestError를 구체적으로 분기할 수 있다. 404, 401, 429 같은 케이스도 각각 전용 에러 클래스로 다룰 수 있다. 이건 실무에서 꽤 중요하다. 단순히 “요청 실패”가 아니라 어떤 실패인지에 따라 UI, 재시도, 토스트, 폼 에러 바인딩 로직이 달라지기 때문이다.

또 하나 좋은 점은 error.json()의 제네릭 지원이다. 서버가 { message, code, fields } 같은 구조로 에러를 내려준다면, 클라이언트는 그 바디를 타입으로 해석해 폼 필드 에러나 재시도 전략을 더 안전하게 구현할 수 있다.

라이브러리는 두 번째 제네릭 파라미터로 예상 가능한 클라이언트 에러 타입 집합을 좁히는 기능도 제공한다. 예를 들어 어떤 API가 400과 404는 자주 반환하지만, 나머지는 보통 서버 에러라고 보면, 타입 상에서 그 범위를 줄일 수 있다. 그러면 분기문이 더 깔끔해진다.

HTTP 에러 클래스는 단순한 마커가 아니다. 각 에러 인스턴스는 다음 정보에 접근할 수 있다.

  • status
  • statusText
  • headers
  • json() / text() / blob() / arrayBuffer()
  • clone()

즉, “실패했으니 throw”가 아니라 실패 응답도 정상적인 데이터 흐름의 일부로 다룬다.

이 글의 핵심 메시지는 FE 코드 스타일 자체에 대한 제안이기도 하다. API 클라이언트가 점점 복잡해질수록 try/catch 하나에 많은 의미를 실으면 읽기도 어렵고 실수도 많아진다. typed-fetch는 그 대신 if (error) { ... } else { ... } 패턴을 밀어준다. 네트워크 실패와 404/422 같은 비즈니스 수준 실패를 더 또렷하게 구분할 수 있어서, 특히 다음 같은 코드베이스에 잘 맞아 보인다.

  • 폼 에러가 많은 BFF / admin frontend
  • 상태 코드별 UX가 중요한 SaaS 대시보드
  • fetch wrapper를 얇고 예측 가능하게 유지하고 싶은 팀

정리하면, typed-fetch는 새로운 HTTP 클라이언트를 거창하게 만들기보다 기본 fetch의 에러 모델을 프론트엔드 친화적으로 교정하는 도구다. “예외”보다 “명시적 값”을 선호하는 팀이라면 꽤 마음에 들 가능성이 높다.

원문 제목: Next.js Across Platforms: Adapters, OpenNext, and Our Commitments 원문 링크: https://nextjs.org/blog/nextjs-across-platforms 번역일: 2026-03-31 KST

한국어 번역

Next.js 16.2는 안정화된 Adapter API를 도입했다. 이 글은 그 배경과 함께, 앞으로 Next.js가 특정 호스팅 플랫폼에 덜 종속되고 더 일관되게 배포될 수 있도록 어떤 약속을 하는지 설명한다.

문제는 오래됐다. 단일 Node.js 서버에서 next start로 앱을 띄우는 건 지금도 잘 된다. 하지만 서비스가 커져 여러 인스턴스로 확장되는 순간, 단순 실행만으로는 충분하지 않다.

  • 캐시가 인스턴스 간에 동기화되어야 한다.
  • on-demand revalidation이 전체에 전파되어야 한다.
  • streaming이 신뢰성 있게 동작해야 한다.
  • Server Components, middleware, Partial Prerendering, Cache Components 같은 기능도 일관되게 맞물려야 한다.

문제는 이 전체 표면이 그동안 명시적이고 안정적인 계약(contract) 으로 문서화되지 않았다는 데 있었다. 플랫폼 제공자 입장에서는 Next.js의 빌드 산출물을 읽고 자기 인프라에 매핑해야 하는데, 그 기준이 충분히 공개적이고 안정적이지 않았다.

여기서 큰 역할을 한 것이 OpenNext다. OpenNext는 Next.js 빌드 결과를 여러 플랫폼이 소비할 수 있는 형태로 옮겨 주는 다리 역할을 했다. 처음에는 호환 레이어에 가까웠지만, 특히 AWS 환경에서 상당히 실전적인 adapter 역할을 했고, 이후 Cloudflare와 Netlify도 참여했다.

이 경험을 바탕으로 Next.js 팀과 OpenNext 유지보수자, Netlify / Cloudflare / AWS Amplify / Google Cloud 엔지니어들이 함께 협업했고, 그 결과가 공식 Adapter API다.

Adapter API

빌드가 끝나면 Next.js는 앱에 대한 typed, versioned description을 만든다. 여기에는 다음 같은 정보가 담긴다.

  • routes
  • prerenders
  • static assets
  • runtime targets
  • dependencies
  • caching rules
  • routing decisions

플랫폼은 이 출력을 받아 자신의 인프라로 매핑하면 된다. adapter는 기본적으로 두 개의 훅을 구현한다.

  • modifyConfig
  • onBuildComplete

중요한 포인트는, Vercel도 같은 공개 계약을 쓴다는 점이다. 사적인 전용 훅이나 비공개 통합 경로가 아니라, 공개된 동일 API 위에 올라간다고 강조한다. Vercel adapter 역시 오픈소스다.

테스트 스위트

글은 여기서 한 걸음 더 간다. 단순히 API만 공개하는 게 아니라, adapter 작성자를 위한 공통 테스트 스위트도 공개한다.

이 테스트는 다음 같은 동작을 검증한다.

  • streaming behavior
  • caching interactions
  • client navigation
  • 실제 환경에서 터지는 edge case

즉, 플랫폼마다 “대충 되는 것 같다”가 아니라, 같은 기준으로 pass/fail을 측정할 수 있다. 게다가 이 테스트는 Vercel 자신이 쓰는 같은 스위트다. 실무적으로는 이게 꽤 중요하다. 특정 기능이 공식 문서상 지원된다고 해도, 실제 배포 플랫폼마다 미묘하게 다르게 동작하면 팀이 가장 크게 고생하기 때문이다.

Verified adapters

공식적으로 검증된 adapter가 되려면 두 가지 조건이 필요하다.

  1. 오픈소스일 것
  2. 전체 테스트 스위트를 통과할 것

검증된 adapter는 Next.js GitHub organization 아래에 호스팅되고, 관련 문서에도 실린다. 다만 소유권과 릴리스 주기, 구현 선택은 각 플랫폼 팀에 맡긴다. 플랫폼마다 구조가 다르기 때문이다.

현재 공개된 adapter는 다음이 포함된다.

  • Vercel adapter
  • Bun adapter

그리고 Netlify / Cloudflare / AWS(OpenNext 경유) 용 adapter는 올해 안 릴리스를 목표로 활발히 개발 중이라고 한다.

Ecosystem Working Group

Next.js 팀은 호스팅 제공자와 adapter 유지보수자가 함께 참여하는 Ecosystem Working Group도 상설화한다. 회의록은 공개될 예정이다. 의도는 분명하다. 플랫폼들이 변경 사항을 릴리스 이후 뒤늦게 알아차리는 게 아니라, 미리 보고 대응할 수 있게 하자는 것이다.

이 글의 톤은 사실상 하나의 선언문에 가깝다. Next.js는 더 이상 특정 플랫폼 전용에 가까운 프레임워크처럼 보이면 안 된다. Vercel 외 인프라를 쓰는 수많은 개발자도 같은 수준의 안정성과 최신 기능 접근성을 가져야 한다는 입장이다.

실무 관점에서 보면 이 변화의 의미는 크다.

  • 사내 인프라 / 멀티클라우드 / 규제 환경 때문에 Vercel을 못 쓰는 팀도 선택지가 넓어진다.
  • OpenNext 같은 커뮤니티 프로젝트가 공식 생태계의 일부로 흡수되며 불확실성이 줄어든다.
  • 배포 플랫폼 문제를 개별 팀이 우회하지 않아도 될 가능성이 커진다.

정리하면, 이 글은 단순 신기능 소개가 아니라 Next.js 배포 생태계를 표준화하려는 공식 방향 전환이다. FE 실무자 입장에서는 “프레임워크 선택 = 호스팅 락인”이라는 부담을 조금 줄여 주는 소식에 가깝다.

원문 제목: Announcing TypeScript 6.0 원문 링크: https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/ 번역일: 2026-03-31 KST

한국어 번역

TypeScript 팀은 TypeScript 6.0 공개를 발표했다. 이번 릴리스의 성격은 꽤 특이하다. 현재 JavaScript 코드베이스 기반 마지막 릴리스가 될 예정이며, 앞으로의 TypeScript 7.0+는 Go로 작성된 새로운 네이티브 코드베이스 위에 올라간다. 즉, 6.0은 5.9와 7.0 사이를 잇는 브리지 릴리스다.

팀은 이미 VS Code용 native preview와 npm 패키지 형태의 미리보기를 제공하고 있으며, 가능하다면 6.0을 도입한 뒤 7.0 preview도 같이 시험해 보라고 권한다.

베타/RC 이후 달라진 점

6.0 베타 이후 눈에 띄는 조정은 주로 7.0과의 정렬을 위한 것이다.

  • generic call 안의 함수 표현식, 특히 generic JSX 표현식의 타입 체크가 조정됐다.
  • import ... assert {} 문법의 deprecated 범위가 import() 호출까지 확대됐다.
  • DOM 타입이 최신 웹 표준과 Temporal API 변화에 맞게 업데이트됐다.

this를 쓰지 않는 함수의 context sensitivity 완화

기존에는 generic 추론 과정에서, 매개변수 타입이 명시되지 않은 함수가 있으면 TypeScript가 이를 “contextually sensitive function”으로 보고 추론 우선순위를 뒤로 미루는 경우가 있었다. 특히 메서드 문법은 암묵적인 this를 가진다고 취급되기 때문에, 화살표 함수와 같은 의미로 보여도 추론 결과가 달라질 수 있었다.

TypeScript 6.0은 여기서 한 걸음 나아가 실제로 this를 사용하지 않는 함수라면 contextually sensitive 하지 않은 것으로 본다. 그 결과, 이전에는 순서에 따라 unknown 오류가 나던 패턴들이 더 자연스럽게 추론된다. React/JSX 객체 리터럴 패턴에서도 체감이 있을 만한 변화다.

#/ 서브패스 import 지원

Node.js가 최근 #/* 형태의 subpath import를 허용하면서, TypeScript도 moduleResolution: nodenextbundler 모드에서 이를 지원한다. 기존에는 #root/*처럼 # 뒤에 한 세그먼트를 더 붙여야 했는데, 이제는 더 간결한 alias 패턴을 쓸 수 있다.

moduleResolution bundler + module commonjs

이전에는 bundler 해상도 모드를 esnextpreserve와만 조합할 수 있었지만, 6.0에서는 commonjs와의 조합도 허용된다. node10 해상도(deprecated)에서 더 현대적인 설정으로 넘어가려는 프로젝트에 현실적인 업그레이드 경로를 제공한다.

--stableTypeOrdering

TypeScript 7은 병렬 타입 체크를 통해 속도를 크게 올리지만, 병렬화는 내부 객체 방문 순서가 달라지면서 타입/심볼 ID 정렬이 비결정적이 되는 문제를 만들 수 있다. 이를 해결하기 위해 TS 7은 내용 기반 결정적 정렬을 도입한다.

6.0의 --stableTypeOrdering 플래그는 그 정렬 방식에 미리 맞춰 보는 도구다. 6.0과 7.0의 출력 차이를 줄여 주지만, 타입 체크 속도를 최대 25% 정도 늦출 수 있다고 한다. 상시 사용보다는 마이그레이션 진단용에 가깝다.

새 lib / 타입 추가

6.0은 몇 가지 최신 JS/웹 표준을 타입 레벨에서 더 잘 반영한다.

  • es2025 target/lib 지원
  • Temporal 타입 내장
  • Map/WeakMap의 getOrInsert, getOrInsertComputed 타입 추가
  • RegExp.escape 타입 추가
  • dom lib 안에 dom.iterable, dom.asynciterable 내용 통합

특히 DOM iterable 통합은 실무에서 체감이 크다. 예전에는 NodeList 순회 때문에 libdom.iterable을 따로 넣는 걸 자주 까먹었는데, 이제 기본 dom만으로 되는 방향이다.

이번 릴리스의 진짜 큰 변화: 기본값과 deprecated 옵션

6.0은 단순히 새 기능 몇 개 넣고 끝나는 버전이 아니다. 기본값과 설정 철학 자체가 현대 JS 생태계 기준으로 재정렬된다.

기본값 변경

  • strict 기본값이 true
  • module 기본값이 esnext
  • target 기본값이 최신 연도 ES 버전(현재 es2025)
  • noUncheckedSideEffectImports 기본값이 true
  • libReplacement 기본값이 false

즉, 신규 프로젝트는 더 엄격하고, 더 ESM 친화적이며, 더 현대 런타임 기준으로 시작하게 된다.

rootDir 기본값 변경

이제 rootDir 기본값은 항상 tsconfig.json이 있는 디렉터리다. 예전처럼 공통 소스 루트를 추론해 주지 않는다. 소스가 src/ 아래 있고 출력 경로가 미묘하게 꼬이는 프로젝트는 rootDir: "./src"를 명시해야 할 가능성이 크다.

types 기본값이 []

이건 영향이 꽤 클 수 있다. 예전에는 node_modules/@types 아래 패키지를 사실상 광범위하게 끌어왔지만, 이제는 기본적으로 아무 것도 자동 포함하지 않는다.

따라서 process, fs, describe, jest, Bun 같은 전역/런타임 타입이 필요하면 직접 types 배열에 넣어야 한다.

예:

{
  "compilerOptions": {
    "types": ["node", "jest"]
  }
}

팀은 이 변경만으로도 일부 프로젝트에서 빌드 시간이 20~50% 개선됐다고 말한다.

주요 deprecated / 제거 사항

6.0은 오래된 설정을 꽤 공격적으로 정리한다.

  • target: es5 deprecated → 최소 타깃은 사실상 ES2015 이상
  • --downlevelIteration deprecated
  • --moduleResolution node (node10) deprecated
  • --moduleResolution classic 제거 방향
  • module: amd | umd | systemjs | none 제거
  • baseUrl deprecated
  • esModuleInterop: false, allowSyntheticDefaultImports: false 불가
  • alwaysStrict: false 불가
  • outFile 제거
  • namespace 자리에 쓰던 구문 module Foo {} deprecated
  • import assertion의 asserts 문법 deprecated → with 사용
  • /// <reference no-default-lib="true"/> 지원 중단
  • tsconfig.json이 있는 폴더에서 tsc foo.ts처럼 파일을 직접 넘기면 에러

특히 baseUrl deprecated와 types 기본값 변경은 monorepo / 오래된 프론트엔드 레포에서 꽤 많은 설정 손질을 유발할 수 있다. 경로 별칭과 런타임 타입 의존이 얽힌 곳은 업그레이드 전에 꼭 확인해야 한다.

TypeScript 7.0 준비

TypeScript 팀의 메시지는 분명하다.

  1. 6.0을 안정적으로 도입해라.
  2. deprecation warning을 가능한 빨리 정리해라.
  3. 그 다음 7.0 native preview를 시험해라.

즉, 6.0은 최종 목적지가 아니라 7.0 이전 정리 작업에 가깝다. 하지만 동시에, 오늘 바로 써도 되는 안정 릴리스이기도 하다.

정리하면 이번 글의 실무 포인트는 이렇다.

  • React/JSX 타입 추론과 최신 웹 표준 타입은 조금 더 좋아졌다.
  • 하지만 더 큰 이슈는 tsconfig의 기본값과 구식 옵션 정리다.
  • 프론트엔드 팀은 6.0 업그레이드 시 types, rootDir, path alias, module resolution을 가장 먼저 점검하는 게 좋다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment