question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using Prisma with the Electron Framework

See original GitHub issue

Prisma Support for Electron

Electron is a framework for building cross-platform desktop apps with JavaScript, HTML, and CSS. While Electron can use similar frameworks and tooling as web applications, it (electron) has some differences that make it challenging to use with Prisma.

Existing problems

A (non-exhaustive) list of problems that should be addressed to improve the Electron experience with Prisma:

  1. Difficult to generate Prisma Client on the fly for a schema:

  2. Certain data types (Currently Bytes and BigInt) are unserializable and can’t be passed to the renderer process through IPC

Solved Problems

  1. Can not spawnQuery Engine binary when using Prisma with Electron:

Related Discussions and Issues on Github

Acknowledgement: Big thanks to @madebysid for his help in researching this issue.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:20
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

13reactions
TasinIshmamcommented, Oct 11, 2021

Assuming you are packaging and distributing the application past your own computer, I’m struggling to understand the use case for calling prisma directly in electron, instead of through an API?

@sinclairnick The most common use I have seen is to ship an SQLite Database with the electron app. This is done to ensure local data persistence and to support features for apps that need to work in offline mode, just to name a use-case.

12reactions
awohletzcommented, Dec 7, 2021

I’m using it as Tasin says, to manage a SQLite database. Here are a few issues I encountered:

  1. Large Electron app size – If the Electron app runs prisma migrate deploy, it needs the Prisma binaries (query engine, migration engine) included. The size of the binaries on Windows is 70MB and similar on Mac and Linux.
    1. Note the Prisma binaries (query engine, etc) have to be left out of the asar so that they can be executed by Prisma at runtime. I did this by including the Prisma binaries in the extraResources property of electron-builder and excluding them from files. At first I tried using asarUnpack, but that lead to the binaries getting placed in both app.asar and app.asar.unpacked, which doubles the space they take.
  2. No programmatic interface to Prisma migrate – I want to run prisma migrate deploy on app start. However the only way to do that currently is fork a new process, since it’s a CLI. Related issue: https://github.com/prisma/prisma/issues/4703
  3. Slow Prisma client instantiation. The issue is described in https://github.com/prisma/prisma/issues/10289 . I worked around it for now with a build script that replaces a specific line of code.

I have Prisma working fine on Windows, Mac, and Linux in my Electron app. But I had to figure out the above issues. Happy to talk with anyone who wants to try the same.

Appendix

Here’s my code for running prisma migrate deploy programmatically, in case anyone else is trying to do the same:

const platformToExecutables: any = {
    win32: {
        migrationEngine: 'node_modules/@prisma/engines/migration-engine-windows.exe',
        queryEngine: 'node_modules/@prisma/engines/query_engine-windows.dll.node'
    },
    linux: {
        migrationEngine: 'node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x',
        queryEngine: 'node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node'
    },
    darwin: {
        migrationEngine: 'node_modules/@prisma/engines/migration-engine-darwin-arm64',
        queryEngine: 'node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node'
    }
}

export async function runPrismaCommand({command, dbUrl}: {
    command: string[];
    dbUrl: string;
}): Promise<number> {

    const mePath = path.join(
        app.getAppPath().replace('app.asar', 'app.asar.unpacked'),
        platformToExecutables[process.platform].migrationEngine
    )

    try {
        const exitCode = await new Promise((resolve, _) => {
            const prismaPath = path.resolve(__dirname, "..", "..", "node_modules/prisma/build/index.js");

            const child = fork(
                prismaPath,
                command,
                {
                    env: {
                        ...process.env,
                        DATABASE_URL: dbUrl,
                        PRISMA_MIGRATION_ENGINE_BINARY: mePath,
                        PRISMA_QUERY_ENGINE_LIBRARY: path.join(
                            app.getAppPath().replace('app.asar', 'app.asar.unpacked'),
                            platformToExecutables[process.platform].queryEngine
                        ),
                    },
                    stdio: "inherit"
                }
            );

            child.on("error", err => {
                log.error("Child process got error:", err);
            });

            child.on("close", (code, signal) => {
                resolve(code);
            })
        });

        if (exitCode !== 0) throw Error(`command ${command} failed with exit code ${exitCode}`);

        return exitCode;
    } catch (e) {
        log.error(e);
        throw e;
    }
}

Code for working around slow Prisma client instantiation

const replace = require('replace-in-file');

// fix long prisma loading times caused by scanning from process.cwd(), which returns "/" when run in electron
// (thus it scans all files on the computer.) See https://github.com/prisma/prisma/issues/8484
const options = {
    files: path.join(__dirname, "src", "generated", "client", "index.js"),
    from: "findSync(process.cwd()",
    to: `findSync(require('electron').app.getAppPath()`,
};

const results = replace.sync(options);
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use Prisma with Electron - Stack Overflow
Solution. import { PrismaClient } from './generated/client'; As the downloaded binaries are also placed indside the output folder, there was no ...
Read more >
Running Prisma migrate in an Electron app
I use Prisma Migrate in my Electron app. Here's a mechanism to detect when I need to run migrations on app start.
Read more >
Quickstart with TypeScript & SQLite - Prisma
Quickstart · 1. Create TypeScript project and set up Prisma · 2. Model your data in the Prisma schema · 3. Run a...
Read more >
@prisma/studio-electron - npm
Modern Database IDE. Latest version: 0.426.0, last published: a year ago. Start using @prisma/studio-electron in your project by running ...
Read more >
Learn Electron, Jwt and Prisma - Egghead.io
Build a Backend with Prisma in a TypeScript Node Project. Ryan Chenkie ... JSON Web Token (JWT) Authentication with Node.js and Auth0. Joel...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Hashnode Post

No results found