This article assumes that you have a basic understanding of the Prisma Client.
Prisma is an open source next-generation ORM for Node.js and Typescript, allowing connection to PostgreSQL, MySQL and SQLite databases servers.
It has been an instrumental tool in our organisation’s backend service. It has vastly improved our speed of development, allowing our (TypeScript loving) team to quickly build and deliver features at a fraction of the speed.
As we developed more services we found that each of our services had its own individual Prisma Client. And since all of our services are currently connected to the same database this wasn’t the cleanest solution. As you can imagine, whenever we made any database schema changes or even just updated our Prisma dependencies — this meant we had to repeat the same task multiple times. As programmers we couldn’t break the cardinal sin of staying DRY.
To solve this we moved our reused Prisma Client as an internal package with organisation level scope. The package simply exports the context so that we can plug and play it into any of our projects.
With this approach, making schema changes or updating Prisma versions is now as simple as releasing a new version of our internal package and updating the version used by the relevant projects. We don’t even need to have Prisma installed as a dependency in the other projects anymore. Hopefully the programming gods will forgive us now.
Here’s how you can do it too.
Creating a new Prisma project
Setup a new project with
npm init. We'll be publishing this project as a package so use the following naming convention to name it:
We'll follow the same process as the one outlined in the Prisma quick start guide. The new project will contain our schema.prisma file, we will be able to either introspect our db to generate the schema or declare it ourselves and use prisma migrate. In this walkthrough, we’ll be introspecting our db schema.
- First create a new typescript project and install the prisma package. Your dependencies should look similar to the ones below:
- Next create or copy from one of you existing projects the prisma folder and the schema.prisma file. The only bit we care about from the schema.prisma file is the set of code which tells Prisma what we’re using as a datasource — in our case, a PostgreSQL db.
Don't forget to create an .env file and add your db url to it!
- Now we can add the following scripts to our package.json file which allow us to generate the schema.prisma by introspecting our db and to update the prisma client:
After running the newly added scripts your schema.prisma file should have been generated. Now we simply need to export our context and types so that we can use them in any of our projects.
- Create a src directory and then create both index.ts and index.d.ts files inside it. We’ll need to create and export our context in our index.ts as below:
And our ts declaration file should look as below:
Notice how we are also exporting all of the types generated in the prisma client, so we can have access to them in any of our projects.
- Last step is to create a postinstall script that builds your ts code and generates the prisma client after you install the newly create package:
Notice how we are using npx to run prisma generate, this way we won’t even need to have prisma installed in any of our other projects. The prisma version used here should match your project's version.
Publishing your package
We do this by using github actions to create a new private package for our organisation, a great guide into how to do so can be found here.
In the root of your new project create a file under
Push your changes, you can now finally create a new package by creating a new release in github:
A github action should have been triggered and your package will be published!
If you release the package as a private package you should create a
.npmrc file as shown here in any of the projects where you wish to install it. This allows npm to resolve your package name.
Now we can remove Prisma from all of our other projects and simply use our new package instead, we can import the context and context types from it as well as any of the prisma client generated types.
That’s all folks. I hope helps. I welcome any comments / suggestions.