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.