Repo of the Day
reZach/secure-electron-store
Published: Jan 27, 2022
Open repository ↗I'm torn about recreating cliplo in React or Vue 3. I think I am actually leaning toward React.... blehhh. I wanted to work in Vue, but the secure-electron-template already has react, redux, and all those nice to haves ready out of the box. Using dexie with react should be pretty easy as well.
Summary
secure-electron-store is a JavaScript library that reworks electron-store to read and write a local JSON config file through Electron's ipcMain/ipcRenderer channels instead of letting the renderer touch the filesystem directly. It is built to be paired with secure-electron-template and supports optional passkey-based encryption using Node's crypto, plus msgpack minification of the stored file.
What it is useful for
This package is useful when you are building an Electron app and want renderer code to persist key/value settings such as user preferences, feature flags, or window state without granting the renderer direct fs access. By routing reads and writes through IPC and a preload script with contextIsolation, the renderer can only call the specific request handlers you expose via contextBridge.exposeInMainWorld("api", { store: ... }). The optional passkey option adds a password layer on top of the encrypted file, and a separate "unprotected" store (introduced in v1.3.0) is meant for values the main process needs before the app boots, such as BrowserWindow width and height.
How engineers can use it
Install with npm i secure-electron-store, then wire it up in two places. In the file that creates the BrowserWindow, instantiate new Store({ path: app.getPath("userData") }), pass --storePath=... via additionalArguments, point preload at your preload script, and call store.mainBindings(ipcMain, win, fs). In the preload script, require the package, build a Store, and expose store.preloadBindings(ipcRenderer, fs) through contextBridge.
From the renderer, reads use window.api.store.send(readConfigRequest, "myvalue") paired with onReceive(readConfigResponse, ...); writes use send(writeConfigRequest, key, value); deletes use deleteConfigRequest; and a one-shot snapshot is available through window.api.store.initial(). To let the main process read the config (for example to call win.maximize()), send useConfigInMainRequest and add a callback parameter to mainBindings. If a non-empty passkey is configured, you must send savePasskeyRequest first, and initial() is not available.
Two caveats from the docs: every option except path and unprotectedPath must be configured in both the main and preload files, and you should call window.api.store.clearRendererBindings() (e.g. in React's componentDidMount) to avoid duplicate subscriptions. The full options list, the unprotected-store message mapping, and the rest of the API are documented in the README.