January 30, 2025

From Rust to TypeScript: A New Chapter for Prisma ORM

The Prisma query engine, written in Rust, has always been a core part of Prisma ORM. It was developed for the future, but is no longer compatible with Prisma ORM’s current direction. Read on to learn more about our rewrite from Rust to TypeScript.

Prisma’s doing what now?!

In our recently released ORM Manifesto, we described how Prisma ORM will be managed in the coming months and years. One small inclusion was the following tidbit:

We’re addressing this by migrating Prisma’s core logic from Rust to TypeScript and redesigning the ORM to make customization and extension easier.

This may have been only a sentence in our post, but it has caused quite a few reactions:

For example we really loved this video from Theo:

All in all, these are pretty reasonable reactions. The Rust query engine has been with Prisma ORM since the beginning. The discussion we have seen online has been great, but we also wanted to step in and provide some updates as our TypeScript implementation approaches Early Access.

In short, we want to let everyone in the community know what is changing, the motivation behind those changes, and how those changes will be implemented.

Why did Prisma choose Rust?

Before we can explore the future of Prisma ORM, we need to understand why Prisma ORM uses a Rust engine. When we started planning Prisma 2 (now known as Prisma ORM), we had a pretty clear vision: we wanted to build ORMs for as many languages as possible—TypeScript, Go, Python, Scala, Rust, and others. We needed a solution that would make adding support for new languages relatively straightforward. Rust’s performance benefits and systems-level approach made it a natural choice for this core query engine.

This decision was also a continuation of the work done on GraphCool and Prisma 1. The core, deployable infrastructure of these earlier solutions evolved into the Rust-based query engine—a binary designed to handle the heavy lifting of generating SQL queries, managing connection pools, and returning results from your database. This freed up language-specific clients like prisma-client-js to remain lightweight layers on top of the engine.

Why move away from Rust?

While having a powerful Rust engine helped us deliver great performance quickly, we’ve since discovered that it creates some notable challenges:

  • Skillset barriers: Contributing to the query engine requires a combination of Rust and TypeScript proficiency, reducing the opportunity for community involvement.
  • Deployment complexity: Each operating system and OpenSSL library version needs its own binary, complicating deployments and slowing down development.
  • Compatibility issues: Modern JavaScript runtimes, serverless, and edge environments aren’t always compatible with large Rust binaries, limiting how and where Prisma can be deployed.

Additionally, the core benefit of the query engine—the ability to support multiple clients—is no longer our focus. Prisma ORM is a TypeScript project and while we support our community clients, we won’t be developing them in house.

Taking these into account and adding in our commitment to building an inclusive, community-driven ecosystem (as outlined in our ORM Manifesto) has led us to migrate as many pieces as possible from our Rust query engine to TypeScript—simplifying contributions and reducing deployment headaches, without sacrificing the developer experience Prisma ORM users know and love.

Redefining query execution

The major architectural change we’re introducing in Early Access involves moving query execution and database result handling from Rust to TypeScript.

To understand this change, let’s review the current query engine setup.

Execution of a Prisma ORM query today

Today, there are two ways that you can query a database with Prisma ORM:

  • Using a database driver written in Rust.
  • Using a driver adapter and driver both written in TypeScript.

In the first approach, Prisma ORM queries are passed to the query engine, written in Rust. This engine manages everything from building the query plan to executing queries and returning results to the JavaScript client:

Prisma ORM communicating with a database

However, this architecture cannot support databases that only provide JavaScript drivers, such as D1 and Turso. To address this limitation, we introduced driver adapters.

When using a driver adapter, the query engine still develops the query plan and generates SQL statements. The execution, however, is delegated through the driver adapter to the database:

Prisma ORM communicating with a database via a driver adapter.

This approach enables compatibility with JavaScript drivers but introduces a tradeoff: data must be serialized from JavaScript to Rust and then back to JavaScript, reducing efficiency and negating some of the benefits of this method.

Execution of a Prisma ORM query tomorrow

In the new architecture, driver adapters will remain in use. However, instead of relying on a Rust-based query engine, Prisma ORM will pass the query to a WASM compiler, which will return the query plan. This plan will then be executed entirely in TypeScript:

Prisma ORM communicating with a database in the query compiler project

This simplified architecture delivers several immediate benefits:

  • Retains support for proven JavaScript database drivers.
  • Reduces the need for data translation between JavaScript and Rust.
  • Minimizes the volume of data transferred between Rust and JavaScript.
  • Eliminates the need to ship an external binary, as the query compiler no longer depends on system-specific utilities.

By shifting query execution to TypeScript, we streamline the architecture and enhance compatibility and performance for developers.

A streamlined experience coming soon

Moving logic across languages is a significant transformation, but we’re approaching it gradually to minimize disruption. While these changes are substantial, our priority is ensuring a smooth transition that maintains the simplicity and reliability you expect from Prisma. In this migration we’re not just addressing today’s challenges but also laying the foundation for an enhanced developer experience.

Steps toward a smooth transition

Our engineering team is incrementally transitioning query engine logic into the TypeScript side of the codebase. Components that cannot yet be moved are being re-packaged into a WASM file included in the @prisma/client npm module. This WASM file functions as the query compiler, simplifying workflows without significant API changes.

For instance, we plan to remove the requirement for binaryTargets, further streamlining the developer experience. Overall, the Prisma ORM experience will remain familiar and intuitive.

Unlocking future opportunities

This transition isn’t just about addressing current challenges—it creates new opportunities for innovation. In fact, the query compiler enables many possibilities for our team and the community to explore. For example, the use of parameterized query plans could allow for saving query plans for re-use to speed up execution. Another avenue would be to build the initial query plans at compile time, further reducing runtime computation needs.

We’re excited about these possibilities and eager to hear your thoughts! Join the discussion on our GitHub or Discord.

Help us build a better Prisma ORM experience

This project is a significant step toward making Prisma ORM better for everyone. At its core, Prisma ORM is built for developers like you. Your feedback and collaboration are crucial to this journey.

Here’s how you can help:

Finally, test our Early Access client! We’ll share updates on GitHub and Discord.

This is an exciting time for Prisma, with even more improvements and opportunities ahead. Thank you for inspiring us to grow and for being part of this journey.

Want to be among the first to try our new Early Access client? Follow us on X and join our Discord to stay updated.

Don’t miss the next post!

Sign up for the Prisma Newsletter