WASM: SQLite WASM
개요
- SQLite를 WebAssembly로 컴파일해 브라우저 / Node.js / Deno / Bun 등 JavaScript 런타임에서 직접 실행
- 공식 SQLite 프로젝트가 유지·배포 (
sqlite-wasm/@sqlite.org/sqlite-wasm) - 서버 없이 클라이언트 쪽에서 풀-SQL 데이터베이스 사용 가능
- 공식 문서 / npm
특징
- 표준 SQLite: 동일 SQL 문법·기능, 단일 파일 DB
- 다중 백엔드: 메모리 / IndexedDB(
kvvfs) / OPFS (Origin Private File System) — OPFS가 가장 빠르고 권장 - 동기 API (OPFS SAH): Web Worker + OPFS Sync Access Handle로 동기 I/O 지원 → 트랜잭션 성능 향상
- 작은 크기: 약 1MB 미만의 .wasm 바이너리(빌드 옵션에 따라)
- Worker 모드: 메인 스레드 차단 없이 DB 작업
백엔드(VFS) 비교
| 백엔드 | 영속성 | 성능 | 크기 한계 | 비고 |
|---|---|---|---|---|
Memory (:memory:) |
없음 | 최고 | RAM | 임시 분석·테스트용 |
kvvfs (localStorage) |
있음 | 낮음 | ~5MB | 작은 DB, 동기 |
kvvfs (sessionStorage) |
세션 | 낮음 | ~5MB | 세션 한정 |
| OPFS | 있음 | 높음 | 수 GB+ | Worker 필요, 권장 백엔드 |
| OPFS SAH Pool | 있음 | 최고 | 수 GB+ | 동기 I/O, 가장 빠름 |
설치 및 기본 사용
-
설치
npm install @sqlite.org/sqlite-wasm -
메인 스레드 (간단한 사용)
import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; const sqlite3 = await sqlite3InitModule(); const db = new sqlite3.oo1.DB(':memory:'); db.exec(` CREATE TABLE t(id INTEGER PRIMARY KEY, name TEXT); INSERT INTO t(name) VALUES ('hello'), ('world'); `); const rows = db.exec({ sql: 'SELECT * FROM t', rowMode: 'object', returnValue: 'resultRows', }); console.log(rows);
OPFS (영속 저장)
- HTTPS 또는 localhost 컨텍스트, COOP/COEP 헤더 권장
-
Web Worker 안에서 사용
// worker.js import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; const sqlite3 = await sqlite3InitModule(); const db = new sqlite3.oo1.OpfsDb('/mydata.sqlite3'); db.exec("CREATE TABLE IF NOT EXISTS log(t TEXT, msg TEXT)"); db.exec({ sql: 'INSERT INTO log VALUES (?, ?)', bind: [new Date().toISOString(), 'hello opfs'], });
필요한 HTTP 헤더 (OPFS SAH)
-
동기 OPFS API는 cross-origin isolation 필요
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
Worker + Promiser API
-
메인 스레드에서 Worker의 SQLite를 Promise 기반으로 호출
import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm'; const promiser = await new Promise((resolve) => { const p = sqlite3Worker1Promiser({ onready: () => resolve(p), }); }); await promiser('open', { filename: 'file:demo?vfs=opfs' }); await promiser('exec', { sql: 'SELECT 1' });
활용 사례
- 오프라인 우선(Offline-first) 웹 앱
- 로컬 노트·메모·할 일 앱 (Logseq, Excalidraw 등 패턴)
- 브라우저 내 분석·BI 대시보드 (DuckDB-WASM과 함께)
- Electron / Tauri 등 데스크톱 웹뷰 앱의 임베디드 DB
- PWA의 영속 저장 (IndexedDB 대안)
한계
- IndexedDB·LocalStorage 대비 도구 생태계 작음
- OPFS는 origin 단위 저장 — 다른 origin과 공유 불가
- 동기 OPFS SAH는 Worker + COOP/COEP 필요
- 모바일 사파리 등 일부 환경에서 OPFS 동작 차이 존재