Skip to content

rixcian/encrypted-electron-store

Repository files navigation

encrypted-electron-store

npm version npm downloads License Issues Pull Requests


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.

todo: Here will be specified detailed documentation; or just link to the official docs

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

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)

Todos

  • Finish basic React implementation
  • Make const time = useEncryptedStore((store, setStore) => store.time) architecture possible (similar to zustand)
// Usage
const { store, setStore } = useEncryptedStore<Store>()
const time = useEncryptedStore<Store>((store) => store.time)
const setStore = useEncryptedStore<Store>((_, setStore) => setStore)

// Another possible usage
const { store, setStore } = useEncryptedStore<Store>()
const { time, setStore } = useEncryptedStore<Store>((store, setStore) => ({
	time: store.time,
	setStore,
}))

About

Encrypted storage for Electron applications.

Topics

Resources

License

Stars

Watchers

Forks