~/swaraj.dev
Back to all posts
April 13, 20261 min read

Lightweight Querying with expo-sqlite and sql-template-strings

Use sql-template-strings to write safe, readable SQLite queries in Expo apps, keeping your offline data layer tiny and type‑friendly.

sqliteexpoofflinereact-native

Insight

When you need a local relational store in an Expo app, expo-sqlite is the go‑to solution, but raw string concatenation quickly becomes a maintenance nightmare. Pairing it with the tiny sql-template-strings library lets you write parameterized queries that are both safe from injection and easy to read. The combination stays under 5 KB gzipped, so you keep bundle size low while gaining a clean, async‑await‑friendly API.

Example

import * as SQLite from 'expo-sqlite';
import sql from 'sql-template-strings';

const db = SQLite.openDatabase('app.db');

export async function getTodos(userId: number) {
  return new Promise((resolve, reject) => {
    db.transaction(tx => {
      tx.executeSql(
        sql`SELECT id, title, completed FROM todos WHERE user_id = ${userId}`,
        [],
        (_, { rows }) => resolve(rows._array),
        (_, err) => { reject(err); return false; }
      );
    });
  });
}

Takeaway

Wrap every SQLite call in a tiny promise and use sql-template-strings for parameters. This gives you compile‑time safety, prevents SQL injection, and keeps your offline layer lightweight—perfect for fast‑iteration Expo projects.