다크모드
웹 라이브러리 선택 기준
상태: 신규 웹 개발의 기본 기준
적용 대상: Leyve 제품, 운영 도구, 웹 기반 출력·자동화 코드
최종 검토: 2026-07-31
목록에 없는 라이브러리를 필요할 때마다 임의로 추가하지 않습니다. 먼저 웹 플랫폼과 기존 Leysys 패키지로 해결하고, 부족할 때 이 문서의 기본 도구를 사용합니다. 여기에도 맞는 도구가 없으면 비교 근거와 운영 책임을 남긴 뒤 승인받습니다.
이 문서는 패치 버전 목록이 아닙니다. 실제 버전의 정본은 각 저장소의 package.json, lockfile, 패키지 release 절차입니다.
상태의 의미
| 상태 | 의미 |
|---|---|
| 기본 | 같은 용도의 신규 구현에서 우선 사용합니다. |
| 조건부 | 명시된 범위에서만 사용하고, 도입 근거를 PR 또는 ADR에 남깁니다. |
| 레거시 전용 | 기존 코드 유지에는 쓸 수 있지만 신규 도입하지 않습니다. |
| 금지 | 보안·수명·중복 문제로 새 코드에서 사용하지 않습니다. |
공통 도입 규칙
새 의존성을 추가하기 전에 다음 순서로 판단합니다.
- 브라우저·Node.js 표준 API로 충분한지 확인합니다.
@leysys/eds,@leysys/mds,@leysys/print-ds또는 기존 제품 wrapper가 같은 기능을 이미 제공하는지 확인합니다.- 이미 승인된 라이브러리와 용도가 겹치지 않는지 저장소 전체를 검색합니다.
- 공식 문서에 공개된 API만 사용합니다. 내부 경로, undocumented export, 빌드 산출물 직접 참조에 의존하지 않습니다.
- 유지보수 상태, 라이선스, 보안 이력, 번들 크기, SSR·브라우저 호환성, 접근성, 테스트 가능성을 확인합니다.
- 제품 코드가 라이브러리를 곳곳에서 직접 import하지 않도록 한 경계나 wrapper에서 소유합니다. 교체와 보안 검토의 범위를 좁히기 위한 규칙입니다.
- exact version이 필요한 Leysys 패키지와 공급망 예외는 manifest에서 직접 고정합니다. lockfile만으로 계약 버전을 대신하지 않습니다.
단순 편의를 위한 유틸리티 패키지, 같은 기능의 두 번째 UI·날짜·HTTP·상태 관리 라이브러리, 한 함수만 쓰기 위한 큰 패키지는 추가하지 않습니다.
런타임과 애플리케이션
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| Node.js | 기본 | 현재 제품 기준 Node.js 24 LTS | 배포 런타임은 Active LTS 또는 Maintenance LTS만 사용합니다. 저장소의 engines와 .nvmrc가 정확한 버전 정본입니다. |
| 신규 웹 UI | 기본 | Vue 3 + TypeScript + Vite 계열 | 제품이 이미 선택한 빌드 도구와 Vue 3 생태계를 유지합니다. |
| Vue 2·Vue CLI | 레거시 전용 | 기존 코드 유지 | 신규 앱이나 신규 화면의 기반으로 선택하지 않습니다. |
| UI component | 기본 | 해당 제품의 단일 Leysys DS | 제품에서 임의의 UI kit나 primitive library를 직접 섞지 않습니다. 필요한 component는 leysys-design에서 정착한 뒤 소비합니다. |
| 상태 관리 | 기본 | Pinia | 앱 전역 상태가 실제로 필요할 때만 사용합니다. 지역 상태는 Vue 상태로 둡니다. |
| 라우팅 | 기본 | Vue Router | 제품의 기존 major와 route 계약을 따릅니다. |
Node.js의 정확한 patch와 패키지 major는 저장소 단위로 함께 올립니다. 이 문서의 숫자만 보고 일부 의존성이나 개발 환경을 단독 업그레이드하지 않습니다.
날짜와 시간
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| 표시·현지화 | 기본 | Intl.DateTimeFormat, Intl.RelativeTimeFormat | 언어, 시간대, 통화 표시는 브라우저 표준 API를 먼저 사용합니다. |
| 달력·date picker 상태 | 기본 | @internationalized/date | 날짜-only 값, 달력 계산, 시간대가 있는 값의 의미를 분리합니다. Leysys DS와 제품이 공유하는 기준입니다. |
| 일반 날짜 유틸리티 | 조건부 | Day.js | 기존 제품에서 사용 중이거나 표준 API와 승인된 날짜 모델로 해결되지 않는 계산에만 사용합니다. |
| Moment.js | 금지 | 사용하지 않음 | 신규 bundle에 추가하지 않습니다. |
new Date("임의 문자열") 같은 구현 의존 파싱은 피합니다. API의 날짜 형식, 시간대, 날짜-only 여부를 계약으로 정하고 경계에서 변환합니다.
차트와 데이터 표
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| 일반 2D 차트 | 기본 | Chart.js 4 | 막대·선·도넛 등 일반 업무 차트에 사용합니다. 필요한 controller, element, scale, plugin만 import·register하고 화면 단위로 지연 로드합니다. |
| 복잡한 시각화 | 조건부 | 별도 비교 후 결정 | 지도, 수천 개 point, custom interaction처럼 Chart.js 범위를 벗어날 때만 D3·ECharts 등을 검토합니다. |
| 업무 표 | 기본 | Leysys DS의 Table·DataTable·DataGrid 경계 | 제품이 TanStack Table, RevoGrid 같은 기반 라이브러리를 직접 소유하지 않습니다. |
신규 코드에서 편의를 이유로 chart.js/auto를 기본 선택하지 않습니다. 작은 정적 수치를 차트로 만들기 전에 표나 텍스트가 더 명확한지도 확인합니다.
스프레드시트
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| 단순 다운로드 | 기본 | CSV | 서식, 여러 sheet, 수식이 필요하지 않으면 가장 단순하고 검토하기 쉬운 형식을 사용합니다. |
| XLSX 내보내기 | 조건부 | 검증된 SheetJS CE write-only wrapper | 현재 console의 vendored 0.20.3 tarball과 SHA 검증, 동적 import, src/lib/report/xlsxExport.js 경계를 유지합니다. |
| 신뢰할 수 없는 XLSX 읽기 | 조건부 | 별도 보안 설계 후 결정 | upload 크기 제한, parser 격리, 수식·링크·압축 bomb 검토가 필요합니다. write-only 예외를 재사용하지 않습니다. |
npm registry의 xlsx@0.18.5 | 금지 | 사용하지 않음 | 최신판이 아니며 신규 코드의 근거로 삼지 않습니다. |
SheetJS, ExcelJS, 다른 parser를 기능 하나 때문에 함께 설치하지 않습니다. XLSX 입력이 필요해지면 유지보수와 보안 모델을 다시 비교하고 ADR로 승인받습니다.
브라우저 자동화와 PDF
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| E2E·스크린샷·브라우저 렌더링 | 기본 | Playwright | Chromium, Firefox, WebKit 검증을 한 도구에서 관리합니다. 저장소가 제공하는 browser 설치·CI 절차를 따릅니다. |
| HTML 기반 PDF 생성 | 기본 | @leysys/print-ds + HTML + Playwright Chromium | 출력 템플릿은 print DS를 사용하고, PDF 생성은 Chromium 경로로 명시합니다. |
| 서버 HTML template | 조건부 | Nunjucks | Vue runtime이 없는 출력·메일·서버 template에서만 사용합니다. Vue 화면에서는 SFC를 사용합니다. |
| Puppeteer | 레거시 전용 | 기존 Chromium 자동화 유지 | Playwright로 충족할 수 있는 신규 코드에는 추가하지 않습니다. |
| PDF 보기·text 추출 | 조건부 | PDF.js (pdfjs-dist) | PDF 표시와 parsing 용도입니다. 생성, 편집, 전자서명 도구로 사용하지 않습니다. |
Playwright의 PDF API는 Chromium 경로이므로 “세 browser에서 같은 PDF 생성”으로 오해하지 않습니다. 영수증·전표·원장 같은 제품 출력물은 print DS와 대표 fixture로 시각 검증합니다.
서명과 QR
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| 손글씨 canvas 입력 | 조건부 | signature_pad | 단순 이미지 입력에만 사용합니다. 본인확인, 서명자 의사, 위변조 방지를 보장하는 전자서명으로 표현하지 않습니다. |
| QR 생성 | 조건부 | qrcode (node-qrcode) | 서버·브라우저 생성이 실제 요구사항일 때 wrapper에서 사용합니다. |
| QR camera·이미지 스캔 | 조건부 | @zxing/browser | 제품 browser matrix와 camera 권한 UX를 검증한 뒤 사용합니다. |
html5-qrcode, 단독 jsQR | 레거시 전용 | 기존 구현 유지 | 새 scanner의 기본값으로 선택하지 않습니다. |
서명 이미지와 QR payload에 개인정보나 인증정보가 들어가면 저장 기간, 로그 노출, 다운로드 권한을 별도로 검토합니다.
ID, CSS, 빌드 도구
| 용도 | 상태 | 권장 | 기준 |
|---|---|---|---|
| 일반 임의 UUID | 기본 | crypto.randomUUID() | 브라우저·Node.js 표준 API로 충분하면 별도 패키지를 추가하지 않습니다. |
| 짧은 URL-safe ID | 조건부 | Nano ID | 길이·충돌 확률 요구가 UUID와 맞지 않을 때만 사용합니다. 업무 식별자나 서버 ID를 임의 대체하지 않습니다. |
| CSS 후처리 | 기본 | 제품 build pipeline | PostCSS·Autoprefixer는 Vite/Tailwind 등 build tool이 소유합니다. 앱이 같은 도구를 중복 설치하거나 별도 설정하지 않습니다. |
| 색상 | 기본 | Leysys token과 CSS oklch() | 색상 선택기·변환기 package를 runtime 의존성으로 추가하지 않습니다. |
승인되지 않은 라이브러리가 필요한 경우
PR 또는 ADR에 최소한 다음 내용을 남깁니다.
- 해결하려는 사용자·운영 문제와 표준 API 또는 기존 도구로 부족한 이유
- 검토한 대안과 선택하지 않은 이유
- 공식 package·repository, 라이선스, 최근 release와 유지보수 신호
- production bundle·server runtime·browser matrix에 미치는 영향
- 개인정보, 파일 parsing, HTML 실행, 네트워크 통신 등 추가 보안 표면
- import를 소유할 wrapper와 제거·교체 계획
- 테스트와 업데이트 책임자
실험을 위해 설치했다가 쓰지 않는 의존성은 같은 변경에서 제거합니다. 승인 없이 package.json에 남겨 두는 것은 도입으로 간주합니다.
참고 자료
- Node.js release 일정
- Vue 공식 tooling 안내
- Chart.js integration과 tree shaking
- SheetJS Node.js 설치·vendoring 안내
- Playwright browser 지원
- Playwright
page.pdf() - PDF.js 시작 안내
signature_padnode-qrcode- ZXing for JS browser layer
보존 배경
2025-04-04 작성된 삭제 예정 블로그의 “Web Standard” 메모에서 Node.js, Vue, Nunjucks, SheetJS, Chart.js, Day.js, signature_pad, PostCSS, Playwright, Puppeteer, QR, PDF.js, Nano ID, Autoprefixer 후보를 선별했습니다. 현재 제품과 leysys-design의 실제 의존성·운영 경계, 공식 지원 문서를 대조해 기본·조건부·레거시 상태로 다시 판정했으며, 오래된 patch 버전과 중복 설명은 옮기지 않았습니다.