3 min read

Cloudflare D1: Everything You Need to Know

Table of Contents

I recently worked with Cloudflare and learned quite a lot about Cloudflare Workers and their D1 database offering, which is currently in open beta. D1 is essentially an SQLite database that you can use inside Cloudflare Workers. In this guide, I’ll share everything I learned about working with D1.

What We’ll Cover

  • Creating and connecting databases to Workers
  • Setting up and managing migrations
  • Local development workflow
  • Testing setup and strategies
  • D1 API usage with TypeScript

Getting Started

First, let’s start with the official template provided by Cloudflare. You can create a new project using:

npm create cloudflare@latest

The CLI will ask you several questions:

  • Project name (e.g., “cloudflare-d1-demo”)
  • Template type (choose “Hello World” with TypeScript)

Setting Up D1 Database

To create a new D1 database, use the Wrangler CLI:

wrangler d1 create demo-db

This will create a database and provide a configuration block for your wrangler.toml file:

[[d1_databases]]
Binding = "DB"
database_name = "demo-db"
database_id = "your-database-id"

Working with Migrations

Create a new migration:

wrangler d1 migrations create add-items-table

This generates a new SQL file where you can define your schema:

CREATE TABLE items (
  name TEXT
);

Apply migrations:

# Local development
wrangler d1 migrations apply

# Production
wrangler d1 migrations apply --remote

TypeScript Integration

To get proper TypeScript support, define your environment interface:

interface Env {
  DB: D1Database;
}

type ItemRow = {
  name: string;
};

Working with the D1 API

Here are some common database operations:

// Insert
const inserted = await env.DB
  .prepare('INSERT INTO items (name) VALUES (?)')
  .bind('First Item')
  .run();

// Select
const items = await env.DB
  .prepare('SELECT * FROM items')
  .all<ItemRow>();

// Update
const updated = await env.DB
  .prepare('UPDATE items SET name = ? WHERE name = ?')
  .bind('Updated Name', 'First Item')
  .run();

Testing

For testing, use the @cloudflare/workers-test package and configure your test environment:

import { test } from '@cloudflare/workers-test';

test('database operations', async (t) => {
  const env = getMiniflareBindings();
  
  const result = await env.DB
    .prepare('INSERT INTO items (name) VALUES (?)')
    .bind('Test Item')
    .run();
    
  t.assert(result.success);
});

Conclusion

Cloudflare D1 provides a powerful database solution for Workers with good TypeScript support and testing capabilities. While it’s still in beta, it’s already quite capable for many use cases.

Remember to check the official documentation for the most up-to-date information, as the API may evolve during the beta period.