SQLite를 Rust로 다시 짠다: Turso가 하루 만에 별 774개를 받은 이유
인-프로세스 DB의 귀환, 이번엔 WebAssembly까지 노린다

2026년 6월 21일 기준, tursodatabase/turso는 하루 만에 별 774개를 쓸어담으며 GitHub 트렌딩 상단을 차지했다. 누적 별 2만 개를 넘긴 이 Rust 프로젝트가 오늘 다시 주목받는 배경에는 단순한 바이럴이 아닌, 수렴하는 세 가지 기술 조류가 있다.
이게 뭔가
인-프로세스(in-process) 데이터베이스란 MySQL·PostgreSQL처럼 별도 서버를 띄우는 대신, 앱과 같은 프로세스 안에서 돌아가는 DB다. SQLite가 그 원조—파일 하나, 서버 없음, 설치 불필요. Turso는 그 SQLite의 SQL 문법과 동작을 그대로 유지하면서 내부 엔진을 Rust로 새로 구현한 프로젝트다.
왜 그냥 SQLite를 쓰지 않느냐고? SQLite는 C로 쓰여 있다. Rust 생태계나 WebAssembly 환경에서 C 라이브러리를 끌어오려면 FFI 바인딩이 필요하고 이는 빌드 복잡도·보안 리스크·WASM 호환 문제를 낳는다. Turso는 그 중간 단계를 통째로 제거한다.
왜 지금 뜨는가
세 흐름이 한 지점에서 교차한다.
- SQLite 르네상스: Cloudflare D1, Fly.io, Val.town 등이 SQLite를 프로덕션 핵심 DB로 채택하며 "서버리스 + SQLite" 조합이 빠르게 주류가 됐다. 수요가 폭발한 생태계가 SQLite 대안을 찾고 있다.
- WASM DB 수요: 브라우저 안에서 SQL을 돌리거나 Cloudflare Workers 같은 엣지 런타임에 DB를 번들링하려면 C 기반 SQLite가 아닌 네이티브 WASM 빌드가 필요하다. Turso는 이 틈을 정조준한다.
- Rust 생태계 성숙: 기존 SQLite Rust 바인딩(
rusqlite)은 C FFI를 래핑하는 구조라 WASM 빌드가 까다롭다. Turso는 crates.io에 순수 Rust 크레이트로 배포돼,cargo add turso한 줄로 끝난다.
핵심 기능
- SQLite 호환 SQL: 기존 쿼리·스키마를 그대로 재사용 가능
- 다중 언어 SDK: Rust, JavaScript, Python, Java(Maven Central) 공식 지원
- WebAssembly 빌드 지원: 브라우저·엣지 런타임에서 동작
- 인-프로세스: 외부 서버·네트워크·추가 데몬 없음
- MIT 라이선스: 상업 프로젝트 제약 없음
누구에게 쓸모 있나
| 대상 | 이유 |
|---|---|
| Rust 개발자 | C FFI 없이 순수 Rust로 SQL DB 통합 |
| 프런트엔드 엔지니어 | 브라우저에서 SQLite 수준 SQL 실행 |
| 엣지·서버리스 팀 | Workers·Deno Deploy 등에 DB 번들링 |
| Python·JS 백엔드 | 로컬 SQLite를 메모리 안전 구현으로 교체 |
기존 Turso 클라우드 서비스(libSQL 기반)를 쓰던 팀도 이 인-프로세스 엔진을 로컬 개발 환경에 붙여 일관성을 높일 수 있다.
시작하기
Rust — Cargo.toml에 의존성 추가:
[dependencies]
turso = "0.0.8"
tokio = { version = "1", features = ["full"] }
JavaScript / Node.js:
npm install @tursodatabase/database
Python:
pip install pyturso
사용 예시
예시 1 — Rust: 인메모리 DB 생성 후 CRUD (서버 없이 메모리 안에서 SQLite 문법 그대로 사용)
use turso::Builder;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let db = Builder::new_local(":memory:").build().await?;
let conn = db.connect()?;
conn.execute(
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)",
(),
).await?;
conn.execute("INSERT INTO users (name) VALUES (?1)", ["Alice"]).await?;
let mut rows = conn.query("SELECT id, name FROM users", ()).await?;
while let Some(row) = rows.next().await? {
println!("{:?}", row);
}
Ok(())
}
예시 2 — JavaScript: 파일 기반 DB 연결 (기존 @libsql/client와 유사한 API로 로컬 파일 DB 운용)
import { createClient } from "@tursodatabase/database";
const client = createClient({ url: "file:app.db" });
await client.execute(
"CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY, task TEXT)"
);
await client.execute(
"INSERT INTO todos (task) VALUES (?)",
["Deploy to production"]
);
const result = await client.execute("SELECT * FROM todos");
console.log(result.rows);
예시 3 — Python: 간단한 로컬 DB (표준 sqlite3 모듈과 유사한 인터페이스)
import turso
conn = turso.connect("notes.db")
conn.execute("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT)")
conn.execute("INSERT INTO notes (body) VALUES (?)", ("Hello Turso",))
for row in conn.execute("SELECT * FROM notes"):
print(row)
한계·주의
- 버전 0.x, 프로덕션은 아직 이르다: 현재 초기 개발 단계다. 핵심 경로 투입 전 기능 완성도와 Issue 트래커를 반드시 확인하라.
- SQLite 완전 호환 미보장: FTS5, JSON 함수 등 SQLite 고급 기능 일부는 구현 중이거나 빠져 있을 수 있다. 사용 전 마이그레이션 대상 쿼리를 검증해야 한다.
- 기존 Turso 클라우드와 별개 프로젝트: 같은 회사지만 libSQL 기반 클라우드 서비스와 이 인-프로세스 엔진은 다른 코드베이스다. 혼동 주의.
- 멀티프로세스 공유 불가: 인-프로세스 특성상 여러 프로세스가 동시에 같은 DB 파일을 쓰는 아키텍처엔 맞지 않는다.
SQLite가 단순 로컬 캐시가 아니라 엣지·서버리스·브라우저의 실질적 데이터 레이어가 되어가는 시대, Turso의 Rust-native 재구현은 타이밍이 나쁘지 않다. 다만 0.x 딱지가 떼일 때까지는 사이드 프로젝트·프로토타입에서 검증하며 지켜보는 것이 현명하다.
출처
- tursodatabase/turso — GitHub
- turso on crates.io — crates.io
- @tursodatabase/database on npm — npm
- pyturso on PyPI — PyPI
댓글 0
첫 댓글을 남겨보세요.
