Skip to content

Instantly share code, notes, and snippets.

@juliusmarminge
Last active May 6, 2024 17:22
Show Gist options
  • Save juliusmarminge/b06a3e421117a56ba1fea54e2a4c0fcb to your computer and use it in GitHub Desktop.
Save juliusmarminge/b06a3e421117a56ba1fea54e2a4c0fcb to your computer and use it in GitHub Desktop.
prisma enum generator
import { generatorHandler } from "@prisma/generator-helper";
import fs from "node:fs/promises";
import path from "node:path";
const header = `// This file was generated by a custom prisma generator, do not edit manually.\n`;
generatorHandler({
onManifest() {
return {
defaultOutput: "./enums/index.ts",
prettyName: "Prisma Enum Generator",
};
},
async onGenerate(options) {
const enums = options.dmmf.datamodel.enums;
const output = enums.map((e) => {
let enumString = `export const ${e.name} = {\n`;
e.values.forEach(({ name: value }) => {
enumString += ` ${value}: "${value}",\n`;
});
enumString += `} as const;\n\n`;
enumString += `export type ${e.name} = (typeof ${e.name})[keyof typeof ${e.name}];\n`;
return enumString;
});
const outputFile = options.generator.output;
if (!outputFile || !outputFile.value) {
throw new Error("No output file specified");
}
const outputPath = path.resolve(outputFile.value);
await fs.mkdir(path.dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, header + output.join("\n"), "utf-8");
},
});

Enum Prisma Generator

It turns out Prisma doesn't treeshake very well, so your prisma client (20kB compressed) is being imported everytime you use an enum. They also cannot be imported on the client as the prisma client will throw error there.

That's where this generator comes in. It pulls out all your enums into a separate file which you can import without the prisma client being "leaked" in. We managed to reduce the bundle size by 5% across the board on cal.com by using this. (PR here)

How to use

  1. In your prisma folder, create a generator as above, and add it in your schema file. I use tsx to run the generator but you can use ts-node as well (as the PR above do too).

  2. When you run prisma generate, a new file will be created in enums/index.ts which will contain all your enums.

  3. Start moving all your imports to use this new entrypoint:

- import { SchedulingType } from "@prisma/client";
+ import { SchedulingType } from "./prisma/enums";

Done! Here is a summary of the results we got:

image

// ...
generator client {
provider = "prisma-client-js"
}
generator enums {
provider = "tsx ./enum-generator"
}
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment