Skip to main content
The Configurate<S> class is the central object you interact with in tauri-plugin-configurate. You instantiate it once per configuration target — providing a schema, a file name, a base directory, and a storage provider — and then call its methods to create, load, save, patch, reset, export, import, validate, and watch your config. The generic parameter S is the schema type returned by defineConfig(), which flows through every method signature to give you end-to-end type safety.

Constructor

new Configurate<S>(opts: ConfigurateInit<S>)
schema
S
required
Schema object returned by defineConfig(). The type parameter S is inferred from this value and propagates through all method return types.
fileName
string
required
Name of the config file, including its extension (for example "app.json" or "settings.toml"). Must be a single filename — forward slashes (/) and back slashes (\) are not allowed. The values "." and ".." are also rejected.
baseDir
BaseDirectory
required
A Tauri BaseDirectory enum value that determines the root location on disk. Import BaseDirectory from @tauri-apps/api/path or from tauri-plugin-configurate-api, which re-exports it.
provider
ConfigurateProvider
required
A storage provider returned by one of JsonProvider(), YmlProvider(), TomlProvider(), or BinaryProvider(). The provider controls the file format and optional encryption.
options
ConfiguratePathOptions
Optional path customization object.
validation
SchemaValidationOptions
Controls when schema validation runs. All three fields default to false.
defaults
Partial<InferUnlocked<S>>
Default values merged into loaded data when keys are absent from the stored file. Defaults are applied after migrations run.
version
number
Current schema version number. When provided, tauri-plugin-configurate stores a __configurate_version__ field alongside your data and uses it to detect when migrations are needed.
migrations
MigrationStep[]
Ordered list of migration steps applied when loading data whose stored version is older than version. Each step describes a single version increment. Migrations run automatically on load(); if any migration runs, the migrated data is auto-saved back to storage.
backup
boolean
When true, rolling backup files (.bak1, .bak2, .bak3) are written before each destructive operation and removed automatically when the application exits. Defaults to false.

Quick-start example

import { Configurate, defineConfig, JsonProvider } from "tauri-plugin-configurate-api";
import { BaseDirectory } from "@tauri-apps/api/path";

const schema = defineConfig({
  theme: String,
  fontSize: Number,
});

const config = new Configurate({
  schema,
  fileName: "app.json",
  baseDir: BaseDirectory.AppConfig,
  provider: JsonProvider(),
  defaults: { theme: "light", fontSize: 14 },
  validation: { validateOnWrite: true },
});

Instance Methods

create(data)

Creates a new config file on disk and returns a lazy builder you chain before executing.
create(data: InferUnlocked<S>): LazyConfigEntry<S>
data
InferUnlocked<S>
required
Full config object whose shape must match the schema. All required fields must be present.
returns
LazyConfigEntry<S>
A chainable builder. Call .run() to execute, .lock(opts).run() to also store keyring fields, or .unlock(opts) to store keyring fields and immediately return the unlocked result.
// No keyring fields in schema
const locked = await config.create({ theme: "dark", fontSize: 16 }).run();

// Schema has keyring fields — use .lock() before .run()
const locked = await config
  .create({ theme: "dark", apiKey: "secret" })
  .lock({ service: "my-app", account: "default" })
  .run();

// Or get unlocked data back immediately
const unlocked = await config
  .create({ theme: "dark", apiKey: "secret" })
  .unlock({ service: "my-app", account: "default" });

load()

Loads an existing config file from disk. Keyring-protected fields come back as null in the locked result unless you call .unlock().
load(): LazyConfigEntry<S>
returns
LazyConfigEntry<S>
A chainable builder. Chain .run() for a locked result, or .unlock(opts) to populate keyring fields.
// Load with keyring fields as null
const locked = await config.load().run();
console.log(locked.data.apiKey); // null

// Load and populate keyring fields
const unlocked = await config.load().unlock({ service: "my-app", account: "default" });
console.log(unlocked.data.apiKey); // "secret"

// Unlock from an already-loaded LockedConfig
const unlocked2 = await locked.unlock({ service: "my-app", account: "default" });
When defaults or migrations are configured, they are applied automatically during load() before returning data to you.

save(data)

Fully overwrites the existing config file with the provided data. Every field is replaced; this is not a merge operation.
save(data: InferUnlocked<S>): LazyConfigEntry<S>
data
InferUnlocked<S>
required
Complete replacement data for the config file.
returns
LazyConfigEntry<S>
A chainable builder with .run(), .lock(opts).run(), and .unlock(opts).
await config
  .save({ theme: "light", fontSize: 12, apiKey: "new-secret" })
  .lock({ service: "my-app", account: "default" })
  .run();

patch(partial)

Deep-merges a partial object into the existing config. Only keys you supply are updated; all other keys remain unchanged. Uses JSON Merge Patch semantics (RFC 7396): setting a key to null writes null to that field.
patch(partial: Partial<InferUnlocked<S>>): LazyPatchEntry<S>
partial
Partial<InferUnlocked<S>>
required
Partial config object. Only present keys are written.
returns
LazyPatchEntry<S>
A chainable builder with .run(), .lock(opts).run(), .createIfMissing(), and .unlock(opts).
// Update only the theme; fontSize is untouched
const patched = await config.patch({ theme: "dark" }).run();

// With keyring
const patched = await config
  .patch({ apiKey: "rotated-secret" })
  .lock({ service: "my-app", account: "default" })
  .run();

// Create the file if it does not already exist
const patched = await config
  .patch({ theme: "dark" })
  .createIfMissing()
  .run();

// Patch and immediately unlock keyring fields
const unlocked = await config
  .patch({ theme: "dark" })
  .unlock({ service: "my-app", account: "default" });
By default patch() throws if the config file does not exist. Chain .createIfMissing() to create it from the partial data instead.

reset(data)

Deletes the existing config and re-creates it from scratch with the provided data. Equivalent to delete() followed by create(), but performed atomically on the Rust side.
reset(data: InferUnlocked<S>): LazyConfigEntry<S>
data
InferUnlocked<S>
required
Full replacement data for the re-created config.
returns
LazyConfigEntry<S>
A chainable builder with .run(), .lock(opts).run(), and .unlock(opts).
const locked = await config
  .reset({ theme: "light", fontSize: 14, apiKey: "fresh-key" })
  .lock({ service: "my-app", account: "default" })
  .run();

// Or unlock immediately
const unlocked = await config
  .reset({ theme: "light", fontSize: 14, apiKey: "fresh-key" })
  .unlock({ service: "my-app", account: "default" });

delete(keyringOpts?)

Deletes the config file from disk. If the schema has keyring fields and you supply keyringOpts, the corresponding keyring entries are removed from the OS keyring as well.
delete(keyringOpts?: KeyringOptions | null): Promise<void>
keyringOpts
KeyringOptions
When provided, removes associated keyring entries. Omit if your schema has no keyring() fields, or if you intentionally want to leave keyring entries intact.
returns
Promise<void>
// Without keyring cleanup
await config.delete();

// With keyring cleanup
await config.delete({ service: "my-app", account: "default" });

exists()

Checks whether the config file currently exists on disk.
exists(): Promise<boolean>
returns
Promise<boolean>
true if the file exists, false otherwise.
const present = await config.exists();
if (!present) {
  await config.create({ theme: "light", fontSize: 14 }).run();
}

list()

Lists config file names in the resolved root directory. For file-based providers, files are filtered to the provider’s extension; .bak* and temporary files are excluded. For SQLite, all config_key values in the table are returned.
list(): Promise<string[]>
returns
Promise<string[]>
Array of file names (including their extension) found in the root directory.
const files = await config.list();
// ["app.json", "settings.json", "user.json"]

exportAs(format, keyringOpts?)

Serializes the current config data to a string in the requested format. Useful for backup, clipboard sharing, or cross-format migration.
exportAs(format: "json" | "yml" | "toml", keyringOpts?: KeyringOptions | null): Promise<string>
format
"json" | "yml" | "toml"
required
Target serialization format for the exported string.
keyringOpts
KeyringOptions
When provided, keyring fields are unlocked and included in the export. Omit to export with keyring fields absent.
returns
Promise<string>
Serialized config string in the requested format.
const json = await config.exportAs("json");
const yaml = await config.exportAs("yml");
const toml = await config.exportAs("toml");

// Include secrets in the export
const yamlWithSecrets = await config.exportAs("yml", {
  service: "my-app",
  account: "default",
});

importFrom(content, format, keyringOpts?)

Parses a serialized config string and writes it to storage, replacing the current config entirely.
importFrom(content: string, format: "json" | "yml" | "toml", keyringOpts?: KeyringOptions | null): Promise<void>
content
string
required
Serialized config string to import.
format
"json" | "yml" | "toml"
required
Format of the content string.
keyringOpts
KeyringOptions
Required when the schema includes keyring() fields and the import data contains values for those fields.
returns
Promise<void>
await config.importFrom('{"theme":"dark","fontSize":16}', "json");
await config.importFrom("theme: dark\n", "yml");
await config.importFrom('theme = "dark"\n', "toml", {
  service: "my-app",
  account: "default",
});

validate(data)

Validates a complete config object against the schema without writing anything to disk. Throws a descriptive error if validation fails.
validate(data: InferUnlocked<S>): void
data
InferUnlocked<S>
required
Full config data to validate.
try {
  config.validate({ theme: "dark", fontSize: 16 });
  console.log("Valid!");
} catch (e) {
  console.error(e.message);
}

validatePartial(data)

Validates a partial config object against the schema. Only keys that are present in data are checked; absent keys do not cause validation to fail.
validatePartial(data: Partial<InferUnlocked<S>>): void
data
Partial<InferUnlocked<S>>
required
Partial config data to validate.
config.validatePartial({ theme: "dark" });   // OK — only checks "theme"
config.validatePartial({ theme: 123 });      // throws — wrong type

onChange(callback)

Registers a callback that fires whenever this config is changed by any operation (create, save, patch, delete, reset, import). Changes originating from external processes are reported by watchExternal() instead.
onChange(callback: (event: ConfigChangeEvent) => void): Promise<() => void>
callback
(event: ConfigChangeEvent) => void
required
Function invoked with a ConfigChangeEvent whenever the config changes.
returns
Promise<() => void>
A synchronous unlisten function. Call it when you no longer need the listener to avoid memory leaks.
const unlisten = await config.onChange((event) => {
  console.log(`${event.operation} on ${event.fileName}`);
});

// Later, when the component is unmounted:
unlisten();

watchExternal(callback)

Watches the config file for changes made by processes outside your application. Only available for file-based providers; calling this with a non-file provider throws an error.
watchExternal(callback: (event: ConfigChangeEvent) => void): Promise<() => Promise<void>>
callback
(event: ConfigChangeEvent) => void
required
Function invoked when an external change is detected. The event.operation value will be "external_change".
returns
Promise<() => Promise<void>>
An async stop function. Await it to unregister the file watcher on the Rust side and remove the JavaScript listener.
const stopWatching = await config.watchExternal((event) => {
  console.log("File changed externally — reloading…");
  // reload your data here
});

// Later:
await stopWatching();
watchExternal() is only supported for file-based providers (JSON, YAML, TOML, Binary). It throws for SQLite.

Static Methods

The three static batch methods let you load, save, or patch multiple configs in a single IPC round-trip, significantly reducing overhead when you manage several config files.

Configurate.loadAll(entries)

Loads multiple configs in one IPC call. Post-load processing (defaults, migrations) is applied to each entry individually after the batch returns.
static loadAll(entries: LoadAllEntry[]): LoadAllRunner
entries
LoadAllEntry[]
required
Array of { id: string; config: Configurate<any> } objects. Each id must be unique within the batch.
returns
LoadAllRunner
A builder with .unlock(id, opts), .unlockAll(opts), and .run().
const result = await Configurate.loadAll([
  { id: "app", config: appConfig },
  { id: "secret", config: secretConfig },
])
  .unlock("secret", { service: "my-app", account: "default" })
  // .unlockAll({ service: "my-app", account: "default" }) — or unlock everything
  .run();

if (result.results.app.ok) {
  console.log(result.results.app.data);
}
if (!result.results.secret.ok) {
  console.error(result.results.secret.error.message);
}

Configurate.saveAll(entries)

Saves multiple configs in one IPC call.
static saveAll(entries: SaveAllEntry[]): SaveAllRunner
entries
SaveAllEntry[]
required
Array of { id: string; config: Configurate<any>; data: unknown } objects.
returns
SaveAllRunner
A builder with .lock(id, opts), .lockAll(opts), and .run().
const result = await Configurate.saveAll([
  { id: "app", config: appConfig, data: { theme: "dark", fontSize: 14 } },
  { id: "secret", config: secretConfig, data: { token: "tok" } },
])
  .lock("secret", { service: "my-app", account: "default" })
  // .lockAll({ service: "my-app", account: "default" }) — or lock everything
  .run();

Configurate.patchAll(entries)

Patches multiple configs in one IPC call.
static patchAll(entries: PatchAllEntry[]): PatchAllRunner
entries
PatchAllEntry[]
required
Array of { id: string; config: Configurate<any>; data: unknown } objects where data is a partial config.
returns
PatchAllRunner
A builder with .lock(id, opts), .lockAll(opts), and .run().
const result = await Configurate.patchAll([
  { id: "app", config: appConfig, data: { theme: "light" } },
])
  .lock("app", { service: "my-app", account: "default" })
  .run();
Batch operations are ideal at application startup when you need to load several config files before rendering the UI. One IPC call replaces N individual calls and reduces perceived latency.