How to execute a function of the main process inside the renderer process in Electron Framework

In some cases, you will need to execute functions that are only accesible at the main process level, besides it can be useful to execute some JS code that can lock the user interface due to its expensive execution. This can be easily done with JavaScript and with some knowledge of the export functions, however if you want to follow the Electron guidelines, we recommend you to use the ipcMain module and the ipcRenderer module of Electron that will help you to communicate asynchronously from the main process to renderer processes.

1. Set the event listener in the main process

The first you need to do is to create an event listener in the main process using the ipcMain module. It works pretty easy and straight forward, you only attach an event listener whose callback will be executed once the ipcRenderer module (in the view) requests its execution.

So, attach the event listener inside a file that runs in the main process, like main.js:

// In some file from the main process
// like main.js
const {ipcMain} = require('electron');

// Attach listener in the main process with the given ID
ipcMain.on('request-mainprocess-action', (event, arg) => {
    // Displays the object sent from the renderer process:
    //{
    //    message: "Hi",
    //    someData: "Let's go"
    //}
    console.log(
        arg
    );
});

Inside the callback, the code that you want to execute in the main process. In this case, we are only showing in the console (of the console that starts the Electron application) the data sent in the renderer (view) process. To know how to trigger this callback, check the following step.

2. Trigger the event from the renderer process

Now if you are sure that there's already an IPC event listener in the main process, you can trigger it with its ID in the renderer process. To make it clearly, we are going to execute it from the index file inside a script tag:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Electron Application</title>

        <!-- Use minimum-scale=1 to enable GPU rasterization -->
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1">
    </head>
    <body>
        <div id="app"></div>

        <script>
            /**
             * The code can be included in some JS file and included
             * via require or <script> in the renderer process
             */

            const { ipcRenderer } = require('electron');

            // Some data that will be sent to the main process
            let Data = {
                message: "Hi",
                someData: "Let's go"
            };

            // Send information to the main process
            // if a listener has been set, then the main process
            // will react to the request !
            ipcRenderer.send('request-mainprocess-action', Data);
        </script>
    </body>
</html>

Using in this case, as we are in the view, the ipcRenderer module, you only need to execute the  send method from it, that expects as first argument the ID of the event that will be triggered and as second argument an object, string, boolean with information that you want to sent from the renderer process to the main one.

3. Requesting and sending information

If you want to send data instead of only executing a callback, you can follow the same process, however using the event.sender object to send information from the main process to the renderer process and adding a listener with the IPCRenderer in the view:

Main process

// In some file from the main process
// like main.js
const {ipcMain} = require('electron');

// Attach listener in the main process with the given ID
ipcMain.on('request-mainprocess-action', (event, arg) => {
    // Displays the object sent from the renderer process:
    //{
    //    message: "Hi",
    //    someData: "Let's go"
    //}
    console.log(
        arg
    );

    // Return some data to the renderer process with the mainprocess-response ID
    event.sender.send('mainprocess-response', "Hello World!");
});

Renderer process

/**
 * The code can be included in some JS file and included
 * via require or <script> in the renderer process
*/

const { ipcRenderer } = require('electron');

// Some data that will be sent to the main process
let Data = {
    message: "Hi",
    someData: "Let's go"
};

// Add the event listener for the response from the main process
ipcRenderer.on('mainprocess-response', (event, arg) => {
    console.log(arg); // prints "Hello World!"
});

// Send information to the main process
// if a listener has been set, then the main process
// will react to the request !
ipcRenderer.send('request-mainprocess-action', Data);

Happy coding !

This could interest you

Become a more social person