electron-vite: Easy way to protect your Electron source code
Tags: webdev, vite, electron, beginners
Published: 2022-09-20 11:47:08

**[electron-vite](https://evite.netlify.app/) is a build tool that aims to provide a faster and leaner development experience for Electron.**

We all know that Electron uses javascript to build desktop applications, which makes it very easy for hackers to unpack our applications, modify logic to break commercial restrictions, repackage, and redistribute cracked versions.

## Solutions

To really solve the problem, in addition to putting all the commercial logic on the server side, we need to harden the code to avoid unpacking, tampering, repackaging, and redistributing.

The mainstream plan:

1. **Uglify / Obfuscator:** Minimize the readability of JS code by uglifying and obfuscating it.
2. **Native encryption:** Encrypt the bundle via XOR or AES, encapsulated into Node Addon, and decrypted by JS at runtime.
3. **ASAR encryption:** Encrypt the Electron ASAR file, modify the Electron source code, decrypt the ASAR file before reading it, and then run it.
4. **V8 bytecode:** The `vm` module in the Node standard library can generate its cache data from script objects ([see](https://nodejs.org/api/vm.html#vm_script_createcacheddata)). The cached data can be interpreted as v8 bytecode, which is distributed to achieve source code protection.

Scheme comparison:

| -               | Obfuscator | Native encryption | ASAR encryption | V8 bytecode |
| :-------------: | :--------: | :---------------: | :-------------: | :---------: |
| **Unpack**      | Easy       | High              |  High           | High        |
| **Tampering**   | Easy       | Easy              |  Middle         | High        |
| **Readability** | Easy       | Easy              |  Easy           | High        |
| **Repackaging** | Easy       | Easy              |  Easy           | Easy        |
| **Access cost** | Low        | High              |  High           | Middle      |
| **Overall protection**  | Low        | Middle            |  Middle         | High        |


For now, **the solution with v8 bytecode seems to be the best one**.

Read more:

- [Electron code protection solution based on Node.js Addon and V8 bytecode](https://www.mo4tech.com/electron-code-protection-solution-based-on-node-js-addon-and-v8-bytecode.html)

## What is V8 Bytecode

As we can understand, V8 bytecode is a serialized form of JavaScript parsed and compiled by the V8 engine, and it is often used for performance optimization within the browser. So if we run the code through V8 bytecode, we can not only protect the code, but also improve performance.

`electron-vite` inspired by [bytenode](https://github.com/bytenode/bytenode), the specific implementation:

- Implement a plugin `bytecodePlugin` to parse the bundles, and determines whether to compile to bytecode.
- Start the Electron process to compile the bundles into `.jsc` files and ensure that the generated bytecode can run in Electron's Node environment.
- Generate a bytecode loader to enable Electorn applications to load bytecode modules.
- Support developers to freely decide which chunks to compile.

In addition, electron-vite also solves some problems that `bytenode` can't solve:

- Fixed the issue where async arrow functions could crash Electron apps.

## Enable Bytecode to Protect Your Electron Source Code

Use the plugin `bytecodePlugin` to enable it:

```js
import { defineConfig, bytecodePlugin } from 'electron-vite'

export default defineConfig({
  main: {
    plugins: [bytecodePlugin()]
  },
  preload: {
    plugins: [bytecodePlugin()]
  },
  renderer: {
    // ...
  }
})
```

![test1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lx4xi45xuf0g52o5veh6.gif)

## Customizing Protection

For example, only protect `src/main/foo.ts`:

```{5}
.
├──src
│  ├──main
│  │  ├──index.ts
│  │  ├──foo.ts
│  │  └──...
└──...
```

You can modify your config file like this:

```js
import { defineConfig, bytecodePlugin } from 'electron-vite'

export default defineConfig({
  main: {
    plugins: [bytecodePlugin({ chunkAlias: 'foo' })],
    build: {
      rollupOptions: {
        output: {
          manualChunks(id): string | void {
            if (id.includes('foo')) {
              return 'foo'
            }
          }
        }
      }
    }
  },
  preload: {
    // ...
  },
  renderer: {
    // ...
  }
})
```

![test2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4msh9yqaix8twi7cfhu1.gif)

## Examples

You can learn more by playing with the [example](https://github.com/alex8088/electron-vite-bytecode-example).

## QA

### Impact on code organization and writing?

The only effect that bytecode schemes have found on code so far is `Function.prototype.toString()`Method does not work because the source code does not follow the bytecode distribution, so the source code for the function is not available.

### Does it affect application performance?

There is no impact on code execution performance and a slight improvement.

### Impact on program volume?

For bundles of only a few hundred KILobytes, there is a significant increase in bytecode size, but for 2M+ bundles, there is no significant difference in bytecode size.

### How strong is the code protection?

Currently, there are no tools available to decompile V8 bytecode, so this solution is reliable and secure.

## More electron-vite Features

- **Pre-configured:** Pre-configured for Electron, don't worry about configuration.
- **Fast HMR:** HMR for renderer processes.
- **Hot Reloading:** The main process and preload scripts support hot reloading.
- **Easy to Debug:** Very easy to debug in IDE like vscode or webstorm.
- **Out-of-the-box:** Out-of-the-box support for TypeScript, Vue, React, Svelte, SolidJS and more.

## End

You can learn more about electron-vite and source code protection at the following links:

Docs：[https://evite.netlify.app/](https://evite.netlify.app/)

GitHub：[https://github.com/alex8088/electron-vite/](https://github.com/alex8088/electron-vite/)