npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

sqlocal

v0.16.0

Published

SQLocal makes it easy to run SQLite3 in the browser, backed by the origin private file system.

Downloads

23,042

Readme

SQLocal

SQLocal makes it easy to run SQLite3 in the browser, backed by the origin private file system. It wraps the WebAssembly build of SQLite3 and gives you a simple interface to interact with databases running on device.

Documentation - GitHub - NPM - Fund

Features

  • 🔎 Locally executes any query that SQLite3 supports
  • 🧵 Runs the SQLite engine in a web worker so queries do not block the main thread
  • 📂 Persists data to the origin private file system, which is optimized for fast file I/O
  • 🚀 Simple API; just name your database and start running SQL queries
  • ⚡️ Subscribe to query results and receive changes, even across tabs
  • 🔒 Each user can have their own private database instance
  • 🛠️ Works with Kysely and Drizzle ORM for making type-safe queries
  • 🤝 Get set up quickly with hooks for UI frameworks and a Vite plugin

Examples

import { SQLocal } from 'sqlocal';

// Create a client with a name for the SQLite file to save in
// the origin private file system
const { sql } = new SQLocal('database.sqlite3');

// Use the "sql" tagged template to execute a SQL statement
// against the SQLite database
await sql`CREATE TABLE groceries (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)`;

// Execute a parameterized statement just by inserting 
// parameters in the SQL string
const items = ['bread', 'milk', 'rice'];
for (let item of items) {
  await sql`INSERT INTO groceries (name) VALUES (${item})`;
}

// SELECT queries and queries with the RETURNING clause will
// return the matched records as an array of objects
const data = await sql`SELECT * FROM groceries`;
console.log(data);

Log:

[
  { id: 1, name: 'bread' },
  { id: 2, name: 'milk' },
  { id: 3, name: 'rice' }
]

Or, you can use SQLocal as a driver for Kysely or Drizzle ORM to make fully-typed queries.

Kysely

import { SQLocalKysely } from 'sqlocal/kysely';
import { Kysely, Generated } from 'kysely';

// Initialize SQLocalKysely and pass the dialect to Kysely
const { dialect } = new SQLocalKysely('database.sqlite3');
const db = new Kysely<DB>({ dialect });

// Define your schema 
// (passed to the Kysely generic above)
type DB = {
  groceries: {
    id: Generated<number>;
    name: string;
  };
};

// Make type-safe queries
const data = await db
  .selectFrom('groceries')
  .select('name')
  .orderBy('name', 'asc')
  .execute();
console.log(data);

See the Kysely documentation for getting started.

Drizzle

import { SQLocalDrizzle } from 'sqlocal/drizzle';
import { drizzle } from 'drizzle-orm/sqlite-proxy';
import { sqliteTable, int, text } from 'drizzle-orm/sqlite-core';

// Initialize SQLocalDrizzle and pass the driver to Drizzle
const { driver } = new SQLocalDrizzle('database.sqlite3');
const db = drizzle(driver);

// Define your schema
const groceries = sqliteTable('groceries', {
  id: int('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
});

// Make type-safe queries
const data = await db
  .select({ name: groceries.name })
  .from(groceries)
  .orderBy(groceries.name)
  .all();
console.log(data);

See the Drizzle ORM documentation for declaring your schema and making queries.

Install

Install the SQLocal package in your application using your package manager.

npm install sqlocal
# or...
yarn add sqlocal
# or...
pnpm install sqlocal

Cross-Origin Isolation

In order to persist data to the origin private file system, this package relies on APIs that require cross-origin isolation, so the page you use this package on must be served with the following HTTP headers. Otherwise, the browser will block access to the origin private file system.

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

How this is configured will depend on what web server or hosting service your application uses. If your development server uses Vite, see the configuration below.

Vite Configuration

Vite needs some additional configuration to handle web worker files correctly. If you or your framework uses Vite as your build tool, you can use SQLocal's Vite plugin to set this up.

The plugin will also enable cross-origin isolation (required for origin private file system persistence) for the Vite development server by default. Just don't forget to also configure your production web server to use the same HTTP headers.

Import the plugin from sqlocal/vite and add it to your Vite configuration.

import { defineConfig } from 'vite';
import sqlocal from 'sqlocal/vite';

export default defineConfig({
  plugins: [sqlocal()],
});