내 AI 디렉터리 스택을 구동하는 다섯 개의 간과된 패키지
출처: Dev.to
프로젝트에서 흥미로운 부분은 항상 AI 모델이나 호스팅 플랫폼만은 아니다. 이번 주에는 package.json 파일에 조용히 자리 잡고 있는 다섯 개 의존성의 소스 코드를 읽는 데 시간을 보냈다. 이들 중 어느 것도 트렌드에 오르지는 않았지만, 모두가 핵심적인 역할을 한다.
내 스택은 Astro 5 SSG + Turso libSQL + GitHub Actions cron + Claude Haiku 4.5이다. 세 개의 사이트: Top AI Tools, Find Games Like, Open Alternative To. 시작한 지 7주가 되었지만 전체 페이지뷰는 아직 400 이하이며, 인프라가 충분히 견고해서 콘텐츠 제작에 집중할 수 있고, 불시의 문제 해결에 매달릴 필요가 없다.
tsx — 빌드 절차 없이 TypeScript
tsx (히로키 오사메) 덕분에 모노레포 안의 모든 ETL 스크립트를 바로 실행한다. tsx src/etl/run.ts 라는 명령은 그대로 동작한다 — tsconfig를 건드릴 필요도, ts-node --esm 플래그도, 별도의 컴파일 단계도 없다. 내부적으로 esbuild를 사용하기 때문에 시작 속도가 빨라 5초 정도의 cron 워밍업도 문제되지 않는다.
레포를 살펴보면서 놀란 점: tsx는 TypeScript 컴파일러 대신 esbuild로 타입을 제거하기 때문에 타입 검사를 하지 않는다. 이것은 의도된 동작이다. CI 단계에서 pnpm typecheck 로 구조적 오류를 잡고 싶지만, 실제 실행 경로에서는 속도가 중요한 ETL 스크립트에 딱 맞는 트레이드오프다. README에서도 이를 명확히 언급하고 있다. 3주 전에 이 점을 읽었더라면, tsx가 전체 타입 검사를 수행한다고 가정했을 일은 없었을 텐데.
Pagefind — 서버 없이 정적 전체 텍스트 검색
Pagefind은 postbuild 단계에서 pagefind --site dist --output-subdir _pagefind 로 실행된다. 빌드된 HTML을 크롤링해 압축된 WASM 인덱스를 만들고, 클라이언트‑사이드 JS는 쿼리마다 필요한 청크만 로드한다. 결과적으로 정적 Vercel 혹은 Cloudflare Pages 배포에서도 추가 인프라 없이 검색이 동작한다.
이번 주에 인덱스 포맷 문서를 살펴보았다. 세그먼트 파일은 zstd 압축된 바이너리 블롭 형태로 저장되며, JS 클라이언트는 쿼리 프리픽스에 따라 이를 지연 로드한다. 2,000 페이지 미만인 세 사이트의 인덱스 전체 용량은 500 KB 이하다. Pagefind UI 컴포넌트는 선택 사항이어서, 나는 이를 일반 “ 로 대체해 JS API를 직접 호출하고 Astro 컴포넌트 안에서 결과 렌더링을 제어했다.
Crawlee — 내장 큐 관리가 포함된 TypeScript 스크래핑
아직 Crawlee를 실제 서비스에 적용하지는 않았지만, itch.io ETL을 만들기 시작한 뒤부터 즐겨 찾기에 올려두었다. 현재는 fetch + 수동 파싱 방식으로 알려진 엔드포인트를 처리하고 있다. Crawlee는 요청 큐 영속성, 레이트 리밋, 그리고 HTML 추출을 위한 cheerio 통합을 제공하며, 모두 TypeScript와 네이티브 ESM 지원으로 구현돼 있다.
전환하지 않은 이유는 내 ETL이 GitHub Actions 안에서