0
0
RemixHow-ToBeginner ยท 4 min read

How to Use Drizzle with Remix: Setup and Example

To use drizzle-orm with Remix, install Drizzle packages, set up your database connection in a Remix loader or action, and use Drizzle's query builder to interact with your database. You then export functions to run queries server-side and call them in Remix loaders or actions for data fetching and mutations.
๐Ÿ“

Syntax

Here is the basic syntax to set up Drizzle ORM with Remix:

  • Import Drizzle and your database client (e.g., pg for PostgreSQL).
  • Create a database connection using the client.
  • Initialize Drizzle with the connection.
  • Define your tables and queries using Drizzle's schema and query builder.
  • Use Remix loaders or actions to call your Drizzle query functions server-side.
typescript
import { createClient } from '@libsql/client';
import { drizzle } from 'drizzle-orm/libsql';

// Create a database client
const client = createClient({ url: 'your-database-url' });

// Initialize Drizzle ORM
const db = drizzle(client);

// Define a query function
export async function getUsers() {
  return await db.select().from('users');
}

// In Remix loader
export async function loader() {
  const users = await getUsers();
  return { users };
}
๐Ÿ’ป

Example

This example shows a simple Remix loader fetching users from a SQLite database using Drizzle ORM. It demonstrates setting up the database, defining a table, and querying data in a loader.

typescript
import { json } from '@remix-run/node';
import { drizzle } from 'drizzle-orm/sqlite3';
import sqlite3 from 'sqlite3';
import { eq } from 'drizzle-orm';
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { useLoaderData } from '@remix-run/react';

// Define users table schema
const users = sqliteTable('users', {
  id: integer('id').primaryKey().autoincrement(),
  name: text('name'),
});

// Open SQLite database
const db = drizzle(new sqlite3.Database('./mydb.sqlite'));

// Loader to fetch all users
export async function loader() {
  const allUsers = await db.select().from(users);
  return json({ users: allUsers });
}

// React component to display users
export default function Users() {
  const { users } = useLoaderData();
  return (
    <main>
      <h1>User List</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </main>
  );
}
Output
<main> <h1>User List</h1> <ul> <li>Alice</li> <li>Bob</li> </ul> </main>
โš ๏ธ

Common Pitfalls

Common mistakes when using Drizzle with Remix include:

  • Trying to use Drizzle client-side instead of only server-side in loaders or actions.
  • Not properly initializing the database connection before queries.
  • Forgetting to await async database calls, causing unresolved promises.
  • Mixing Drizzle schema definitions with incompatible database clients.

Always keep Drizzle usage server-only and ensure your database client matches your database type.

typescript
/* Wrong: Using Drizzle client in React component (client-side) */
import { drizzle } from 'drizzle-orm';
const db = drizzle(client);

function Users() {
  const users = db.select().from('users'); // โŒ This is async and server-only
  return <div>{users.length}</div>;
}

/* Right: Use Drizzle in loader and pass data to component */
export async function loader() {
  const users = await db.select().from('users');
  return { users };
}

function Users() {
  const { users } = useLoaderData();
  return <div>{users.length}</div>;
}
๐Ÿ“Š

Quick Reference

Tips for using Drizzle with Remix:

  • Always initialize Drizzle with a server-side database client.
  • Use Remix loaders and actions to run Drizzle queries asynchronously.
  • Define your database schema with Drizzle's schema helpers for type safety.
  • Pass data from loaders to React components via useLoaderData().
  • Handle errors in loaders/actions to avoid crashes.
โœ…

Key Takeaways

Use Drizzle ORM only in Remix loaders or actions to keep database logic server-side.
Initialize Drizzle with the correct database client matching your database type.
Define your tables with Drizzle schema helpers for clear and type-safe queries.
Always await Drizzle async calls and pass data to components via useLoaderData.
Avoid using Drizzle directly in React components to prevent runtime errors.