Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.
If you’ve ever needed a lightweight and super-fast database for a Node.js project, chances are you’ve looked at SQLite.It’s self-contained, serverless, and simple to use — perfect for apps, tools, and local data storage.
But when it comes to using SQLite with Node.js, not all libraries are created equal.
That’s where Better-SQLite3 comes in.
What is Better-SQLite3?
Better-SQLite3 is a Node.js library that provides a fast, safe, and simple way to work with SQLite databases.
Unlike other SQLite bindings such as node-sqlite3, it offers a fully synchronous API — and yet it still manages to outperform most async wrappers.
It’s designed for developers who want performance and simplicity, especially when dealing with local data or small to medium datasets.
Installation
npm install better-sqlite3
Requirements: Node.js v14.21.1 or later (LTS recommended).
If installation fails, check the library’s troubleshooting guide — prebuilt binaries are available for common environments.
Basic Usage
const Database = require('better-sqlite3');
const db = new Database('foobar.db');
// Enable WAL mode for performance
db.pragma('journal_mode = WAL');
// Query example
const row = db.prepare('SELECT * FROM users WHERE id = ?').get(1);
console.log(row.firstName, row.lastName, row.email);
Or using ES Modules:
import Database from 'better-sqlite3';
const db = new Database('foobar.db');
db.pragma('journal_mode = WAL');
Why Better-SQLite3 Is Different
1. Sync but faster than async
node-sqlite3 uses asynchronous APIs for serialized operations — which actually hurts performance.
better-sqlite3 executes everything synchronously, avoiding event loop complexity and improving concurrency.
2. Memory management done the JavaScript way
Instead of exposing raw C-level memory operations, it relies on Node’s garbage collector.
3. Cleaner API and utilities
Tasks that are complex or impossible in node-sqlite3 are straightforward here — transactions, backups, and custom functions are first-class citizens.
4. Performance
Benchmarks show it outperforms node-sqlite3 in almost all cases, and matches it in the rest.
When Not to Use It
SQLite — and therefore Better-SQLite3 — has limits. You might not want to use it if:
- You have many concurrent writes (e.g., a social media platform).
- You’re serving large read data (e.g., video streams).
- Your database is approaching terabyte size.
In these cases, a full-scale RDBMS like PostgreSQL or MySQL is a better choice.
The Database Class
Creating a new database connection:
const db = new Database('foobar.db', {
readonly: false,
fileMustExist: false,
timeout: 5000,
verbose: console.log
});
- readonly — open DB in read-only mode.
- fileMustExist — throw an error if the DB file doesn’t exist.
- timeout — how long to wait on a locked DB (default: 5 seconds).
- verbose — log every SQL query executed.
To create an in-memory database:
const db = new Database(':memory:');
Transactions Made Easy
Transactions wrap multiple queries into a single atomic operation:
const insert = db.prepare('INSERT INTO cats (name, age) VALUES (?, ?)');
const insertMany = db.transaction((cats) => {
for (const cat of cats) insert.run(cat.name, cat.age);
});
insertMany([
{ name: 'Joey', age: 2 },
{ name: 'Sally', age: 4 }
]);
Transactions can also be nested and come with different modes:
insertMany.deferred(cats);
insertMany.immediate(cats);
insertMany.exclusive(cats);
If an inner transaction fails, it automatically rolls back to its previous savepoint.
Other Useful APIs
-
db.prepare(sql)→ returns aStatementfor repeated execution. -
db.transaction(fn)→ runs a function inside a transaction. -
db.backup(path)→ backs up the database file. -
db.serialize()/db.deserialize()→ convert the database to/from a buffer. -
db.function()/db.aggregate()→ define custom SQL functions. -
db.loadExtension()→ load SQLite C extensions. -
db.close()→ safely close the database.
Final Thoughts
Better-SQLite3 is ideal when you want:
- A local, fast, and reliable database for your Node.js app.
- Synchronous access without async complexity.
- High-performance data handling for tools, scripts, or embedded systems.
It’s not meant to replace enterprise databases — but for most small to medium projects, it’s a perfect balance of speed, simplicity, and control.
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*
Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.
⭐ Star it on GitHub:
HexmosTech
/
git-lrc
Free, Unlimited AI Code Reviews That Run on Commit
AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.
See It In Action
See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements
git-lrc-intro-60s.mp4
Why
- 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
- 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
- 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
- 🔗 Why git? Git is universal. Every editor, every IDE, every AI…
Top comments (2)
Great Explanation.
Thanks