DEPRECATED: electron-remote: an asynchronous 'remote', and more

No Maintenance Intended

This project is no longer maintained, pull requests are no longer being reviewed or merged and issues are no longer being responded to.


remote

The Quickest of Quick Starts

Calling main process modules from a renderer
import { createProxyForMainProcessModule } from 'electron-remote';

// app is now a proxy for the app module in the main process
const app = createProxyForMainProcessModule('app');

// The difference is all methods return a Promise instead of blocking
const memoryInfo = await app.getAppMemoryInfo();
Calling code in other windows
import { createProxyForRemote } from 'electron-remote';

// myWindowJs is now a proxy object for myWindow's `window` global object
const myWindowJs = createProxyForRemote(myWindow);

// Functions suffixed with _get will read a value
userAgent = await myWindowJs.navigator.userAgent_get()
Renderer Taskpool
import { requireTaskPool } from 'electron-remote';

const myCoolModule = requireTaskPool(require.resolve('./my-cool-module'));

// This method will run synchronously, but in a background BrowserWindow process
// so that your app will not block
let result = await myCoolModule.calculateDigitsOfPi(100000);

But I like Remote!

Remote is super convenient! But it also has some downsides - its main downside is that its action is synchronous. This means that both the main and window processes will wait for a method to finish running. Even for quick methods, calling it too often can introduce scroll jank and generally cause performance problems.

electron-remote is a version of remote that, while less ergonomic, guarantees that it won't block the calling thread.

Using createProxyForRemote

createProxyForRemoteexecuteJavaScriptwindowremote

This provides a number of very important advantages:

createProxyForRemoteeval

How do I get properties if everything is a Promise tho???

_get()
import { createProxyForRemote } from 'electron-remote';

// myWindowJs is now a proxy object for myWindow's `window` global object
const myWindowJs = createProxyForRemote(myWindow);

// Functions suffixed with _get will read a value
myWindowJs.navigator.userAgent_get()
  .then((agent) => console.log(`The user agent is ${agent}`));

But do this first!

createProxyForRemoteinitializeEvalHandler()

Bringing it all together

// In my window's main.js
initializeEvalHandler();
window.addNumbers = (a,b) => a + b;


// In my main process
let myWindowProxy = createProxyForRemote(myWindow);
myWindowProxy.addNumbers(5, 5)
  .then((x) => console.log(x));

>>> 10

Using createProxyForMainProcessModule

remotecreateProxyForRemoteevalipc.sendSync

Here Be Dragons

electron-remote has a number of significant caveats versus the remote module that you should definitely be aware of:

  • Remote values must be Serializable
JSON.stringify
let myWindowProxy = createProxyForRemote(myWindow);

// XXX: BAD - HTML elements aren't serializable
let obj = myWindowProxy.document.createElement('h1');
  • Remote event listeners aren't supported

Anything that involves an event handler isn't going to work:

// XXX: BAD - You can't add event handlers
myWindowProxy.document.addEventListener('onBlur', (e) => console.log("Blur!"));

The Renderer Taskpool

Renderer Taskpools provide an automatic way to use BrowserWindows as "background processes" that auto-scales based on usage, similar to Grand Central Dispatch or the .NET TPL Taskpool. This works by allowing you to provide a Module that you'd like to load in the remote processes, which will be loaded and unloaded on the fly according to demand.

Let's look at the example again:

import { requireTaskPool } from 'electron-remote';

const myCoolModule = requireTaskPool(require.resolve('./my-cool-module'));

// This method will run synchronously, but in a background BrowserWindow process
// so that your app will not block
let result = await myCoolModule.calculateDigitsOfPi(100000);
requireTaskPool
More Dragons
requireTaskPool

The remote-ajax module

remote-ajax
import { requireTaskPool } from 'electron-remote';

const remoteAjax = requireTaskPool(require.resolve('electron-remote/remote-ajax'));

// Result is the object that XmlHttpRequest gives you
let result = await remoteAjax.get('https://httpbin.org/get');
console.log(result.url)

>>> 'https://httpbin.org/get'

See the documentation for Rx-DOM for how these methods work.

downloadFileOrUrl
/**
 * Downloads a path as either a file path or a HTTP URL to a specific place
 *
 * @param  {string} pathOrUrl   Either an HTTP URL or a file path.
 * @return {string}             The contents as a UTF-8 decoded string.
 */
function downloadFileOrUrl(pathOrUrl, target)