3-15. "프로덕션이라는 말" — config 시스템·CJS DCE·styled/emotion 트랜스포머

기간: 2026년 4월 24일 ~ 4월 30일 (7일) 커밋: zts 약 543개 (4/24 57 · 4/25 102 · 4/26 76 · 4/27 34 · 4/28 91 · 4/29 90 · 4/30 93) 핵심: type-only import elision 근본 수정 Phase D, oxc 스타일 AST cosmetic refactor #1802 (--strict-cosmetic CI 게이트), Astro Starlight 문서 사이트 전면 개편, manualChunks 에픽 #1027 (Rollup parity 64%→93%), FileSystem 추상화 + WASM 번들러 #1885, runtime-helper virtual module #1961 + ES5 헬퍼 null-prefix 근본 수정, config 시스템 (zts.config.* / .env / --mode / extends / workspace), CJS DCE 에픽, styled-components·emotion 트랜스포머 정식 스펙 parity, "프로덕션 레벨 배포에 부족한 것" 첫 점검, 그리고 OpenAI Codex 등판 진행 중 — 이 편이 담는 대부분은 여전히 에픽으로 열려 있다. 머지된 phase와 리뷰 중인 phase가 섞여 있다.

이 편의 위치

3-14는 4/19~4/23의 RFC 시리즈 — References 통합, oxc 스타일 AST 재설계(D1 리버트 후 debug infra 위에서 재진입), HMR 프로파일 계층화, ModuleGraph accessor, require.context, Expo — 로 끝났다. 그 마지막에 "4/23 시점에 진행 중인 에픽" 표가 길게 붙어 있었다. 이 편은 그 표의 항목들이 하나씩 닫히고, 동시에 "학습 프로젝트"라는 자기소개를 슬그머니 내려놓고 "프로덕션 레벨 배포 준비"라는 단어를 처음 입에 올린 7일이다.

그리고 이 7일 안에 또 하나의 변화가 있다 — OpenAI Codex CLI를 병행 투입하기 시작했다. 처음엔 같은 zts 폴더에서, 4/29부터는 zts-codex라는 별도 클론에서. 두 AI가 같은 GitHub 저장소·같은 이슈/PR 풀을 공유하며 갈라져 작업하는 구도가 이때 만들어졌다. 자세한 회고는 3-17 끝에 둔다.

4/24 — type-only import 근본 수정, AST cosmetic refactor, 문서 사이트 갈아엎기

require가 없다

이날 오전, RN 앱이 또 깨진다:

09:35
> "[runtime not ready]: ReferenceError: Property 'require' doesn't exist ..."
09:41 > "왜 근데 감지 못했던거예요?"
10:08 > "근본으로 고쳐주세요 우회하지말고"

원인은 type-only import elision이 불완전해서 import type만 남은 모듈 참조가 런타임 require()로 새어 나간 것. 4/23 RFC #1672 시리즈 때부터 끌고 온 project_type_only_import_elision.md의 "구현 설계" 섹션을 꺼내 축 A → 축 B 순서로:

12:03 > "축 A → 축 B 순서로 진행해줘"
12:04 > "네 좋아요 추천대로 가시죠 /simplify 각각 PR마다 진행하고 순차적으로 할 것"
12:08 > "임시로 막는거만 되는거 아니예요? 근본 수정은 무엇인데요?"
12:13 > "네 근본으로 가시죠 무조건 근본"
13:54 > "번들러들끼리도 비교해서 어떤게 가장 근본적인 수정인지 확인해주세요"

이 "근본으로 / 무조건 근본 / band-aid는 싫다 / 다른 번들러는 어떻게 하는데"의 4박자가 이 편 7일을 (그리고 이후 전 기간을) 관통한다. type-only import elision은 16개 바인딩 캡을 제거하고 unresolved는 soft-fail하는 쪽으로 Phase D까지 진행(#2466 등은 5/3에 닫힌다).

AST cosmetic refactor #1802 — 그리고 --strict-cosmetic

3-14의 RFC #1672(oxc 스타일 단일 in-place AST)는 D1 리버트 이후 "debug infra 위에서 재진입"이 정답이었다. 그 재진입의 첫 단계가 cosmetic refactor — 동작을 바꾸지 않고 노드 구조만 oxc에 맞춰 정리하는 카테고리 A/B/B2/C/special. --strict-cosmetic CI 게이트를 만들어 "이번 PR은 cosmetic만"임을 기계로 강제했다. Tag↔variant 정합성 정적 감사(#1797), flow_match_arm 태그 분리(#1822)도 이 흐름.

13:59 > "리버트 머지 안하고 그냥 메인기준에서 작업해서 해도 되지 않나요? oxc-style로 가시죠"
15:21 > "oxc으로 하면 지그에선 성능 손해도 보지?"
15:22 > "재 설계하면 성능이랑 유지보수 둘 다 잡나 아니면 성능을 잃나?"

"진짜 Full AST로 재작성" — 그리고 백로그

같은 날 더 큰 질문이 떠올랐다. std.zig.Ast.parse 같은 네이티브 파서 수준으로 zts AST 자체를 다시 짤 것인가?

16:04 > "std.zig.Ast.parse native 파싱 이라고 했는데 왜 지금은 네이티브 파싱이 아닌거예요?"
16:17 > "진짜 Full AST 로 재작성"
20:03 > "완전 교체는 무슨말이예요? std.zig.Ast.parse가 정확히 뭔지 설명해주세요"
20:11 > "그럼 저걸 할 이득이 있다는거 아니야? 나 이해가 안돼 초보자한테 설명하는것처럼 다 개념부터 제대로 설명해줘"
20:13 > "일단 그럼 백로그로 남겨두자"

이득(parse-once, identity preservation 끝까지)은 분명했지만 비용이 더 컸다. cosmetic refactor + Phase C/D로 충분히 수렴할 수 있다고 보고 백로그. (3-14의 "AST 설계는 2주짜리 프로젝트에서도 한 번 더 갈아엎게 된다"는 교훈이 또 적용됐다 — 이번엔 "더 갈아엎지 않기로" 결정했다는 게 차이.)

문서 사이트를 갈아엎다

14:18 > "지금 문서 사이트 디자인이 너무 허접한데 어떻게 갈아 엎는게 좋아?"
14:22 > "타우리가 젤 깔끔한거 같은데 테일윈드 기반으로 할 수 있나?"
14:30 > "스타일은 Tauri 스타일을 원하는데 메뉴 구성이나 이런것들을 Biome로 가길 원하는거고"
14:38 > "bun.sh식 / 코드탭 필요 / 벤치마크도 랜딩에 보여주고 / 벤치마크는 근데 다시 측정해야해"
14:55 > "테일윈드 쓰는데 왜 인라인으로 스타일 박아요?"

Astro/Starlight 기반으로 랜딩 페이지를 Zig 오렌지 팔레트 + 스플래시 레이아웃 + 8그룹 사이드바로 재설계. 이날 저녁 내내 히어로 정렬·다크모드·레이어 깨짐(* { margin: 0 }이 범인) 보고가 반복됐다:

17:42 > "* { /* margin: 0; */ } 이 속성이 문제 같아요"
17:48 > "그부분 수정말고 걍 그 히어로 영역만 커스텀 스타일 적용하면 안될까? 원래대로 돌리고"

문서 사이트는 이후 5/11까지 계속 보강된다 — 이 프로젝트가 "공개"를 진지하게 생각하기 시작했다는 가장 가시적인 신호다.

require.context Phase 4(#1579 — graph dep + tree-shake root 연결), for-of+let 클로저 캡처 → _loop 추출(#1807), IIFE+external+globals(#1824)도 같은 날.

4/25 — manualChunks parity, WASM 번들러, 스모크 테스트 폭격

manualChunks 에픽 #1027

Rollup/rolldown의 manualChunks(어떤 모듈을 어느 청크에 넣을지 사용자가 지정) — 부분 구현 상태였다. Phase 1(substring 매칭), Phase 2(함수 resolver), NAPI 브리지, meta API까지 채워 Rollup parity를 **64% → 93%**로. inlineDynamicImports도 같이.

01:32 > "이번 주제 연속이 근데 왜이리 오래걸려요??"
01:39 > "실제 롤다운이나 esbuild는 어떻게 에러 주는지?"
01:47 > "그리고 레퍼런스 롤다운쪽에서 봐서 거기서도 테스트코드 있음녀 가져와줘"
02:33 > "근본 수정이 B죠?"  ...  02:50 > "A로 가자"
03:22 > "근본수정은 뭔데?? 왜 롤다운은 근본 수정 안한거야?"
03:30 > "일단 A로가고 B 근본 추후에 갈거라고 적어줘"

FileSystem 추상화 + WASM 번들러 #1885

"Playground 번들러 모드" — 브라우저에서 zts 번들러를 돌리려면 파일시스템이 추상화돼야 한다.

15:48 > "#1885 — Playground 번들러 모드 이 이슈 진행하고 싶은데 어떻게 하는게 좋을까?"
15:51 > "왜 정공법은 안되는거야? 침적 리팩토링이 어떤 말인지?"
15:53 > "장기 가치가 크면 거기로 가자 플랜 한번 세워봐"
16:53 > "호환성이란게? wasm도 독자 디자인으로 가면 지그 코어도 편해지나?"
16:59 > "외부호환은 고려할 필요 없어 독자적인걸로 갈꺼야"
17:01 > "근데 디버깅은 할 수 있어야 하는거 아니예요? ABI 동기화가 왜 안정화가 차이 있는거예요? 저 잘 몰라서 최대한 자세히 설명해주세요"

RealFS / VirtualFS(host-JS 콜백) / ResolvedModule 유니온, wasm-bundler 빌드 타깃, Astro COOP/COEP, playground 번들러 페이지. 트랜스파일 wasm과 번들러 wasm을 별도 페이지로 분리:

23:20 > "그럼 웹페이지에는 wasm 트랜스파일러는 필요 없어지지않아요?"
23:21 > "일단 분리로 가고 번들러페이지는 플레이그라운드 페이지를 따로 나눌까요??"
04:03 > "계속 발견하는데 게속 더 해봐 실라이브러리"
04:07 > "리액트나 이런거 더 많이 쓰는 라이브러리 더 추가해줘 스모크 테스트"
18:19 > "pnpm, yarn pnp, npm도 고려ㅇ해야하는거 아니에여?"
18:20 > "bun이랑 pnpm symlink랑 거의 동일한 구조로 알고 있는데"

스모크 테스트 라이브러리 대량 추가 + pnpm/bun symlink farm 해석(#1921). async-generator/__asyncGenerator(#1911), async this binding(#1909), yield* iterable wrap(#1910), if-await ES5 generator state-machine(#1887) — ES5 다운레벨의 빈칸도 메웠다. bundle-perf regression-guard 인프라 + baseline도 이날.

4/26 — Codex 등판, runtime-helper virtual module, ES5 헬퍼 null-prefix 근본 수정

"당신은 버그 헌터예요"

이날 처음으로 OpenAI Codex CLI에 작업이 떨어진다 — 처음엔 같은 zts 폴더에서:

[Codex, 15:42]
> "당신은 버그 헌터예요  트랜스 파일링 ES 다운 레벨링에서 버그 있는지 재현코드로 재현해서 버그 한번 잡아보시곘어요?"
[Codex, 19:50]
> "https://github.com/ohah/zts/issues/2010 이거 수정해줄 수 있어?"
> "루트커즈를 수정해야합니다"

Codex의 무게중심은 처음부터 분명했다 — 번들 크기/속도 회귀 전수조사 + root cause 수정, 그리고 Svelte/effect/date-fns 같은 라이브러리에서 "왜 우리가 rolldown보다 큰가". (4/27 Codex: purity + statement DCE 계획 세워주세요 / 세우신 계획이 루트커즈 수정이예요?)

ES5 헬퍼 null-prefix — 모든 헬퍼를 바꿔야 하나

__commonJS, __create, __defProp 같은 런타임 헬퍼가 splitting 모드에서 제대로 분배되지 않거나 이름이 충돌하는 문제. oxc는 헬퍼를 virtual module로 빼서 그래프에 정식 노드로 넣는다:

10:24 > "https://github.com/ohah/zts/issues/1961 이 이슈 해결하기전에 다른 번들러들은 이 문제 어떻게 해?"
10:34 > "oxc식 null prefix 해도 es5 만 돌아가는 브라우저에 문제없어?"
10:51 > "안ㅣ하위버전고려하지말고 모든 헬퍼 바꿔야 하는거 아니야?"
11:07 > "그래 인프라 하자 매핑형 테이블 만들어"
11:30 > "머지해 바로"

runtime-helper-virtual-module 에픽 #1961 — loader 인프라, 14개 누락 헬퍼 매핑, splitting 모드 분배, single-bundle 활성화, transformer pre-pass + builtin plugin. 동시에 ES5 class/super 다운레벨의 정확성을 대대적으로 쓸었다 — NewTarget 캡처, derived-ctor super receiver _this(#2022), wrapped-super lowering(#2030), optional-chain super(#2034), parameter-property 순서. CJS interop도(ESM external을 require로 보존 #1962, __toESM transitive default re-export 회귀 #812).

"CLI가 왜 느려졌지?"

18:21 > "실측에 맞게 업데이트 해주세요 근데 vue 진짜 저렇게 느려요??"
18:26 > "esbuild, rolldown, rspack 속도 차이 비교해봐주세요 한번 실행해서"
18:30 > "rspack 왜이리 빨라??"
18:32 > "그리고 cli 도 원래 빨랐었는데 왜 느려졌지?"
18:37 > "CLI는 왜 느린거예요??"
18:44 > "napi는 빌드를 해서 빨랐던거죠?"

결론: NAPI 경로는 미리 빌드된 네이티브 바이너리라 빠르고, CLI는 매번 컴파일해서 느렸던 것 — 측정 환경의 문제였지 코드 회귀가 아니었다. (이 "추론 말고 실측"은 3-14에서도 반복됐던 패턴.) innerGraph 같은 개념을 다시 설명받고, axios CI fail 재발 원인을 추적했다.

4/27 — 회귀 추적, /simplify 정리

비교적 한산한 날(34 커밋). 직접 올린 PR을 /simplify로 일괄 정리하고, smoke FAIL이 다시 난 패키지들(semver@es5, neverthrow, minimatch, cheerio, kysely)의 회귀 원인을 추적했다:

14:20 > "neverthrow / minimatch / cheerio / kysely / FAIL 아니던거 나는데 확인해줘"
15:57 > "semver@es5 FAIL도 원래 안 났었는데 이제 이 원인 확인해주실 수 있을까요?"
16:11 > "테스트코드랑 회귀케이스 잘 작성해주셨나요?"

bundler tree-shaking/DCE refinement(순수 class expression, post-declaration assignment, re-export-star reachability, post-transform analysis refresh, transform-source를 캐시 키에), HMR 메모리 ownership 수리, Expo RN dev rewrites 안정화도 이날.

4/28 — config 시스템, CJS DCE, 그리고 "프로덕션 레벨 배포에 부족한 것"

config 시스템 에픽

zts.config.{ts,mjs,js,cjs,json} 자동 발견, .ts/.js self-compile loader, --mode + zts.config.{mode}.*, .env 자동 로드 + import.meta.env 정적 치환, extends + 사이클 탐지, Levenshtein "did you mean?" 오타 탐지, 함수형 config, zts.workspace.ts(Vitest 스타일 모노레포), config/.env 변경 시 watch 자동 재시작.

17:34 > "그리고 zts.config.ts가 부족한거 말해주고"
17:36 > "좋아요 그거 다 해주세요 모노레포 기준으로는 vitest 벤치마킹해서 작업"
19:17 > "Node 24 .ts 한계가 뭐죠?"
19:20 > ".ts 생략 한거 다 바꾸시면 되지 않아요?"
20:10 > "dotenv 자동으로 읽는거죠?"
20:22 > "별도 PR 로 하는게 장기적으로 좋지? CLI 플래그"
22:54 > "PR #2134 (feat/zts-workspace) CI 진행 상황을 확인하고, 통과했으면 머지하고, 실패했으면 원인 분석 후 수정해주세요. ... Phase 3 잔여 진행 중."
23:13 > "직접 테스트 해보실 수 있나요? 부족한 부분은 없나요? 그리고 왜 cli랑 옵션이 상이하죠?"

CLI ↔ BuildOptions ↔ WASM 스키마 동기화, TypeScript 5.9.3→6.0.3, oxlint 경고 0개도 같은 흐름.

CJS DCE 에픽 — "장기적으론 다 해야하는거죠?"

CJS 출력의 dead code elimination — Object.defineProperty getter/value export DCE, __esModule 마커 가지치기, dead-write/dead-store 가지치기, 새 Object.assign/Object.freeze를 pure로 취급. 여기서 매번 나온 질문이:

14:50 > "지금 아스트로 문서 사이트 메인 스플래쉬 화면이 반응형에 대응 안되어있는데 확인해주세요"
15:25 > "(() => { ... })(); 이 코드 왜 이렇게 개행까지 되는거예요?"
15:26 > "근데 보통 한줄 개행이 일반적이지 않아요? 왜 여려러줄 개행이 된걸까요?"
15:27 > "그리고 다른 번들러들도 그렇게 하는지?"
16:35 > "장기적으론 다 하긴 해야하는거죠?"
16:39 > "그럼 지금처럼 일부만 바꾸는것도 이득 없는거 아니예요?"

"일부만 바꾸면 이득 없다 → 전수로 해라"는 이 무렵 자주 나온 판단 기준. 4/29~4/30에 더 밀어붙인다.

"프로덕션 레벨 배포 하려면 부족한 게 뭐예요?"

이 편에서 가장 의미 있는 한 문장:

17:24
> "이제 프로덕션 레벨 배포 하려면 부족한것들이 뭐뭐 있을까요?"
17:33 > "그리고 해야할거 표로 정리해봐"

3-1의 "공부용이긴 하지만 그래도 프로덕션 레벨을 고민하면서"가 36일 만에 "이제 프로덕션 레벨 배포"가 됐다. 동시에 묵은 이슈를 닫는다:

17:26 > "#1747 HMR warm 174ms → 100ms 미달성 ... 이거 달성했음 클리어 해주세요 최근 PR 보면 제가 HMR 수정한거 있는데 이거 해결됐어요"
17:30 > "hmr은 이슈 클로즈"

3-14의 진행 중 에픽 표에 있던 HMR #1747이 여기서 닫힌다.

4/29 — 옵션 갭 메우기, IIFE 디폴트 제거, 그리고 zts-codex 분리

"다른 번들러 대비 딸리는 옵션이 뭐야?"

05:56 > "그건 됐고 비트나 롤다운 rspack에 비해 우리가 딸리는 설정이나 옵션들이 뭐야?"
06:00 > "넵 그럼 이슈탭에 정리 해주시고"
06:03 > "추천하신 순위대로 진행가시죠"
06:15 > "builtin loader (dataurl / base64 / copy / binary) 라고 하셨는데 롤다운은 지원 안해요?"
06:19 > "그건 냅두시고 그럼 아까 말한 진짜 갭 다 구현까지 해서 구현 진행하시죠 이번에"

base64 loader, onLoad loader override(#2157), sourcemap 3-mode(inline/external/linked, #2217), Vite 스타일 alias 배열, preserveSymlinks, single-file dynamic-import 자동 lazy-wrap(#2209/#2211), 사이클 const/let/class → var 강등(ESM live binding, #2198), string-enum reverse-mapping 제거(#2192), 플러그인 lifecycle hook buildStart/buildEnd/closeBundle(#2156).

IIFE 디폴트 포맷 제거

15:03 > "그리고롤다운도 깨져??"
15:04 > "근데 왜 우린 IIFE로 되지?"
15:05 > "디폴트 포맷이 IIFE인 애들은 없지?"
15:06 > "일단 default IIFE는 제거하자 코드 제거는 쉽자나 그건 걍 여기 작업에 포함"
16:57 > "파일 fallback 으로 동작 ... 라고 하셨는데 ... fallback은 의도적인 정책이 아니라면 무조건 없어야 하는데"

"의도된 정책이 아닌 fallback은 무조건 없앤다" — 이 원칙이 4/30 styled-components/emotion의 SKIP fallback 제거로 그대로 이어진다.

zts-codex 별도 클론

이날부터 Codex 세션의 작업 디렉터리가 ~/Documents/workspace/zts에서 ~/Documents/workspace/zts-codex(별도 클론, 같은 origin remote)로 옮겨진다. 같은 시각대에 Claude는 zts에서, Codex는 zts-codex에서 — 둘이 같은 GitHub 이슈/PR을 던져받고, 작업 시작 시마다 git switch main && git pull로 상대방 결과를 흡수하는 구도. 이날 Codex 쪽 흐름은 번들 크기 회귀 전수조사(mobx/d3/lru-cache/dotenv/toolkit/semver/dayjs)와, 한발 더 나가 ZTS를 standalone Vite-style app builder로 포지셔닝(zts dev/build/preview, HTML entry, .env, publicDir, base, Tailwind/PostCSS, dev CSS HMR):

[Codex, 04:31] > "https://github.com/ohah/zts/issues/2060 이거 좀 오래됐는데 지금 다시 체크하셔서, mobx 기준으로 우리가 뭐가 용량이 큰 지 확인할 수 있을까요?"
[Codex, 06:16] > "레퍼런스 폴더에 롤다운 클론 한번 해주실래요?"
[Codex, 11:43] > "지금 프로젝트에서 vite, rspack에 비해 부족한 옵션이나 기능이 뭐가 있을까"
[Codex, 18:50] > "좋아요 진행해주시고 테스트케이스 반드시 e2e로 검증해가면서 하셔야해요"

4/30 — styled-components·emotion 트랜스포머, "CSS 파서가 없어서"

SKIP fallback을 근본으로

10:19 > "spread element ({...userConfig}) 시 SKIP fallback (런타임 override 위험) ... 이것도 근본으로 수정해야하는거 아니예요? 왜 스킵"
10:46 > "재사용 왜 향후로 미루신거에요?"
13:17 > "넵 무조건 루트 커즈 잡는게 나아요"
13:45 > "이모션 정식 스펙으로 갔으면 좋겠는데"

emotion / styled-components 트랜스포머 정식 스펙

이날 zts는 Babel 플러그인 없이 자체 트랜스포머로 styled-components와 emotion을 처리한다 — RN/네이티브 지원의 핵심 차별점이다.

  • emotion: autoLabel(never/always/dev-only), @emotion/styled default 탐지, ClassNames render-prop, css prop object/array, keyframes/Global/injectGlobal autoLabel, importMap, labelFormat/sanitizeLabelPart, sourceMap 인라인 코멘트, styled chain walker(withComponent/attrs).
  • styled-components: componentId 해시, withConfig MERGE/preserve, cssProp Steps 1~6(intrinsic tag → custom component → object form → auto-inject + program-level hoist), minify/ssr/pure/namespace/fileName/meaninglessFileNames/topLevelImportPaths 옵션, picomatch 호환 glob 유틸.
16:45 > "왜 이게 어렵지?"
16:47 > "css 파서가 없어서인가?"
16:47 > "바벨은 css로 하고 있는거야?"
17:23 > "그럼 제대로 안되는거잖아요?? 팔로업 이랑 미지원 세션 케이스까지 다 진행해주세여"
17:24 > "바벨도 안되는거면 상관없는데 바벨이 되는데 우린 안되는거면 문제가 있어요"

"바벨이 되는데 우리만 안 되면 문제" — 이게 parity의 기준선이다. Buffer overflow 차단 (256B 스택 버퍼) 같은 임시 방어도 "fallback 없이 완벽하게 못 하나요?"로 도전받았고(5/3에 ArrayList 전환으로 해결), RN 쪽 실패 케이스는 "보편적인 루트커즈 해결은 아닌거네요? 점진적으로 다 해결해주시죠"로 백로그됐다.

도그푸드 — 외부 IP로 예제앱 접속

18:06 > "예제 앱들 한번 12300으로 포트 해서 실행시켜 볼 수 있나여 스타일 컴포넌트랑 이모션"
18:12 > "http://118.217.211.243/ 이게 외부아이피라서 이걸로 접속해보려했더니 안되네요 이유가?"
18:22 > "픽스쳐 예제 추가하시고, band-aid는 하위버전 필요 없으니 지워주시면 됩니다"

ES5 다운레벨 정정도 이날 또 한 차례 쓸었다. Codex 쪽은 24-byte compact node vs ESTree AST 토론(처음부터 이걸 고려했으면 성능에도 문제없고 잘 만들어졌을 수 있을까? / 록다운이나 swc는?)과 메인 기준 문법 변환 전수조사(또 한번 해주세요 할때마다 계속 나오네요 / 무조건 루트커즈 수정을 해주세요)를 돌렸다.

7일간 관통한 것들

귀결
type-only import elisionPhase D — 16-binding 캡 제거, unresolved soft-fail. RFC #1672 시리즈의 마무리
AST cosmetic refactor #1802oxc 구조로 정렬, --strict-cosmetic CI 게이트. "Full AST 재작성"은 백로그
문서 사이트Astro/Starlight 전면 개편 — Zig 오렌지 팔레트, 코드 탭, 벤치마크. "공개"를 진지하게
manualChunks #1027 / WASM 번들러 #1885Rollup parity 64→93%, RealFS/VirtualFS, 브라우저 playground 번들러
runtime-helper virtual module #1961헬퍼를 그래프 정식 노드로. ES5 class/super 다운레벨 대대적 정정
config 시스템zts.config.* / .env / --mode / extends / workspace. CLI↔BuildOptions↔WASM 스키마 동기화
CJS DCE / 옵션 갭 메우기"일부만 바꾸면 이득 없다 → 전수로". IIFE 디폴트 제거, 의도 안 된 fallback 제거
styled-components·emotion 트랜스포머Babel 없이 자체 처리, "바벨이 되는데 우리만 안 되면 문제"가 기준선
"프로덕션 레벨 배포에 부족한 것"처음으로 입에 올림. HMR #1747 클로즈. 36일 만에 자기소개가 바뀜
Codex 등판4/26 첫 투입(버그 헌터), 4/29 zts-codex 별도 클론 분리. 두 AI가 같은 이슈/PR 풀 공유

4/30 시점에 진행 중인 에픽

에픽상태
RFC #1672 (oxc 스타일 AST)cosmetic refactor 머지, Phase C/D는 debug infra 위에서 재진행 중
WASM 번들러 #1885RealFS/VirtualFS 머지, 브라우저 playground 동작. 디버깅/ABI 안정화 후속
manualChunks #1027Rollup parity 93%. inlineDynamicImports 머지
config 시스템zts.config.*/.env/--mode 머지, workspace Phase 3 잔여
CJS DCE 에픽defineProperty facts·dead-store 가지치기 머지, 전수 적용 진행 중
styled-components·emotion 트랜스포머정식 스펙 옵션 거의 머지. RN 케이스 일부 미해결
ES5 다운레벨 빈칸async generator/yield*/super lowering 머지. 헤르메스 깊이는 5/7에 재논의
Vite 스타일 app builderCodex 쪽에서 dev/build/preview/HTML/CSS HMR 진행 중
번들 크기 회귀Codex 쪽 전수조사 — "왜 rolldown보다 큰가" (5/3 numeric const folding으로 일부 해소)
에러 UX miette급ZTS0xxx 코드 + 소스 포인터. dev 에러 오버레이는 5/4
require.context Phase 4#1579 — graph dep + tree-shake root 연결 머지

다음 편

3-16은 5/15/7 — esbuild 스타일 tsconfigRaw 통합, binding-lite 트랜스파일 fast path, 메모리 오염 근본 수정(#raw-require / 0xAA slice use-after-free), stack-overflow hardening, RN codegen rn-0.780.84 매트릭스, Flow 파서를 "ts처럼" 만들기, core-js 자동 폴리필, @zntc/* 모노레포 패키지 분리, BoringSSL dev TLS, 번개(bungae) 흡수 + 폐기, 그리고 프로젝트 이름이 zts에서 zntc로 바뀐 날을 담는다.

3/18 ~ 4/07 ████████████████████  3-1 ~ 3-10 (20일 — 기준선 확보)
4/08 ~ 4/10 ████                  3-11 (3일 — RN HMR 재설계)
4/11 ~ 4/14 █████                 3-12 (4일 — 호환성 겹층)
4/15 ~ 4/18 █████                 3-13 (4일 — Metro 경계 확정)
4/19 ~ 4/23 ██████                3-14 (5일 — RFC 시리즈)
4/24 ~ 4/30 ████████              3-15 (7일 — "프로덕션이라는 말")
5/01 ~ 5/07 ████████              3-16 (7일 — binding-lite·패키지 분리·이름 변경)  ← 다음
5/08 ~ 5/12 ██████                3-17 (5일 — 0.1.0을 향해)
5/13 ~        →→→→→→→→→→→→→       계속 진행 중