Skip to main content
The schema layer is where you describe the shape of your configuration data. You call defineConfig() once with a plain object, use keyring() to mark sensitive fields, and use optional() to mark fields that may be absent. TypeScript infers all value types from the schema automatically — no manual type annotations required.

defineConfig(schema)

Validates a schema object at runtime and returns it unchanged. The return value is used for TypeScript inference when constructing a Configurate instance. Signature:
function defineConfig<S extends SchemaObject>(schema: S): S
defineConfig() checks that every keyring() ID in the schema is unique. It throws a runtime error if any IDs are duplicated.
schema
SchemaObject
required
A plain object where each key maps to a schema value: String, Number, Boolean, a keyring() field, an optional() field, a nested object, or a single-element array.
Returns: S — the same schema object, unchanged.
import { defineConfig, keyring, optional } from "tauri-plugin-configurate-api";

const schema = defineConfig({
  theme: String,
  fontSize: optional(Number),
  apiKey: keyring(String, { id: "api-key" }),
  database: {
    host: String,
    port: Number,
    password: keyring(String, { id: "db-password" }),
  },
  tags: [String],
});
Array schemas are supported. Use a single-element tuple to declare the element type:
const schema = defineConfig({
  tags: [String],
  timetable: [
    {
      time: String,
      token: keyring(String, { id: "timetable-token" }),
    },
  ],
});

keyring(typeCtor, opts)

Marks a schema field as keyring-protected. At runtime, the value is stored in the OS keyring (Windows Credential Manager, macOS Keychain, or Linux Secret Service) instead of being written to disk. When loaded without unlocking, the field appears as null. Signature:
function keyring<T, Id extends string>(
  typeCtor: StringConstructor | NumberConstructor | BooleanConstructor,
  opts: { id: Id }
): KeyringField<T, Id>
typeCtor
StringConstructor | NumberConstructor | BooleanConstructor
required
The value type constructor: String, Number, or Boolean.
opts.id
string
required
A unique identifier for this keyring field within the schema. Used as part of the OS keyring user string ({account}/{id}). Must not be empty and must not contain /.
Returns: KeyringField<T, Id>
import { keyring } from "tauri-plugin-configurate-api";

// String secret
keyring(String, { id: "api-key" })

// Number secret
keyring(Number, { id: "port-secret" })

// Optional keyring field
optional(keyring(String, { id: "opt-secret" }))
Every keyring() call in a single schema must use a unique id. defineConfig() validates this at runtime and throws if any IDs are duplicated. IDs must not contain / — it is used as a path separator in the keyring user string.

optional(schema)

Marks a schema field as optional. An optional field may be absent from the stored config object. Validation (validateOnRead / validateOnWrite) does not fail when the field is missing. The inferred TypeScript type includes undefined. Signature:
function optional<V extends OptionalInner>(schema: V): OptionalField<V>
schema
PrimitiveConstructor | KeyringField | SchemaObject | SchemaArray
required
The schema value to make optional. Can wrap primitives, keyring fields, nested objects, or arrays.
Returns: OptionalField<V>
import { optional, keyring } from "tauri-plugin-configurate-api";

optional(Number)                                    // optional number
optional(keyring(String, { id: "opt-secret" }))     // optional keyring string
optional({ host: String, port: Number })            // optional nested object
optional([String])                                  // optional array of strings

Schema value types

TypeTypeScript typeDescription
StringstringRequired string field
NumbernumberRequired number field (must be finite)
BooleanbooleanRequired boolean field
keyring(Type, { id })string | number | booleanOS keyring-protected field; appears as null when locked
optional(Type)T | undefinedOptional field; may be absent from the config object
{ ... }objectNested object with its own schema keys
[Type]Type[]Array of a single element type

Type utilities: InferLocked and InferUnlocked

These generic utility types derive the full TypeScript type of your config data from a schema.

InferUnlocked<S>

Infers the config type with keyring fields as their actual runtime types. Use this type when you have unlocked data (returned from .unlock(keyringOpts)).
import type { InferUnlocked } from "tauri-plugin-configurate-api";

const schema = defineConfig({
  theme: String,
  password: keyring(String, { id: "pw" }),
});

type Config = InferUnlocked<typeof schema>;
// { theme: string; password: string }

InferLocked<S>

Infers the config type with keyring fields replaced by null. Use this type when you have locked data (returned from .run() without unlocking).
import type { InferLocked } from "tauri-plugin-configurate-api";

const schema = defineConfig({
  theme: String,
  password: keyring(String, { id: "pw" }),
});

type LockedConfig = InferLocked<typeof schema>;
// { theme: string; password: null }

Complete schema example

src/lib/schema.ts
import { defineConfig, keyring, optional } from "tauri-plugin-configurate-api";
import type { InferUnlocked, InferLocked } from "tauri-plugin-configurate-api";

export const appSchema = defineConfig({
  theme: String,
  language: String,
  fontSize: optional(Number),
  database: {
    host: String,
    port: Number,
    password: keyring(String, { id: "db-password" }),
  },
  tags: [String],
  proxy: optional({
    host: String,
    port: Number,
  }),
});

// Full type — keyring fields are their actual types
export type AppConfig = InferUnlocked<typeof appSchema>;

// Locked type — keyring fields are null
export type LockedAppConfig = InferLocked<typeof appSchema>;

Build docs developers (and LLMs) love