Tutorial Backend Node.js

Building a Real-World API with RepoDB

Suman Malik
January 25, 2026

What We're Building

We are going to build the backend for a simple CRM (Customer Relationship Management) tool. We need to store users, track their status, and log when they were added.

1. Designing the Schema

SQLite is dynamically typed, but RepoDB enforces data integrity. We recommend being strict with your types.

const setupQuery = `
    -- Enable foreign keys just in case we extend later
    PRAGMA foreign_keys = ON;

    CREATE TABLE IF NOT EXISTS customers (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        full_name TEXT NOT NULL,
        email TEXT UNIQUE NOT NULL CHECK(email LIKE '%@%'),
        status TEXT DEFAULT 'lead' CHECK(status IN ('lead', 'customer', 'churned')),
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    );
    
    CREATE INDEX IF NOT EXISTS idx_email ON customers(email);
`;

await db.execute(setupQuery);
console.log("Schema initialized successfully.");

Pro Tip: Creating indexes on columns you search frequently (like email) can speed up your queries by 100x.

2. Secure Data Insertion

The #1 vulnerability in web apps is SQL Injection. RepoDB solves this by supporting parameterized queries out of the box. Never inject strings directly!

async function addCustomer(name, email) {
    const query = `
        INSERT INTO customers (full_name, email) 
        VALUES (?, ?) 
        RETURNING id, created_at
    `;
    
    try {
        // Pass user input as the second argument array
        const result = await db.execute(query, [name, email]);
        return result.rows[0];
    } catch (error) {
        if (error.message.includes('UNIQUE constraint failed')) {
            throw new Error('This email is already registered.');
        }
        throw error;
    }
}

3. Complex Querying & Filtering

Let's find all recent customers. Note how effortless it is to write standard SQL.

const result = await db.execute(`
    SELECT * FROM customers 
    WHERE status = 'customer' 
    ORDER BY created_at DESC 
    LIMIT 20
`);

console.table(result.rows);

With RepoDB, you are writing native SQL. You don't have to learn a proprietary Query Language or a complex ORM syntax. If you know SQL, you know RepoDB.

Ready to try RepoDB?

Get started with your own database in seconds.


Read Next

How to use MySQL Compatibility in RepoDB

A step-by-step guide on how to leverage the new MySQL dialect support in RepoDB....

Deep Dive: Our MySQL Compatibility Layer

A technical look at how we implemented MySQL support on top of a SQLite core, an...

Switching from SQLite to MySQL: Why and How

Already using RepoDB with SQLite? Here is why you might want to switch to the My...