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 (unlikeelectron-store
- issue link) - Has CommonJS exports (
electron-store
has only ESM exports) - Uses the same API as
zustand
for getting values from store (viauseEncryptedStore
React hook)- e.g.
const encrypted = useEncryptedStore(store => store.encrypted)
- e.g.
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
- Clone this repo:
git clone https://github.com/rixcian/encrypted-electron-store
- Make sure you have node v22:
nvm use
- Install dependencies:
npm i
- After making changes, run tests:
npm run test
- Create changelog:
npx @changesets/cli
- As a maintainer, after review, I will run:
npx @changesets/cli version
- Build the library:
npm run build
- And publish it to NPM with:
npx @changesets/cli publish
Comparison to electron-store
Feature | encrypted-electron-store | electron-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) |