4 min read
encrypted-electron-store

Simple encrypted data persistence for your Electron app - Save and load user settings, app state, cache, and more.

You can use it as a single store for both the main and renderer processes.

It has the same features as the well-known electron-store library, but solves several other things:

  • Encrypts the data saved on disk (using Electron’s built-in safeStorage API)
  • Support for React hooks (auto re-renders view on store update)
  • Works in the renderer process (unlike electron-store - issue link)
  • Has CommonJS exports (electron-store has only ESM exports)
  • Uses the same API as zustand for getting values from store (via useEncryptedStore React hook)
    • e.g. const encrypted = useEncryptedStore(store => store.encrypted)

Install

npm i encrypted-electron-store
pnpm i encrypted-electron-store
yarn add encrypted-electron-store

Usage

Main process (main.ts/js)

import EncryptedStore from 'encrypted-electron-store/main'

const store = EncryptedStore.create<any>()
// or: const store = EncryptedStore.create<{ encrypted: string }>()
// or: const store = EncryptedStore.create<IStore>()

store.set('encrypted', '🔒')
console.log(store.get('encrypted'))
//=> '🔒'

store.delete('encrypted')
console.log(store.get('encrypted'))
//=> undefined

// IMPORTANT: If you want to use the store in the renderer process
window.webContents.on('did-finish-load', () => {
	encryptedStore.setBrowserWindow(window)
})

Renderer process

If you want to use this library in the renderer process, you first need to call this function in the preload.ts/js file.

// preload.ts/js
import { preloadEncryptedStore } from 'encrypted-electron-store/preload'

preloadEncryptedStore()

// ... rest of the file

React

Add the EncryptedStoreProvider component in main.tsx/jsx or wherever you want in your React project.

// main.tsx/jsx
import { EncryptedStoreProvider } from 'encrypted-electron-store/react'

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <EncryptedStoreProvider>
      <App />
    </EncryptedStoreProvider>
  </React.StrictMode>
);

Use the useEncryptedStore() hook wherever you want in your React project.

// e.g. App.tsx/jsx
import { useEncryptedStore } from 'encrypted-electron-store/react'

function App() {
  const { store, setStore } = useEncryptedStore<{ encrypted: string }>()
  const encrypted = useEncryptedStore<{ encrypted: string }>((store) => store.encrypted);

  setStore({ encrypted: '🔒' });

  return (
    /* Gets automatically re-rendered when the value changes */
    <p>{encrypted}</p>
  )
}

Vanilla JS

import EncryptedStore from 'encrypted-electron-store/vanilla'

// You need to use `await` because the library reads the initial store from the file on disk.
const store = await EncryptedStore.create<{ encrypted: string }>()

store.set('encrypted', '🔒')
console.log(store.get('encrypted'))
// => '🔒'

Docs

You can find examples of usage in real projects in the examples folder.

Contribution

  1. Clone this repo:
git clone https://github.com/rixcian/encrypted-electron-store
  1. Make sure you have node v22:
nvm use
  1. Install dependencies:
npm i
  1. After making changes, run tests:
npm run test
  1. Create changelog:
npx @changesets/cli
  1. As a maintainer, after review, I will run:
npx @changesets/cli version
  1. Build the library:
npm run build
  1. And publish it to NPM with:
npx @changesets/cli publish

Comparison to electron-store

Featureencrypted-electron-storeelectron-store
Works in main & renderer processes✅ Yes🟡 Only in main process
ESM & CommonJS exports✅ ESM & CJS Supported❌ Only ESM exports supported
Encryption✅ Uses Electron’s built-in encryption🟡 Not sufficient (encryption password in plaintext)
React Integration✅ Built-in React hooks❌ No React integration
Vanilla JS Integration✅ Simple API✅ Simple API
File Extensions✅ Configurable✅ Configurable
Works with files atomically✅ Yes✅ Yes
JSON Schema validation🟡 Work in progress✅ Yes
Migrations❌ Yes, if there’ll be demand🟡 Yes, with bugs (more info)