Electron has something called inter-process communication. That inter-process communication was a bit confusing, so I’m posting a record of learning it with diagrams.
Inter-Process Communication (One-Way)
Inter-Process Communication | Electron
IPC: interprocess communication: exchanging data between running programs: inter-process communication
This is achieved using ipcRenderer.send and ipcMain.on.
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js');
}
})
mainWindow.loadFile('index.html');
}
app.whenReady().then(() => {
ipcMain.on('say-hello', (event, hello) => console.log(hello));
createWindow();
});
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
seyHello: (hello) => ipcRenderer.send('say-hello', hello);
});
<html>
<script>
window.electronAPI.sayHello("hello");
</script>
</html>

Inter-Process Communication (Two-Way)
Inter-Process Communication | Electron
This is achieved by using ipcRenderer.invoke and ipcMain.handle as a pair.
const {app, BrowserWindow, ipcMain, dialog} = require('electron')
const path = require('path')
async function handleYourName() {
return "Taki Tachibana"
}
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.handle('whats:yourname', handleYourName)
createWindow()
})
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI',{
yourName: () => ipcRenderer.invoke('whats:yourName')
})
<html>
<script>
const yourName = await window.electronAPI.yourName()
console.log("I'm Mitsuha Miyamizu your name:" + yourName);
</script>
</html>
