apps/docs/content/docs.v6/orm/prisma-client/deployment/edge/deploy-to-deno-deploy.mdx
With this guide, you can learn how to build and deploy a simple application to Deno Deploy. The application uses Prisma ORM to save a log of each request to a Prisma Postgres database.
This guide covers the use of Prisma CLI with Deno CLI, Deno Deploy, Prisma Client, and Prisma Postgres.
:::tip[Use Prisma ORM without Rust binaries]
If Prisma ORM's Rust engine binaries cause large bundle sizes, slow builds, or deployment issues (for example, in serverless or edge environments), you can use it without them using this configuration of your generator block:
generator client {
provider = "prisma-client-js" // or "prisma-client"
engineType = "client"
}
Prisma ORM without Rust binaries has been Generally Available since v6.16.0.
Note that you need to use a driver adapter in this case.
When using this architecture:
@prisma/adapter-pg for PostgreSQL).This setup can simplify deployments in serverless or edge runtimes. Learn more in the docs here.
Curious why we moved away from the Rust engine? Take a look at why we transitioned from Rust binary engines to an all-TypeScript approach for a faster, lighter Prisma ORM in this blog post.
:::
To start, you create a directory for your project, and then use deno run to initialize your application with prisma init as an npm package with npm specifiers.
To set up your application, open your terminal and navigate to a location of your choice. Then, run the following commands to set up your application:
mkdir prisma-deno-deploy
cd prisma-deno-deploy
npx prisma@latest init --db
Enter a name for your project and choose a database region.
This command:
prisma directory containing a schema.prisma file for your database models..env file with your DATABASE_URL (e.g., DATABASE_URL="postgresql://user:password@host:5432/database").Edit the prisma/schema.prisma file to define a Log model, add a custom output path and the prisma-client generator with deno as the runtime:
generator client {
provider = "prisma-client-js" // [!code --]
provider = "prisma-client" // [!code ++]
output = "../generated/prisma" // [!code ++]
runtime = "deno" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model Log { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
level Level // [!code ++]
message String // [!code ++]
meta Json // [!code ++]
} // [!code ++]
enum Level { // [!code ++]
Info // [!code ++]
Warn // [!code ++]
Error // [!code ++]
} // [!code ++]
Then, install Prisma Client and the Postgres adapter:
deno install npm:@prisma/client
deno install npm:@prisma/adapter-pg
Prisma Client does not read .env files by default on Deno, so you must also install dotenv-cli locally:
deno install npm:dotenv-cli
With the data model in place and your database connection configured, you can now apply the data model to your database.
deno run -A npm:prisma migrate dev --name init
The command does two things:
At this point, the command has an additional side effects. The command installs Prisma Client and creates the package.json file for the project.
You can now create a local Deno application. Create index.ts in the root folder of your project and add the content below:
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { PrismaPg } from "npm:@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client.ts";
const connectionString = `${Deno.env.get("DATABASE_URL")}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
async function handler(request: Request) {
// Ignore /favicon.ico requests:
const url = new URL(request.url);
if (url.pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
const log = await prisma.log.create({
data: {
level: "Info",
message: `${request.method} ${request.url}`,
meta: {
headers: JSON.stringify(request.headers),
},
},
});
const body = JSON.stringify(log, null, 2);
return new Response(body, {
headers: { "content-type": "application/json; charset=utf-8" },
});
}
serve(handler);
:::info
VS Code error: An import path cannot end with a '.ts' extension
If you use VS Code and see the error An import path cannot end with a '.ts' extension for the import statements at the beginning of index.ts, you need to install the Deno extension for VS Code, select View > Command Palette and run the command Deno: Initialize Workspace Configuration. This tells VS Code that the TypeScript files in the current project need to run with Deno, which then triggers the correct validations.
:::
You can now start your application locally and test the creation of log entries.
npx dotenv -- deno run -A ./index.ts
In a web browser, open http://localhost:8000/. This page writes your request to the database.
{
"id": 1,
"level": "Info",
"message": "GET http://localhost:8000/",
"meta": {
"headers": "{}"
}
}
Reload the page a few times.
Every time you reload, the script generates a new log entry and the id of the current log entry increments.
This confirms that your application works when you run it from your local environment.
You need a GitHub repository to add your project to Deno Deploy and enable automated deployments whenever you push changes.
To set up a GitHub repository:
Initialize your repository locally and push your changes to GitHub, with the following commands:
git init -b main
git remote add origin https://github.com/<username>/prisma-deno-deploy
git add .
git commit -m "initial commit"
git push -u origin main
Use the GitHub repository to add your application to Deno Deploy:
deno run -A npm:prisma generate to generate the Prisma Client.index.ts as the entry point to your project.Create & Deploy.The deployment should fail as you have to add the DATABASE_URL environment variable.
Locate and navigate to the settings for the project.
DATABASE_URL.You have to add some code and create another commit to trigger a re-dployment.
Add the following code in your index.ts file:
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { PrismaPg } from "npm:@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client.ts";
const connectionString = `${Deno.env.get("DATABASE_URL")}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
async function handler(request: Request) {
// Ignore /favicon.ico requests:
const url = new URL(request.url);
if (url.pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
console.log("Request received."); // [!code ++]
const log = await prisma.log.create({
data: {
level: "Info",
message: `${request.method} ${request.url}`,
meta: {
headers: JSON.stringify(request.headers),
},
},
});
const body = JSON.stringify(log, null, 2);
return new Response(body, {
headers: { "content-type": "application/json; charset=utf-8" },
});
}
serve(handler);
Commit the new changes:
git add .
git commit -m "add log"
git push origin main
This rebuilds the deployment, which now works because the environment variable has been added. After it completes, follow the URL in the deployment output. The application should show the same result as before, with a new, incremented log record ID:
{
"id": 5,
"level": "Info",
"message": "GET https://prisma-deno-deploy.deno.dev/",
"meta": {
"headers": "{}"
}
}
You successfully deployed a Deno application that you created in TypeScript, which uses Prisma Client with the Postgres adapter to connect to a Postgres database.