How to use Rust inside your Electron application with Neon Bindings
// What is it for?
/* If you have an Electron application that needs to be more performant in some tasks, if you need to access something on operating system or even to try the Rust language.
Github Repository: https://github.com/cazetto/neon-electron
Hi, everyone. This is my first contribution on Medium, I hope you enjoy it!
Today we'll create an Electron application with the superpowers of the Rust Language.
Prerequisites:
Install NodeJS: https://nodejs.org/en/download/
Install Rust: https://www.rust-lang.org/tools/install
The Rust part
What is Neon?
Neon is a library and toolchain for embedding Rust in your NodeJS apps and libraries.
What a Neon project is?
Neon project is both a Node npm package, and a Rust crate package.
First of all, we are going to create a new Neon Project.
I am referencing the Neon documentation and the base of our project is the code resultant from the Neon hello-world tutorial.
https://neon-bindings.com/docs/hello-world
We'll start by creating a neon Project named neon-electron:
npm init neon neon-electron
This will generate a new project containing aCargo.toml
and a package.json
file, let's take a look at what is this:
Cargo is the Rust package manager, like in node that we have the npm, in Rust we have Cargo.
And we have a src/lib.rs
, that is where the magic happens, this file is the Rust part of our application and in this tutorial, we'll share the information about the number of CPUs in your computer, like in the Neon Bindings hello world tutorial.
Start by adding num_cpus
Rust library as a dependency in our Cargo.toml:
[dependencies]
num_cpus = "1"
Run yarn to install the dependencies:
yarn
Now, inside lib.rs,
we're going to create the function to read the number of CPUs through the num_cpus Rust crate:
fn get_num_cpus(mut cx: FunctionContext) -> JsResult<JsNumber> { Ok(cx.number(num_cpus::get() as f64));}
Finally, we export our function from Rust code, it will be available in the generated file index.node
.
#[neon::main]fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("get", get_num_cpus)?; Ok(())}
The lib.rs
code becomes:
Now we should be able to rebuild the project:
npm run build -- --release
Now we can test it by open NodeJS in the terminal and running generated code:
node> const cpuCount = require('.')> cpuCount.get()4
The Electron part
Add Electron as a dependency:
yarn add -D electron
Add electron start script to package.json
{
"scripts": {
"dev": "electron ./src/main.js",
}
}
Create a src/main.js
file:
Create the src/preload.js
script:
Create the src/index.html
file:
Put the two parts to work together:
In our src/index.html
we need to add a new element to show the number of CPUs.
<p> <span>CPUs:</span> <span id="number-of-cpus"></span></p>
The src/ndex.html
file becomes:
In the src/preload.js
the file we need to import the code generated by Neon:
const lib = require('../index.node');
Inside DOMContentLoader callback:
const numberOfCPUs = lib.get();const numberOfCPUsElement = document.getElementById(‘number-of-cpus’);numberOfCPUsElement.innerText = numberOfCPUs;
Than, src/preloader.js
becomes:
With this, we can run yarn dev
and see our application running with the number of CPUs data coming from Rust to NodeJS.
And that is all, feel free to interact with this post, ask or suggest something, and let me know if I made any mistakes.
Let me know if this tutorial was helpful for you or not so I can direct myself to write better posts.
Hope you enjoy it 🚀