# Show GN: StAX-XML: JavaScript/TypeScript용 고성능 스트리밍 XML 파서

> Clean Markdown view of GeekNews topic #23213. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=23213](https://news.hada.io/topic?id=23213)
- GeekNews Markdown: [https://news.hada.io/topic/23213.md](https://news.hada.io/topic/23213.md)
- Type: show
- Author: [click](https://news.hada.io/@click)
- Published: 2025-09-22T12:49:17+09:00
- Updated: 2025-09-22T12:49:17+09:00
- Original source: [github.com/Clickin](https://github.com/Clickin/stax-xml)
- Points: 11
- Comments: 1

## Summary

**고성능**이 요구되는 **대용량 XML 스트리밍 파싱** 환경에서, Java의 StAX와 유사한 **풀(Pull) 방식**과 **완전 비동기 스트림 지원**을 TypeScript/JavaScript에서 실현한 오픈소스 라이브러리가 등장했습니다. 이 라이브러리는 **10MB 미만의 낮은 메모리 사용량**으로 수백 MB~GB 크기의 XML을 실시간 처리할 수 있으며, 기존의 Rust/Java wasm 바인딩보다 성능-효율 측면에서 우수한 순수 **TypeScript 최적화**를 자랑합니다. **Node.js, Deno, 웹 브라우저 등 범용 런타임 호환성**과, 이벤트 기반 파싱 패턴, 타입 가드 등 **개발자 친화적 기능**도 강력하게 지원합니다. StAX-XML은 기존의 fast-xml-parser 대비 10배 이상 메모리 효율을 보이며, **스트림, 대용량, 비동기 파싱**이 필요한 프론트/백엔드에 새로운 대안을 제시합니다.

## Topic Body

직장이 자바로 된 레거시 서비스+XML 기반으로 통신하는데 레거시 서비스를 백엔드로 두면서 js 기반으로 웹서비스를 새로 만드려다보니 딱 마음에 드는 xml 파서가 없어서 직접 만들어버렸습니다.  
  
StAX 기반 pull 방식으로 xml을 파싱하고 비동기 구현체를 제공해 Stream 기반으로 대용량 xml 파일도 10MB 정도의 메모리만으로 파싱이 가능합니다.  
ecmascript 표준에서 string의 최대 길이는 2^53 - 1이다보니 1GB가 넘는 xml들은 sax 파서를 사용할 수밖에 없었는데 이 라이브러리가 좋은 대안이 될 거라고 생각합니다.  
  
직장에서 자바를 주로 쓰고 node 진영에 라이브러리를 만들어보는 건 처음이다보니 부족한 부분은 제안해주시면 최대한 반영해보겠습니다.  
  
#### 역사  
처음에는 java의 woodstox 라이브러리를 wasm으로 바인딩해서 쓸까 고민했지만  
그때는 아직 wasm에 gc 구현이 없었어서 아직 java를 wasm 컴파일하는건 시기상조라고 생각해서 그만뒀습니다.   
두번째로 rust의 quick-xml을 wasm으로 바인딩해서 시도해봤는데 stream을 wasm으로 넘겨서 처리하는 비용이 너무 커서 기존의 javascript xml 파서랑 성능 차이가 너무 많이 나는 바람에 드롭했습니다.  
최종적으로 순수 typescript로 짜기로 결정하고 여러 AI의 도움도 받아가면서 V8 엔진 타깃으로 여러 최적화도 적용했습니다.   
  
#### 🚀 주요 특징  
  
##### **완전 비동기 스트림 기반 파싱**  
- **대용량 XML 파일** (수백 MB~GB) 메모리 효율적 처리  
- **ReadableStream** 기반으로 메인 스레드 차단 없이 실시간 파싱  
- **pull 방식**으로 필요한 만큼만 데이터 처리  
  
```typescript  
// 970MB 파일도 10MB 미만 메모리로 처리 가능  
const parser = new StaxXmlParser(largeXmlStream);  
for await (const event of parser) {  
  // 스트리밍으로 이벤트 처리  
}  
```  
  
##### **StAX 스타일 이벤트 기반 파싱**  
Java 개발자들에게 친숙한 **풀 파서 패턴**을 제공하여 XML 구조를 세밀하게 제어할 수 있습니다.  
  
```typescript  
import { StaxXmlParser, isStartElement, isCharacters } from 'stax-xml';  
  
for await (const event of parser) {  
  if (isStartElement(event)) {  
    console.log(`요소: ${event.name}`, event.attributes);  
  } else if (isCharacters(event)) {  
    console.log(`텍스트: ${event.value}`);  
  }  
}  
```  
  
#### 🛠️ 4가지 핵심 컴포넌트  
  
##### **1. StaxXmlParser (비동기 파서)**  
- **대용량 파일 전용**: 스트림 기반 메모리 효율적 파싱  
- **실시간 처리**: fetch API와 연동하여 원격 XML 실시간 파싱  
- **TypeScript 타입 가드**: 런타임 타입 안전성 보장  
  
##### **2. StaxXmlParserSync (동기 파서)**  
- **소규모 파일 최적화**: 인메모리 XML 문자열 고속 파싱  
- **웹 API 응답**: 동기식 워크플로우에서 즉시 처리  
  
##### **3. StaxXmlWriter (비동기 라이터)**  
- **스트리밍 생성**: WritableStream에 직접 XML 출력  
- **실시간 응답**: API 서버에서 대용량 XML 응답 생성  
- **메모리 효율적**: 전체 XML을 메모리에 저장하지 않음  
  
##### **4. StaxXmlWriterSync (동기 라이터)**  
- **즉시 생성**: 메모리 내 XML 문자열 빌드  
- **웹 서버 통합**: Express, Hono 등과 완벽 연동  
  
#### 📊 성능 비교 (벤치마크)  
##### 벤치마크 환경  
- **CPU**: 13th Gen Intel(R) Core(TM) i5-13600K (~4.70-4.80 GHz)  
- **Runtime**: Node.js 22.17.0 (x64-win32) with --expose-gc  
- **Tool**: Mitata  
  
**97MB 대용량 파일 파싱:**  
- **stax-xml**: 1.05s, **메모리 8.89MB**  
- fast-xml-parser: 4.41s, 메모리 886.33MB  
- txml: 1.02s, 메모리 897.50MB  
  
#### 🌐 범용 호환성  
  
**웹 표준 API만 사용**하여 모든 JavaScript 런타임에서 동작:  
- Node.js (v18+)  
- Bun, Deno  
- 웹 브라우저  
- Edge Runtime (Vercel, Cloudflare Workers)  
  
#### 📦 설치 및 시작  
  
```bash  
npm install stax-xml  
```  
  
```typescript  
import { StaxXmlParser, XmlEventType } from 'stax-xml';  
  
// XML 문자열에서 스트림 생성  
const stream = new ReadableStream({  
  start(controller) {  
    controller.enqueue(new TextEncoder().encode(xmlContent));  
    controller.close();  
  }  
});  
  
// 비동기 파싱  
const parser = new StaxXmlParser(stream);  
for await (const event of parser) {  
  if (event.type === XmlEventType.START_ELEMENT) {  
    console.log(`요소: ${event.name}`, event.attributes);  
  }  
}  
```  
  
#### 📄 프로젝트 정보  
  
- **GitHub**: [https://github.com/clickin/stax-xml](https://github.com/clickin/stax-xml)  
- **문서**: [https://clickin.github.io/stax-xml](https://clickin.github.io/stax-xml)  
- **NPM**: [https://www.npmjs.com/package/stax-xml](https://www.npmjs.com/package/stax-xml)  
- **라이센스**: MIT  
  
---  
  
**※ 라이센스 관련 참고사항**: 이 라이브러리는 [JSR 173: Streaming API for XML](https://jcp.org/en/jsr/detail?id=173)에서 제안된 StAX의 개념에서 영감을 받았으나, JSR 자체의 라이센스 조건을 명확히 파악할 수 없었습니다. **StAX** 명칭의 라이센스 조항을 아시는 분은 조언을 주시면 감사하겠습니다.

## Comments



### Comment 44163

- Author: honglu
- Created: 2025-09-22T17:55:20+09:00
- Points: 1

문서에서 정성과 성의가 느껴져서 좋았습니당.  
  
잘 읽었어요!
