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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-sqlite-table

v0.2.2

Published

**Type-safe SQLite table wrapper for React Native.** Built on top of [`react-native-sqlite-storage`](https://github.com/andpor/react-native-sqlite-storage), this library provides schema management, CRUD utilities, and React Hook support with full TypeS

Readme

react-native-sqlite-table

Type-safe SQLite table wrapper for React Native.
Built on top of react-native-sqlite-storage, this library provides schema management, CRUD utilities, and React Hook support with full TypeScript integration.

✨ Features

  • Type-safe column definitions
    Define interfaces and column specs in one place, ensuring both runtime and compile-time validation.

  • Simple CRUD utilities
    Use insert, update, delete, query, and more with concise APIs.

  • Schema versioning & migration
    Manage table lifecycle automatically using DDLOption, with built-in version tracking and migrations.

  • React Hook support
    useSQLiteTable automatically handles DB open/close and keeps table instances stable across re-renders.

  • Advanced type support
    Built-in handling for BLOB, BOOLEAN, and automatic JSON serialization.

📱 Supported Platforms

| Platform | Support | Notes | |----------|---------|-------| | iOS | ✅ | Fully supported | | Android | ✅ | Fully supported | | Windows | ✅ | Fully supported | | macOS | ✅ | Fully supported |


📦 Installation

npm install react-native-sqlite-table react-native-sqlite-storage
# or
yarn add react-native-sqlite-table react-native-sqlite-storage

Note: react and react-native are peer dependencies and must already be installed.

🚀 Quick Start

1. Define columns & interface

// message.types.ts
export interface Message {
  roomId: string;
  text: string;
  timestamp: number;
  edited?: boolean;
}

export const messageColumns = {
  roomId: 'TEXT',
  text: { type: 'TEXT', nullable: false },
  timestamp: 'INTEGER',
  edited: { type: 'BOOLEAN', default: false },
};

2. Create and use table (class)

import { SQLiteTable } from 'react-native-sqlite-table';
import type { Message } from './message.types';

const table = new SQLiteTable<Message>(
  'MyAppSQLiteDB',        // Database file name
  'messages',             // Table name
  messageColumns,         // Column specs
  { version: 1 },         // (optional) DDL options
  true                    // (optional) Debug mode
);

await table.insert({
  roomId: 'lobby',
  text: 'Hello world!',
  timestamp: Date.now(),
});

const rows = await table.all();
console.log(rows);

3. Use useSQLiteTable Hook

import React from 'react';
import { useSQLiteTable } from 'react-native-sqlite-table';
import { messageColumns, Message } from './message.types';

export function Chat() {
  const table = useSQLiteTable<Message>({
    tableName: 'messages',
    columns: messageColumns,
  });

  const send = async (text: string) => {
    await table.insert({ roomId: 'lobby', text, timestamp: Date.now() });
  };

  // DB connection is automatically closed when the component unmounts
  return <ChatUI onSend={send} />;
}

🗂 Column Spec Format

Each column can be defined as an object or shorthand string ('TEXT', 'INTEGER', etc.).

| Property | Type | Description | |----------|----------------------------------------------|--------------------------------------| | type | 'TEXT' \| 'INTEGER' \| 'BOOLEAN' \| 'BLOB' | SQLite column type (required) | | nullable | boolean | Whether NULL values are allowed | | default | string \| number \| boolean \| object | Default value | | unique | boolean | Create a unique index | | check | string | Add a CHECK(...) constraint |

⚡ Schema & Migration

Use DDLOption for automated schema lifecycle management.

const chatDDL = {
  version: 2,
  beforeCreateNoTxn: [['PRAGMA auto_vacuum=INCREMENTAL']],
  afterCreateTxn: [
    ['CREATE INDEX IF NOT EXISTS idx_chat_room_ts ON messages(room_id, timestamp)']
  ],
  afterCreateNoTxn: [['PRAGMA journal_mode=WAL']],
  onEveryOpen: [['PRAGMA foreign_keys=ON']],
  migrationSteps: [
    {
      to: 2,
      txn: [['ALTER TABLE messages ADD COLUMN edited BOOLEAN DEFAULT 0']],
    }
  ]
};
  • version: Target schema version (positive integer)
  • beforeCreateNoTxn: Commands before table creation (outside transaction)
  • afterCreateTxn: Commands after table creation (inside transaction)
  • afterCreateNoTxn: Commands after table creation (outside transaction)
  • onEveryOpen: Commands on every database open
  • migrationSteps: Define version upgrade steps

📖 API Reference

SQLiteTable<T>

| Method | Description | |---------------------------------|-------------------------------------| | open() / close() | Open or close the database connection | | insert(row) / insertMany(rows) | Insert rows | | update(where, changes) | Update rows matching condition | | delete(where) | Delete rows | | all() | Fetch all rows | | findByKeyValue(obj) | Find by key-value pairs | | query(sql, params?) | Run a custom SELECT query | | queryWithPK(sql, params?) | SELECT query including row_id | | run(sql, params?) | Run a custom non-SELECT query |

useSQLiteTable<T>(options)

React Hook that accepts:

  • dbName
  • tableName
  • columns
  • ddlOption

It automatically opens/closes DB with the component lifecycle.

🧑‍💻 Additional Examples

Update & Delete

// Update a message by rowId
await table.update({ row_id: 1 }, { text: 'Edited text', edited: true });

// Delete all messages in a room
await table.delete({ roomId: 'lobby' });

Query

// Custom SELECT
const results = await table.query(
  'SELECT * FROM messages WHERE roomId = ? ORDER BY timestamp DESC LIMIT ?',
  ['lobby', 50]
);

Hook with Effect

function ChatList() {
  const table = useSQLiteTable<Message>({
    tableName: 'messages',
    columns: messageColumns,
  });

  const [messages, setMessages] = React.useState<Message[]>([]);

  React.useEffect(() => {
    table.all().then(setMessages);
  }, [table]);

  return <MessageList data={messages} />;
}

🔄 Migration Example

const ddl = {
  version: 3,
  migrationSteps: [
    {
      to: 2,
      txn: [
        ['ALTER TABLE messages ADD COLUMN edited BOOLEAN DEFAULT 0']
      ]
    },
    {
      to: 3,
      txn: [
        ['ALTER TABLE messages ADD COLUMN sender TEXT'],
        ['CREATE INDEX IF NOT EXISTS idx_messages_room_sender ON messages(room_id, sender)']
      ]
    }
  ]
};
  • v1 → v2: add edited column
  • v2 → v3: add sender column + index

⚠️ Always test migration with existing data to avoid accidental loss.


🧩 TypeScript First-Class Support

  • Compiler ensures your TypeScript interface is consistent with the defined columns.
  • Insert, update, and select queries are fully type-safe at compile time.
  • Query results are automatically typed as your entity interface.
  • If you don’t pass a generic type, the type is still inferred automatically from the provided column definitions.

📄 License

MIT

🤝 Contributing

Contributions are welcome!
Feel free to open issues or submit PRs for bug reports, feature requests, or improvements.