Is Deno Ready for Primetime?

Theory

Recently I've been working on a TypeScript command-line interface (CLI) tool which is relatively straightforward: it runs a headless browser, parses some on-page data, and then stores the result in a database.

Initially I wrote this in Node and JavaScript but when I began using Prisma for database management, I decided to migrate to TypeScript. Deno, which is an alternative to Node, seemed attractive given its builtin TypeScript support and overall simplicity; perfect for a CLI application.

One of the features of Deno is that it advertises compatibility with the Node ecosystem, including NPM packages. In other words, Node things should just work with your Deno applications.

Reality

Prisma immediately proved to be an exception to the promise of Node and NPM compatibility.

First it's worth noting there's an open issue, dating back to 2020, on the Prisma project asking about Deno support.1 In short: it's complicated.

Since then, a workaround has emerged. This involves an import hack, which apart from being a bit messy, is also broken, as we'll see in a moment.

For example, here's how we might set up our Prisma client such that Deno can use it:

// prisma/schema.prisma

generator client {
    provider        = "prisma-client-js"
    previewFeatures = ["deno"]
    output          = "./generated/client"
}
// src/main.ts

import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);

cconst { PrismaClient } = require("../prisma/generated/client");
const prisma = new PrismaClient();

Not Quite There

However there's a problem with this: Types aren't properly inferred.2 To get around this, we can import them directly:

// src/main.ts

import { PrismaClient as PrismaClientType } from "./generated/client/index.d.ts";

const prisma: PrismaClientType = new PrismaClient();

This will work within our editor, but we'll run into a problem when we try to actually run our application.

$ deno run -A src/main.ts

error: Module not found "file:///[...]/prisma/generated/client/runtime/library".
    at file:///[...]/prisma/generated/client/index.d.ts:6:26

Removing the manually imported types fixes this issue but is far from an ideal development experience.

Stability

Apart from the ergonomics, there also seems to be ongoing stability issues with the Node compatibility layer. For example, when running the Prisma CLI, there's a frequent memory address error:

$ deno run -A npm:prisma@^4.5 generate

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
assertion failed [block != nullptr]: BasicBlock requested for unrecognized address
(BuilderBase.h:550 block_for_offset)
 fish: Job 1, 'deno run -A npm:prisma@^4.5 gen…' terminated by signal SIGABRT (Abort)

If we rerun the command enough times, it does in fact work.3 That said, this does not inspire confidence and is again another sharp edge against the development experience.

Back to Node

For my project, I've moved back to Node. My hope is that in the future this situation improves. Both the interface and stability of the Node compatibility layer seem to need additional attention.

It's also worth pointing out that Prisma may present some unique challenges that most NPM packages do not and so the average use case may never encounter these issues.

I'll look to revisit this in the future should things improve. Nonetheless, Deno isn't a runtime which can currently support my needs.

Footnotes

  1. The Prisma team notes it's not so easy,

    ...there are a lot of things to consider yet like how would the exosystem look like and would it be able to interop with the existing npm packages or would we have to create a separate one for Deno.

  2. Types are a key feature of Prisma and without them the value of the tool is dramatically reduced.

  3. On my machine, this happens the majority of the time. After several attempts, it eventually succeeds.

A Newsletter to Share My Knowledge

I built this site to share everything I know about leadership, building startups, and indie hacking. This newsletter is another way for me to provide that value to you.

What you get for signing up:

  • Exclusive content tailored just for our newsletter
  • Notifications when I add new content
  • Occasional access to unpublished and draft work

All signal, no noise. Unsubscribe at any point.