Simple data persistence for your Electron app - save and load user settings, app state, cache, etc
Another electron-store, minimal fork of conf, with more features.
electron-conf is a fork of conf (behind electron-store). What we try to achieve in this library, is to eliminate some dependencies and features that our target users don't need, and is designed only for Electron.
- ✅ Minimal and simple
- ✅ Read data form disk once, ~100x faster
- ✅ Simpler migration strategy
- ✅ Safer to use it in Electron renderer (no nodeIntegration)
- ✅ Written in TypeScript, and support CommonJS and ESM. For Electron 15.x and higher.
- ❌ No watch
- ❌ No encryption
If you need features like watch or encryption, electron-store is a better choice for you.
$ npm install electron-conf
import { Conf } from 'electron-conf/main'
const conf = new Conf()
conf.set('foo', '🌈')
console.log(conf.get('foo')) // => 🌈
// Use dot-notation to access nested properties
conf.set('a.b', true)
console.log(conf.get('a')) // => {b: true}
conf.delete('foo')
console.log(conf.get('foo')) // => undefined
- Register a listener in main process, so that you can use it in the renderer process.
import { Conf } from 'electron-conf/main'
const conf = new Conf()
conf.registerRendererListener()
- Expose the
Conf
API.
You can expose it in the specified preload script:
import { exposeConf } from 'electron-conf/preload'
exposeConf()
Or, you can expose it globally in the main process for all renderer processes:
import { useConf } from 'electron-conf/main'
useConf()
- Use it in the renderer process
import { Conf } from 'electron-conf/renderer'
const conf = new Conf()
await conf.set('foo', 1)
Note
Use the same way as the main process. The difference is that all APIs are promise-based.
return a new instance.
Warning
It does not support multiple instances reading and writing the same configuration file.
Note
Conf
for the renderer process, only supports the name
option.
- Type:
string
- Default:
app.getPath('userData')
The directory for storing your app's configuration file.
- Type:
string
- Default:
config
Configuration file name without extension.
- Type:
string
- Default:
.json
Configuration file extension.
- Type:
object
Default config used if there are no existing config.
- Type:
Serializer
Provides functionality to serialize object types to UTF-8 strings and to deserialize UTF-8 strings into object types.
By default, JSON.stringify
is used for serialization and JSON.parse
is used for deserialization.
You would usually not need this, but it could be useful if you want to use a format other than JSON.
Type Signature
interface Serializer<T> {
/**
* Deserialize the config object from a UTF-8 string when reading the config file.
* @param raw UTF-8 encoded string.
*/
read: (raw: string) => T
/**
* Serialize the config object to a UTF-8 string when writing the config file.
* @param value The config object.
*/
write: (value: T) => string
}
- Type: JSONSchema
JSON Schema to validate your config data.
Under the hood, we use the ajv JSON Schema validator to validate config data.
You should define your schema as an object where each key is the name of your data's property and each value is a JSON schema used to validate that property.
import { Conf } from 'electron-conf/main'
const schema = {
type: 'object',
properties: {
foo: {
type: 'string',
maxLength: 10,
nullable: true
}
}
}
const conf = new Conf({ schema })
- type:
Migration[]
You can customize versions and perform operations to migrate configurations. When instantiated, it will be compared with the version number of the configuration file and a higher version migration operation will be performed.
Note: The migration version must be greater than 0
. A new version is defined on each migration and is incremented on the previous version.
import { Conf } from 'electron-conf/main'
const migrations = [
{
version: 1,
hook: (conf, version): void => {
conf.set('foo', 'a')
console.log(`migrate from ${version} to 1`) // migrate from 0 to 1
}
},
{
version: 2,
hook: (conf, version): void => {
conf.set('foo', 'b')
console.log(`migrate from ${version} to 2`) // migrate from 1 to 2
}
}
]
const conf = new Conf({ migrations })
Type Signature
type Migration<T extends Record<string, any>> = {
/**
* Migration version. The initial version must be greater than `0`. A new
* version is defined on each migration and is incremented on the previous version.
*/
version: number
/**
* Migration hook. You can perform operations to update your configuration.
* @param instance config instance.
* @param currentVersion current version.
*/
hook: (instance: BaseConf<T>, currentVersion: number) => void
}
You can use dot-notation in a key to access nested properties.
The instance is iterable
so you can use it directly in a for…of
loop.
Note
All methods in renderer are promise-based.
Get an item or defaultValue if the item does not exist.
Set an item.
Set an item or multiple items at once.
conf.set({ foo: 'boo', bar: { baz: 1 } })
Reset items to their default values, as defined by the defaults or schema option.
Check if an item exists.
Delete an item.
Delete all items.
callback
:(newValue, oldValue) => {}
Watches the given key
, calling callback
on any changes.
When a key is first set oldValue
will be undefined
, and when a key is deleted newValue
will be undefined
.
Returns a function which you can use to unsubscribe:
const unsubscribe = conf.onDidChange(key, callback)
unsubscribe()
Tip
Not available in renderer
callback
:(newValue, oldValue) => {}
Watches the whole config object, calling callback
on any changes.
oldValue
and newValue
will be the config object before and after the change, respectively. You must compare oldValue
to newValue
to find out what changed.
Returns a function which you can use to unsubscribe:
const unsubscribe = store.onDidAnyChange(callback)
unsubscribe()
Tip
Not available in renderer
Get the configuration file path.
Tip
Not available in renderer
Conf, simple config handling for your app or module.