Appearance
Electron Main Process
GemShell lets you hook into Electron's main process with a plain JavaScript file — no ejecting, no custom build setup.
Setup
- Create a
main-process.jsin your project root. - Set the
"main"field in yourpackage.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.jsinside the build. Don't reference it by that name — always use the"main"field inpackage.json. - The function is called after the window is created and shown, so
mainWindowis 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, andipcMain.
