Runtimes

Deno

Learn how to use Prisma ORM in a Deno application with Prisma Postgres

Introduction

Deno is a secure JavaScript and TypeScript runtime built on V8 with built-in TypeScript support, a permissions system, and web-standard APIs. In this guide, you will set up a Deno project with Prisma ORM and a Prisma Postgres database. You will create a simple HTTP server that reads from the database and returns the results.

Prerequisites

1. Setting up your Deno project

First, create a directory for your project and navigate to it:

mkdir deno-prisma
cd deno-prisma

Then, initialize a new Deno project:

deno init

This creates a basic Deno project with a deno.json configuration file and a main.ts file.

1.1. Configure Deno for Prisma

Update the deno.json file with the following configuration to set up Node.js compatibility, import maps, and Prisma-related task scripts:

deno.json
{
  "nodeModulesDir": "auto",
  "compilerOptions": {
    "lib": ["deno.window"],
    "types": ["node"]
  },
  "imports": {
    "@prisma/adapter-pg": "npm:@prisma/adapter-pg@^7.0.0",
    "@prisma/client": "npm:@prisma/client@^7.0.0",
    "prisma": "npm:prisma@^7.0.0"
  },
  "tasks": {
    "dev": "deno run -A --env=.env --watch main.ts",
    "db:generate": "deno run -A --env=.env npm:prisma generate",
    "db:push": "deno run -A --env=.env npm:prisma db push",
    "db:migrate": "deno run -A --env=.env npm:prisma migrate dev",
    "db:seed": "deno run -A --env=.env npm:prisma db seed"
  }
}

2. Installing and configuring Prisma

2.1. Initialize Prisma ORM with Prisma Postgres

Initialize Prisma ORM with Prisma Postgres in your project:

deno run -A npm:prisma init

This command creates:

  • A prisma/ directory with your schema.prisma file
  • A prisma.config.ts file
  • A .env file with your DATABASE_URL

2.2. Update the Prisma config file

Open the generated prisma.config.ts file. Since Deno loads environment variables using the --env=.env flag (configured in deno.json tasks), you can remove the dotenv/config import if it was generated:

prisma.config.ts
import "dotenv/config"; 
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});

2.3. Create a Prisma Postgres database

Create a Prisma Postgres database and replace the generated DATABASE_URL in your .env file with the postgres://... connection string from the CLI output:

npx create-db

Update your .env file:

.env
DATABASE_URL="postgres://..."

2.4. Update your Prisma schema

Open prisma/schema.prisma and update it to include the Deno runtime and your data model:

prisma/schema.prisma
generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
  runtime  = "deno"
}

datasource db {
  provider = "postgresql"
}

model User { 
  id    Int     @id @default(autoincrement()) 
  email String  @unique
  name  String?
} 

3. Generate Prisma Client and run migrations

Generate the Prisma Client and apply your schema to the database:

deno task db:migrate --name init
deno task db:generate

This command:

  • Creates the database tables based on your schema
  • Generates the Prisma Client in the generated/prisma directory

4. Setting up database configuration and creating a seed script

4.1. Create a database utility file

Create a db.ts file in your project root to configure PrismaClient:

db.ts
import { PrismaClient } from "./generated/prisma/client.ts";
import { PrismaPg } from "@prisma/adapter-pg";

const adapter = new PrismaPg({
  connectionString: Deno.env.get("DATABASE_URL")!,
});

export const prisma = new PrismaClient({
  adapter,
});

4.2. Create a seed script

Create a seed script in the prisma folder to populate your database with sample data:

prisma/seed.ts
import { PrismaClient } from "../generated/prisma/client.ts";
import { PrismaPg } from "@prisma/adapter-pg";

const adapter = new PrismaPg({
  connectionString: Deno.env.get("DATABASE_URL")!,
});

const prisma = new PrismaClient({
  adapter,
});

async function main() {
  // Create multiple users
  await prisma.user.createMany({
    data: [
      { email: "alice@example.com", name: "Alice" },
      { email: "bob@example.com", name: "Bob" },
      { email: "charlie@example.com", name: "Charlie" },
      { email: "diana@example.com", name: "Diana" },
      { email: "eve@example.com", name: "Eve" },
      { email: "frank@example.com", name: "Frank" },
      { email: "grace@example.com", name: "Grace" },
      { email: "henry@example.com", name: "Henry" },
      { email: "isabella@example.com", name: "Isabella" },
      { email: "jack@example.com", name: "Jack" },
    ],
    skipDuplicates: true, // prevents errors if you run the seed multiple times
  });

  console.log("Seed data inserted!");
}

main()
  .catch((e) => {
    console.error(e);
    Deno.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });

4.3. Add the seed script to Prisma Config

Update the prisma.config.ts file to include the seed command:

prisma.config.ts
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
    seed: "deno run -A --env=.env ./prisma/seed.ts", 
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});

Run the seed script to populate your database:

deno task db:seed

5. Creating your Deno server

Replace the main.ts file contents with the following code to build a simple HTTP server that uses Prisma ORM to fetch and display users:

main.ts
import { prisma } from "./db.ts";

async function handler(req: Request): Promise<Response> {
  const { pathname } = new URL(req.url);

  // Skip favicon route
  if (pathname === "/favicon.ico") {
    return new Response(null, { status: 204 });
  }

  // Return all users
  const users = await prisma.user.findMany();

  // Count all users
  const count = await prisma.user.count();

  // Format the response with JSON
  return new Response(
    JSON.stringify({
      users: users,
      totalUsers: count,
    }),
    { headers: { "Content-Type": "application/json" } },
  );
}

Deno.serve({ port: 8000 }, handler);

6. Running your application

Start your Deno server:

deno task dev

You should see the server running on http://localhost:8000 in the console. When you visit http://localhost:8000 in your browser, you'll see a JSON response with all the users in your database and the total count.

Next steps

Now that you have a Deno application connected to a Prisma Postgres database, you can continue by:

  • Extending your Prisma schema with additional models and relationships
  • Implementing authentication and authorization
  • Adding input validation with Zod
  • Exploring Deno's built-in testing tools
  • Deploying your application to Deno Deploy

More info

On this page