Notr Logo

Best Practices

Conventions for predictable, production-ready apps using Drizzleasy.

Architecture

  • Prefer server actions for mutations; read on the server for SSR/SSG
  • Avoid creating separate REST routes when you can call server actions directly
  • Do not access the database on the client

Coding style (TypeScript + Next.js)

  • Prefer pure functions and immutable data for predictability
  • Type everything (entities, inputs, results)
  • Consider named exports (common in libraries); Next.js pages/views can be default exports
  • Keep complex UI state in reducers; keep reducers pure
  • Organize server actions close to the domain they modify

Server actions

'use server'
import { createFn, updateFn, readFn, destroyFn } from '@remcostoeten/drizzleasy'

type TUser = { id: string; email: string; name: string; status: 'active' | 'inactive' }

export async function createUser(data: { email: string; name: string }) {
  const create = createFn<TUser>()
  return create('users')({ id: crypto.randomUUID(), email: data.email, name: data.name, status: 'active' })
}

export async function getUsers() {
  const read = readFn<TUser>()
  return read('users')()
}

Error handling

  • Use the provided DrizzleasyError classes for consistent error surfaces
  • Wrap async work with handleAsyncError and log with logError

Performance

  • Wrap critical operations with measurePerformance
  • Index columns used in WHERE conditions
  • Reuse connections; initializeConnection caches connections

Environment

  • Validate env with validateDatabaseEnvironment
  • Provide TURSO_AUTH_TOKEN for libsql
  • Use environment switching config for development vs production