Skip to content

Instantly share code, notes, and snippets.

@steve981cr
Created August 30, 2023 20:17
Show Gist options
  • Save steve981cr/499dae0c2a4c6340d0f35656dae92020 to your computer and use it in GitHub Desktop.
Save steve981cr/499dae0c2a4c6340d0f35656dae92020 to your computer and use it in GitHub Desktop.
Electron-Store interim fix to Electron Forge packaging error

Electron-Store interim fix to Electron Forge packaging error

The problem: Electron's recommended app packager is Electron Forge. My app uses electron-store to persist small amounts of data used in the main process. It works fine in development mode but for some reason when I package the app with Electron-forge it will thrown an error and crash the app.

Interim solution: My solution was to build my own super simple storage module using the same file and method names used by electron store. It is not as robust as electron-store but it was sufficient for my needs so I thought I would pass this on to anyone else running into this issue. This is not an npm package, rather you can just copy the code below to make your own local module. If you are already using electron-store you do not have to modify any of your code except for adding the relative path to your module in the require statement.


Electron-store.js

Create a file named electron-store.js populated with the below. It exports a class called Store that places a JSON file called config.json in your app's userData directory.

Store contains three instance methods.

  • The get method returns the JSON data converted to a JavaScript config object.
  • The set method adds or changes the value of a config object property.
  • The delete method deletes the value of a config object property.
const { app } = require('electron');
const path = require('path');
const fs = require('fs');

class Store {
  get(key) {
    const configPath = path.join(app.getPath('userData'), 'config.json');
    if (!fs.existsSync(configPath)) {
      fs.writeFileSync(configPath, '{}');
    }
    const configJson = fs.readFileSync(configPath, 'utf8');
    const configJs = JSON.parse(configJson);
    return configJs[key];
  }

  set(key, value) {
    const configPath = path.join(app.getPath('userData'), 'config.json');
    if (!fs.existsSync(configPath)) {
      fs.writeFileSync(configPath, '{}');
    }
    const configJson = fs.readFileSync(configPath, 'utf8');
    const configJs = JSON.parse(configJson);
    configJs[key] = value;
    const newConfigJson = JSON.stringify(configJs);
    fs.writeFileSync(configPath, newConfigJson);
  }

  delete(key) {
    const configPath = path.join(app.getPath('userData'), 'config.json');
    if (!fs.existsSync(configPath)) {
      fs.writeFileSync(configPath, '{}');
    }
    const configJson = fs.readFileSync(configPath, 'utf8');
    const configJs = JSON.parse(configJson);
    configJs[key] = '';
    const newConfigJson = JSON.stringify(configJs);
    fs.writeFileSync(configPath, newConfigJson);
  }
}

module.exports = Store;

Main.js

The only change to the main.js file is to include the path to the electron-store file when you import your module.

const Store = require('./electron-store');

const store = new Store();

store.set('unicorn', '🦄');
console.log(store.get('unicorn'));
//=> '🦄'

// Use dot-notation to access nested properties
store.set('foo.bar', true);
console.log(store.get('foo'));
//=> {bar: true}

store.delete('unicorn');
console.log(store.get('unicorn'));
//=> undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment