Skip to content

Commit 9a2e4c0

Browse files
committed
docs: update README to clarify performance comparison and library alternatives
1 parent a62c377 commit 9a2e4c0

File tree

1 file changed

+73
-120
lines changed

1 file changed

+73
-120
lines changed

README.md

Lines changed: 73 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -199,35 +199,13 @@ console.log(`User: ${user.name} <${user.email}>`);
199199

200200
## Performance
201201

202-
This package provides the same performance characteristics as Node.js built-in SQLite:
202+
This package provides performance comparable to Node.js's built-in SQLite and better-sqlite3, with:
203203

204204
- **Synchronous operations** - No async/await overhead
205205
- **Direct C library access** - Minimal JavaScript ↔ native boundary crossings
206-
- **Prepared statements** - Optimal query planning and parameter binding
207-
- **SQLite optimizations** - Compiled with performance-focused flags including:
208-
- Full-Text Search (FTS5)
209-
- JSON functions
210-
- R\*Tree indexes
211-
- Math functions
212-
- Session extension
206+
- **Full SQLite features** - FTS5, JSON functions, R\*Tree indexes, math functions, session extension
213207

214-
### Performance Features
215-
216-
- **Batch operations**: Use transactions for bulk inserts/updates
217-
- **Iterator protocol**: Memory-efficient result streaming
218-
- **BigInt support**: Native handling of 64-bit integers
219-
- **Prepared statement caching**: Reuse statements for better performance
220-
- **Backup API**: Non-blocking incremental backups
221-
222-
Benchmark comparison with other SQLite libraries:
223-
224-
| Library | Operations/sec | Notes |
225-
| ---------------------- | -------------- | --------------------------------------- |
226-
| @photostructure/sqlite | ~450,000 | Node.js-compatible API, Node-API stable |
227-
| better-sqlite3 | ~400,000 | Custom API, V8-specific implementation |
228-
| sqlite3 | ~50,000 | Async overhead, callback-based |
229-
230-
_Benchmarks are approximate and vary by use case and system._
208+
Performance is quite similar to node:sqlite and better-sqlite3, while significantly faster than async sqlite3 due to synchronous operations.
231209

232210
## Platform Support
233211

@@ -249,120 +227,95 @@ Prebuilt binaries are provided for all supported platforms. If a prebuilt binary
249227

250228
## Alternatives
251229

252-
When choosing a SQLite library for Node.js, you have several options. Here's how @photostructure/sqlite compares to the main alternatives:
253-
254-
### node:sqlite (Node.js Built-in)
255-
256-
Node.js 22.5.0+ includes an experimental built-in SQLite module.
257-
258-
**Pros:**
259-
260-
-**Zero dependencies**: Built into Node.js, no installation needed
261-
-**Official support**: Maintained by the Node.js core team
262-
-**High performance**: Direct C library integration with minimal overhead
263-
-**Synchronous API**: Simple, blocking operations without callback complexity
264-
-**Complete feature set**: Full SQLite functionality including FTS, JSON functions
265-
266-
**Cons:**
267-
268-
-**Experimental status**: Not recommended for production use
269-
-**Version requirements**: Only available in Node.js 22.5.0+
270-
-**Flag required**: Needs `--experimental-sqlite` flag to use
271-
-**API instability**: May change before becoming stable
272-
-**Limited adoption**: Few real-world deployments and examples
273-
274-
**Best for:** Experimental projects and future-proofing when it becomes stable.
230+
When choosing a SQLite library for Node.js, you have several excellent options. Here's how **`@photostructure/sqlite`** compares to the alternatives:
275231

276-
### better-sqlite3
232+
### 🏷️ [`node:sqlite`](https://nodejs.org/docs/latest/api/sqlite.html) — Node.js Built-in Module
277233

278-
The most popular high-performance SQLite library for Node.js.
234+
*The official SQLite module included with Node.js 22.5.0+ (experimental)*
279235

280-
**Pros:**
236+
**✨ Pros:**
237+
- **Zero dependencies** — Built directly into Node.js
238+
- **Official support** — Maintained by the Node.js core team
239+
- **Clean synchronous API** — Simple, predictable blocking operations
240+
- **Full SQLite power** — FTS5, JSON functions, R*Tree, and more
281241

282-
-**Excellent performance**: 2-15x faster than sqlite3 in most operations
283-
-**Synchronous API**: Simple blocking operations, no callback/Promise complexity
284-
-**Mature and stable**: Battle-tested with thousands of projects using it
285-
-**Rich features**: User-defined functions, aggregates, virtual tables, extensions
286-
-**Great TypeScript support**: Comprehensive type definitions
287-
-**Active maintenance**: Regular updates and excellent documentation
288-
-**Worker thread support**: For handling large/slow queries
242+
**⚠️ Cons:**
243+
- **Experimental status** — Not yet stable for production use
244+
- **Requires Node.js 22.5.0+** — Won't work on older versions
245+
- **Flag required** — Must use `--experimental-sqlite` to enable
246+
- **API may change** — Breaking changes possible before stable release
247+
- **Limited real-world usage** — Few production deployments to learn from
289248

290-
**Cons:**
249+
**🎯 Best for:** Experimental projects, early adopters, and preparing for the future when it becomes stable.
291250

292-
-**Synchronous only**: No async operations (though this is often an advantage)
293-
-**Different API**: Not compatible with Node.js built-in SQLite interface
294-
-**Not suitable for all cases**: High concurrent writes or very large databases
295-
-**Migration effort**: Requires code changes from other SQLite libraries
296-
-**V8 API dependency**: Uses V8-specific APIs, requiring separate prebuilds for each Node.js version
297-
298-
**Best for:** High-performance applications where you control the API design and want maximum speed.
299-
300-
### sqlite3 (node-sqlite3)
301-
302-
The traditional asynchronous SQLite library for Node.js.
303-
304-
**Pros:**
305-
306-
-**Mature and established**: Long history, widely adopted (4000+ dependent packages)
307-
-**Asynchronous API**: Non-blocking operations with callbacks/Promises
308-
-**Extensive ecosystem**: Many tutorials, examples, and community resources
309-
-**Flexible**: Supports both serialized and parallel execution modes
310-
-**Extension support**: SQLite extensions including SQLCipher encryption
311-
-**Node-API compatibility**: Works across Node.js versions without rebuilding
312-
313-
**Cons:**
314-
315-
-**Poor performance**: 2-15x slower than synchronous alternatives
316-
-**Complex API**: Callback-based with potential callback hell
317-
-**Resource waste**: Async overhead for inherently synchronous operations
318-
-**Memory management**: Exposes low-level C memory management concerns
319-
-**Mutex thrashing**: Performance degradation under load
251+
---
320252

321-
**Best for:** Legacy applications, projects requiring async patterns, or when database operations must not block the event loop.
253+
### 🚀 [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) — The Performance Champion
322254

323-
### Performance Comparison
255+
*The most popular high-performance synchronous SQLite library*
324256

325-
Based on benchmarks from better-sqlite3 and our testing:
257+
**✨ Pros:**
258+
- **Blazing fast** — 2-15x faster than async alternatives
259+
- **Rock-solid stability** — Battle-tested in thousands of production apps
260+
- **Rich feature set** — User functions, aggregates, virtual tables, extensions
326261

327-
| Operation | @photostructure/sqlite | better-sqlite3 | sqlite3 |
328-
| ----------------------------- | ---------------------- | ---------------- | --------------- |
329-
| SELECT 1 row | ~450,000 ops/sec | ~400,000 ops/sec | ~50,000 ops/sec |
330-
| SELECT 100 rows | 1x (baseline) | ~1x | ~3x slower |
331-
| INSERT 1 row | 1x (baseline) | ~1x | ~3x slower |
332-
| INSERT 100 rows (transaction) | 1x (baseline) | ~1x | ~15x slower |
262+
**⚠️ Cons:**
263+
- **Different API** — Not compatible with Node.js built-in SQLite
264+
- **V8-specific** — Requires separate builds for each Node.js version
265+
- **Synchronous only** — No async operations (usually a feature, not a bug)
266+
- **Migration effort** — Switching from other libraries requires code changes
333267

334-
### Recommendation Guide
268+
**🎯 Best for:** High-performance applications where you want maximum speed and control over the API.
335269

336-
**Choose @photostructure/sqlite if:**
270+
---
337271

338-
- You want a **drop-in replacement** for `node:sqlite` with zero code changes
339-
- You need Node.js built-in SQLite API compatibility today
340-
- You need to support multiple Node.js versions without experimental flags
341-
- You want the performance of synchronous operations
342-
- You prefer Node-API stability over V8-specific implementations
343-
- You're building for the future when Node.js SQLite becomes stable
344-
- You want to write code that works with both `@photostructure/sqlite` and `node:sqlite`
272+
### 📦 [`sqlite3`](https://github.com/TryGhost/node-sqlite3) — The Async Classic
345273

346-
**Choose better-sqlite3 if:**
274+
*The original asynchronous SQLite binding for Node.js*
347275

348-
- Performance is your top priority
349-
- You're building a new application and control the API design
350-
- You want the most mature synchronous SQLite library
351-
- You prefer their specific API design over Node.js compatibility
276+
**✨ Pros:**
277+
- **Battle-tested legacy** — 10+ years of production use
278+
- **Massive ecosystem** — 4000+ dependent packages
279+
- **Truly asynchronous** — Non-blocking operations won't freeze your app
280+
- **Extensive resources** — Countless tutorials and Stack Overflow answers
281+
- **Extension support** — Works with SQLCipher for encryption
282+
- **Node-API stable** — One build works across Node.js versions
352283

353-
**Choose sqlite3 if:**
284+
**⚠️ Cons:**
285+
- **Significantly slower** — 2-15x performance penalty vs synchronous libs
286+
- **Callback complexity** — Prone to callback hell without careful design
287+
- **Unnecessary overhead** — SQLite is inherently synchronous anyway
288+
- **Memory management quirks** — Exposes low-level C concerns to JavaScript
289+
- **Concurrency issues** — Mutex contention under heavy load
354290

355-
- You have an existing codebase using async SQLite patterns
356-
- You specifically need non-blocking database operations
357-
- You're working with legacy systems that require callback-based APIs
358-
- You need SQLCipher encryption support
291+
**🎯 Best for:** Legacy codebases, apps requiring true async operations, or when you need SQLCipher encryption.
359292

360-
**Choose node:sqlite if:**
293+
---
361294

362-
- You're experimenting with cutting-edge Node.js features
363-
- You don't mind using experimental APIs
364-
- You want zero-dependency SQLite access
365-
- You're building proof-of-concepts for future migration
295+
## 🎯 Quick Decision Guide
296+
297+
### Choose **`@photostructure/sqlite`** when you want:
298+
-**Future-proof code** that works with both this package AND `node:sqlite`
299+
-**Node.js API compatibility** without waiting for stable release
300+
-**Broad Node.js support** (v20+) without experimental flags
301+
-**Synchronous performance** with a clean, official API
302+
-**Node-API stability** — one build works across Node.js versions
303+
-**Zero migration path** when `node:sqlite` becomes stable
304+
305+
### Choose **`better-sqlite3`** when you want:
306+
- ✅ The most mature and feature-rich synchronous SQLite library
307+
- ✅ Maximum performance above all else
308+
- ✅ A specific API design that differs from Node.js
309+
310+
### Choose **`sqlite3`** when you have:
311+
- ✅ Legacy code using async/callback patterns
312+
- ✅ Hard requirement for non-blocking operations
313+
- ✅ Need for SQLCipher encryption
314+
315+
### Choose **`node:sqlite`** when you're:
316+
- ✅ Experimenting with bleeding-edge Node.js features
317+
- ✅ Building proof-of-concepts for future migration
318+
- ✅ Working in environments where you control the Node.js version
366319

367320
## Contributing
368321

0 commit comments

Comments
 (0)