
자바스크립트로 날짜를 다뤄 본 사람이라면 Date 객체 때문에 한 번쯤 고생했을 것이다. 월이 0부터 시작하고, 시간대 처리가 불안하고, 객체가 변경 가능해서 실수하기 쉽다. 그래서 대부분 moment나 date-fns, dayjs 같은 라이브러리를 깔았다. 2026년 5월 5일에 나온 Node.js 26이 Temporal API를 기본으로 켰다. 이 글은 그게 무엇을 바꾸는지, 그리고 26으로 올릴 때 함께 걸리는 제거 항목들을 정리한다.
Date 가 왜 문제였는지부터
Temporal이 왜 필요한지는 Date의 결함 목록을 보면 바로 납득된다.
const d = new Date(2026, 8, 11); // 8 = 9월. 월은 0부터 시작한다
d.setMonth(d.getMonth() + 1); // 원본이 바뀐다. 불변이 아니다
new Date("2026-09-11") // UTC 로 해석
new Date("2026/09/11") // 로컬 시간으로 해석
마지막 두 줄이 특히 악명 높다. 구분자 하나 차이로 해석이 달라진다. 여기에 시간대까지 얽히면, 한국에서 테스트할 때는 맞다가 UTC 서버에서 하루씩 밀리는 버그가 나온다.
Date는 1995년에 자바의 java.util.Date를 열흘 만에 본떠 만든 것으로 알려져 있고, 그 자바 클래스조차 이후 java.time으로 대체됐다. 30년간 고치지 못한 이유는 웹의 하위 호환성 때문이다. 고칠 수 없으니 새로 만들어 나란히 두는 것이 Temporal의 접근이다.
Temporal 은 타입을 나눈다
Temporal의 핵심 설계는 "날짜"라는 하나의 개념을 여러 타입으로 쪼갠 것이다.
Temporal.Now.plainDateISO() // 2026-09-11 (시간 없음)
Temporal.Now.instant() // 절대 시점 (시간대 무관)
Temporal.Now.zonedDateTimeISO() // 시간대가 붙은 날짜시간
Temporal.Duration.from({ hours: 3 })

Date로 저장하면 시간대가 붙어버려서, 조회하는 위치에 따라 하루 밀리는 일이 생긴다. PlainDate를 쓰면 이 오류가 타입 수준에서 막힌다.
객체가 불변이라는 점도 크다. 연산은 항상 새 객체를 돌려준다.
const start = Temporal.PlainDate.from("2026-09-11");
const end = start.add({ days: 30 }); // start 는 그대로
console.log(start.until(end).days); // 30
start가 바뀌지 않으므로, 함수에 날짜를 넘겼다가 원본이 오염되는 사고가 없다.
26으로 올릴 때 같이 걸리는 것들
Node 26은 메이저 릴리스라 제거 항목이 함께 왔다. 올리기 전에 확인해야 할 목록이다.
| 영역 | 변경 |
|---|---|
| HTTP | http.Server.prototype.writeHeader() 완전 제거 → writeHead() 사용 |
| Stream | _stream_wrap, _stream_readable, _stream_writable, _stream_duplex, _stream_transform, _stream_passthrough 완전 제거 |
| Crypto | DEP0182 지원 종료 |
| Module | --experimental-transform-types 제거 |
| Module | module.register() 런타임 경고로 강등 |
| Build | GCC 13.2 이상 요구, Python 3.9 지원 중단 |
_stream_* 계열은 원래 내부 모듈이라 직접 쓰면 안 되는 것이었는데, 오래된 패키지가 여전히 참조하는 경우가 있다. 의존성 트리에서 나오면 그 패키지를 올려야 한다.
엔진도 올라갔다. V8이 14.6.202.33이 되면서 Map.prototype.getOrInsert()와 Iterator.concat() 같은 것이 들어왔다. HTTP 클라이언트인 undici는 8.0.2다.
Node 26은 10월에 LTS로 전환된다. 그 전까지는 Current이므로, 프로덕션이라면 LTS 전환 이후에 올리는 것이 안전하다.
날짜 라이브러리를 지금 걷어내야 하나
여기가 실제 판단이 필요한 지점이다. 나는 새 코드부터 Temporal로 쓰고, 기존 코드는 서두르지 않는 것을 권한다. 이유가 셋이다.
첫째, 브라우저 지원이 아직 고르지 않다. Node에서 기본으로 켜졌다는 것이 모든 런타임에서 쓸 수 있다는 뜻은 아니다. 프런트엔드와 백엔드가 날짜 처리 코드를 공유한다면 폴리필이 필요하다.
둘째, 라이브러리가 주는 것이 날짜 연산만은 아니다. 상대 시간 표기("3일 전"), 로케일별 포맷, 파싱 같은 기능은 여전히 라이브러리 쪽이 편하다. Temporal에도 포맷 기능이 있지만, 기존 코드의 출력 형식을 정확히 재현하려면 손이 간다.
셋째, 바꾸는 과정에서 버그가 난다. 날짜 로직은 테스트가 어렵고, 시간대 경계나 윤년처럼 드물게 터지는 조건이 많다. 잘 돌아가는 코드를 이유 없이 건드릴 이유가 없다.
그러면 언제 바꾸나. 날짜 관련 버그가 실제로 났을 때가 가장 좋은 시점이다. 그 버그가 Date의 구조적 결함 때문이라면, 고치는 김에 그 모듈만 Temporal로 옮긴다. 전면 교체보다 이쪽이 위험이 적고 효과는 비슷하다.
새 프로젝트라면 이야기가 다르다. 의존성 하나를 덜 깔 수 있고, 표준이라 앞으로 사라지지 않는다. dayjs가 가볍다지만 표준 API보다 가볍지는 않다.
표준이 라이브러리를 대체하는 흐름
Temporal은 최근 자바스크립트에서 반복되는 패턴의 한 사례다. jQuery가 하던 일을 querySelector와 fetch가 가져갔고, lodash의 상당 부분을 표준 배열 메서드가 가져갔다. 이제 날짜 라이브러리 차례다.
이 흐름의 좋은 점은 분명하다. 번들 크기가 줄고, 의존성 감사 대상이 줄고, 새로 합류한 사람이 배울 것이 줄어든다. 표준은 문서가 잘 되어 있고 사라지지 않는다.
다만 표준화는 느리다. Temporal은 제안된 지 여러 해 만에 런타임 기본값이 됐다. 그동안 라이브러리들이 그 자리를 메웠고, 그게 나쁜 일도 아니었다. 라이브러리가 먼저 문제를 풀고, 검증된 해법이 표준이 된다. 지금 쓰는 라이브러리가 언젠가 표준에 흡수될 수 있다는 것을 알고 쓰면, 교체 시점을 놓치지 않는다.
서버 코드에서 특히 조심할 지점
날짜 버그는 대개 로컬 개발 환경과 서버 환경의 시간대가 달라서 생긴다. 이 함정을 피하는 규칙을 정리하면 이렇다.
저장은 항상 UTC 절대 시점으로. 데이터베이스에 넣는 값은 Instant나 그에 대응하는 타임스탬프여야 한다. 로컬 시간을 저장하면 나중에 어느 시간대 기준인지 알 수 없다.
표시할 때만 시간대를 붙인다. 사용자에게 보여주는 순간에 ZonedDateTime으로 바꾼다. 서버 코드 중간에 시간대를 오가면 변환이 중복되면서 오차가 쌓인다.
"오늘"의 기준을 명시한다. 일별 집계를 낼 때 "오늘"이 서버 시간대인지 사용자 시간대인지 정해야 한다. 정하지 않으면 자정 근처의 데이터가 애매해진다. Temporal은 이걸 타입으로 강제하지는 않지만, PlainDate와 ZonedDateTime을 구분해 쓰면 코드에서 의도가 드러난다.
이 세 가지는 Temporal을 쓰든 안 쓰든 유효하다. 다만 타입이 나뉘어 있으면 규칙을 어겼을 때 눈에 더 잘 띈다.
참고 자료
- Node.js 26.0.0 (Current) — 공식 릴리스 노트 — 릴리스 일자, Temporal 기본 활성화, V8·undici 버전, 제거 항목 전체
- Node.js 26 ships with Temporal API enabled by default — Help Net Security — 릴리스의 의미에 대한 외부 정리
- What's new in Node.js 26 — 변경 항목별 마이그레이션 관점의 설명
'IT' 카테고리의 다른 글
| React 20이 없는 이유와 React Compiler (0) | 2026.10.04 |
|---|---|
| 자바 버전 지금 뭘 써야 하나, LTS와 Valhalla (0) | 2026.10.03 |
| Go 1.26 Green Tea GC, 무엇이 빨라졌나 (0) | 2026.10.01 |
| Python 3.15와 GIL, 무엇이 실제로 바뀌나 (0) | 2026.09.30 |
| TypeScript 7 출시, Go 컴파일러로 10배 빨라졌다 (0) | 2026.09.29 |
