Store Plugin Introduction

An overview of the Tauri Store Plugin covering what it is, the problems it solves, and its core concepts

Tauri applications often need to remember things between launches—user preferences, window positions, or the last opened file. The Store Plugin gives you a simple, file-backed key-value store that does exactly that, without requiring a full database. Installation follows the same plugin install steps as every other official plugin.

What Is the Store Plugin?

It is a Tauri plugin that provides a persistent key-value store. You can think of it as a programmatic way to read and write a JSON file on disk. Both the JavaScript frontend and the Rust backend can read from and write to the same store, making it a straightforward shared state mechanism.

The store lives as a plain .json file in the app’s local data directory. You can load it on demand, save it manually, or let the plugin handle automatic saves when the app exits gracefully. Every operation—reading, writing, clearing—is asynchronous because it involves filesystem access.

Async by nature:

All interactions with the store return promises (in JS) or produce Result types (in Rust). Disk I/O is never instant, so the API forces you to handle this explicitly.

Why a Persistent Key-Value Store Exists

Desktop applications have configuration that must survive restarts. A user who sets a dark theme expects it to be dark the next time they open the app. Without a persistence layer, every setting resets to default on each launch.

Before the Store Plugin, developers either wrote their own file management logic, used a lightweight embedded database, or relied on the operating system’s configuration APIs. Those options add complexity or lock you into platform-specific code. The Store Plugin solves this with a cross-platform, consistent interface that works identically on Windows, macOS, Linux, Android, and iOS.

How It Works at a High Level

The plugin registers itself with Tauri during application startup. Once initialized, it exposes two paths to the same store instance:

  • From JavaScript: You import load (or LazyStore) and get a store handle that talks to the Rust backend via Tauri commands.
  • From Rust: You call app.store("filename.json") to obtain a Store handle directly, using the plugin’s Rust API.

Both handles point to the same underlying store collection. If JavaScript writes a key, Rust can immediately read it (and vice versa), as long as they reference the same file path.

The store file itself is a standard JSON document. When you call set, the plugin updates the in-memory representation. Depending on the autoSave option, changes are written to disk after a short debounce (default 100ms) or only when save() is called explicitly. On a graceful application exit, the store automatically flushes to disk.

Cross-environment consistency:

The Rust and JavaScript sides share the same store collection managed by Tauri’s resource table. Using the same filename on both sides gives you access to the identical data without extra synchronization code.

Common Use Cases

The Store Plugin is not a general-purpose database. It excels at small, frequently accessed configuration data. Here are the most common scenarios:

  • User preferences: theme, language, font size, toggle states.
  • Application state snapshots: last opened file path, last selected tab index, sidebar width.
  • Feature flags or onboarding progress: whether the user has seen the welcome walkthrough.
  • Simple caches: API response data that changes rarely and can be expired manually.

Not a database replacement:

The store is designed for lightweight configuration. Storing large datasets or complex relational data will lead to performance problems and JSON parsing overhead. For structured data with query needs, use the SQL Plugin.

A First Look at the API

Below is the smallest complete interaction with the Store Plugin from both JavaScript and Rust. The example creates (or loads) a store, writes a value, and reads it back.

import { load } from '@tauri-apps/plugin-store';
// Load (or create) a store file named "config.json"
const store = await load('config.json', { autoSave: false });
// Write a key with a typed object
await store.set('preferences', { theme: 'dark', fontSize: 14 });
// Read it back with a type hint
const prefs = await store.get<{ theme: string; fontSize: number }>('preferences');
console.log(prefs); // { theme: 'dark', fontSize: 14 }
// Explicit save — the file is written only when you call this
await store.save();

A few things to notice in both examples: the store is identified by a filename, the values are JSON-serializable, and reading from the store is always asynchronous. In JavaScript, you get a typed result via generics; in Rust, you work with serde_json::Value. Both sides can point at the same file and see each other’s changes.

Do not store secrets in plain JSON:

The store file is unencrypted. Anyone with filesystem access can read its contents. For passwords, API tokens, or cryptographic keys, use Tauri's Stronghold plugin or the OS keychain.

Where This Fits Among Tauri’s State Options

The Store Plugin is one piece of a larger state management picture in Tauri. Understanding where it sits helps you avoid picking the wrong tool:

  • React state (useState, useReducer, context): transient, lost when the app closes. Perfect for UI-only concerns.
  • Tauri’s managed state (app.manage()): Rust-side application state that lives in memory for the session duration, accessible from commands but not persisted.
  • Store Plugin: persistent, file-backed key-value store shared between JS and Rust. Ideal for configuration and small data that must survive restarts.
  • SQL Plugin: full relational database (SQLite) for structured, query-heavy data.
  • Stronghold Plugin: encrypted secrets storage for credentials.

For most applications, you’ll use React state for temporary UI data, the Store Plugin for user preferences, and possibly SQL for complex local data.

Store load is not guaranteed to succeed:

When a store file doesn’t exist yet, the plugin creates it on the first write. However, if the file is corrupted (malformed JSON), loading will fail. Always handle load errors gracefully rather than unwrapping.

Summary

The Store Plugin rewards a small upfront understanding: once you know how to load a file and set a key, you can add persistent settings to any Tauri app in minutes.