Skip to content

Electron Main Process ​

GemShell lets you hook into Electron's main process with a plain JavaScript file — no ejecting, no custom build setup.

Setup ​

  1. Create a main-process.js in your project root.
  2. Set the "main" field in your package.json:
json
{
  "name": "my-game",
  "main": "main-process.js"
}

GemShell picks it up at build time and runs it inside the main process right after the game window is created.

What you get ​

Your script receives three arguments and has access to global.mainWindow:

js
// main-process.js
module.exports = function (mainWindow, app, ipcMain) {
  // mainWindow — the BrowserWindow instance
  // app        — Electron's app module
  // ipcMain    — Electron's ipcMain module
};

global.mainWindow is also set globally, so you can access it anywhere in the file without the argument.

Examples ​

Crash reporting ​

js
const { crashReporter } = require('electron');

module.exports = function () {
  crashReporter.start({
    submitURL: 'https://your-server.com/crashes',
    uploadToServer: true,
  });
};

Crashes are automatically sent as minidumps to your endpoint. Without a server you can read them locally:

js
const { app, crashReporter } = require('electron');
crashReporter.start({ uploadToServer: false });
console.log('Crash dumps folder:', app.getPath('crashDumps'));

Custom IPC handlers ​

js
const { ipcMain } = require('electron');

module.exports = function (mainWindow) {
  ipcMain.handle('my-game:save', async (event, data) => {
    // handle save logic
    return { ok: true };
  });

  ipcMain.on('my-game:quit', () => {
    mainWindow.close();
  });
};

Call from your game:

js
const result = await window.electron.ipcRenderer.invoke('my-game:save', saveData);

Window control ​

js
module.exports = function (mainWindow) {
  mainWindow.on('close', (e) => {
    // intercept close, show confirm dialog, etc.
  });

  // Remove menu bar
  mainWindow.setMenuBarVisibility(false);

  // Always on top
  mainWindow.setAlwaysOnTop(true);
};

App lifecycle ​

js
const { app } = require('electron');

module.exports = function () {
  app.on('before-quit', () => {
    // flush saves, close DB connections, etc.
  });
};

Notes ​

  • The file is copied to _user-main.js inside the build. Don't reference it by that name — always use the "main" field in package.json.
  • The function is called after the window is created and shown, so mainWindow is always valid.
  • You have access to all of Node.js and the full Electron main-process API (app, BrowserWindow, dialog, shell, ipcMain, crashReporter, autoUpdater, etc.).
  • If your file exports something other than a function, it is still loaded but the arguments are not passed. Export a function to receive mainWindow, app, and ipcMain.