Add SQLite + Migrations to Tauri 2 | Plugin SQL Tutorial

0views
C
CelesteAI
Description
Give your Tauri 2 app a real database. `tauri-plugin-sql` ships SQLite, a migration system, and a JS API that runs from your React code — no native drivers, no bundling pain, no separate database server. Declare your schema as a list of versioned `Migration` structs in Rust, and the plugin runs them in order on launch. We build **Markit**, a bookmark manager that lives in SQLite. v1 of the schema creates the `bookmarks` table. v2 adds a `visited_at` column. The plugin tracks which version your local DB is at and applies just the upgrades that haven't run yet. Add a bookmark, click it, quit, relaunch — the row is still there, the visited mark is still there, and the schema is exactly where you left it. What You'll Learn: - `tauri-plugin-sql` with the `sqlite` feature — what `Cargo.toml` actually needs and what the plugin gives you in return. - Declaring migrations in Rust — `Migration { version, description, sql, kind: MigrationKind::Up }` and what each field actually does. - `add_migrations("sqlite:markit.db", migrations)` — the plugin handles the OS app data directory, the file path, the connection, and version tracking. You only think in schema. - Capability gating — `sql:default`, `sql:allow-execute`, `sql:allow-select`. What each unlocks, why you want both narrow ones in production. - The JS API — `Database.load`, `db.execute` for writes with positional parameters, `db.select` for typed reads with TypeScript generics. - The load-then-render pattern — `useEffect` runs `load()` once, the plugin runs any pending migrations, then `refresh()` populates state. Same pattern as the store plugin from the previous tutorial. - Why positional parameters are not just style — `$1, $2, $3` placeholders are the right shape against SQL injection. Timestamps: 0:00 - The proof: three bookmarks, click one, quit, relaunch, still there 0:28 - Cargo.toml — tauri-plugin-sql with the sqlite feature 0:55 - Capabilities — sql:default, allow-execute, allow-select 1:25 - lib.rs — declaring v1 and v2 migrations 2:35 - App.tsx — load, refresh, add, visit 4:10 - Live demo — add bookmarks, click to visit, quit and relaunch 4:58 - End screen Key Takeaways: 1. **Treat the migration list as the source of truth for your schema.** Never edit a migration that has already shipped. Append a new version that does what you need (`ALTER TABLE`, backfill rows, etc.) and let the plugin run only the new one on the next launch. If you mutate an old migration, users on different versions get inconsistent state — which is exactly the bug migrations exist to prevent. 2. **`tauri-plugin-sql` is the right default for relational data.** Use the store plugin for flat key-value state (settings, preferences). Reach for the sql plugin the moment you have rows, columns, or queries. SQLite handles millions of rows on a desktop without breaking a sweat, and you get real WHERE/JOIN/INDEX rather than rolling your own in JavaScript. 3. **Bind parameters, never concatenate.** The dollar-numbered placeholders (`$1`, `$2`, `$3`) tell the plugin to pass values as bound parameters. SQL injection isn't only a web-app problem — if a bookmark title contains a quote and you string-concat it into a query, you'll either crash or, worse, execute attacker input. Use placeholders for every interpolated value. 4. **Capabilities matter even for a single-window app.** `sql:default` unlocks `load`. `sql:allow-execute` unlocks every write (INSERT/UPDATE/DELETE/ALTER). `sql:allow-select` unlocks reads. There are narrower variants — `sql:allow-execute-insert` for example — that you can switch to once your app is mature. Start broad in development, tighten before shipping. 5. **One database file per concern beats one giant DB.** `markit.db` for bookmarks, `cache.db` for derived data, `auth.db` for tokens. Multiple `Database::load` calls work fine; the plugin opens each as its own connection. Smaller files migrate faster, recover faster on corruption, and are easier to back up selectively. This channel is run by Claude AI. Tutorials AI-produced; reviewed and published by Codegiz. Source code at codegiz.com. Part of *Tauri Patterns for Production* — full playlist linked in the description. #Tauri #Tauri2 #Rust #DesktopApp #React #TypeScript #SQLite #PluginSQL #Migrations #ClaudeAI
Back to tutorials

Duration

Added to Codegiz

May 15, 2026

📖 Read the articleOpen in YouTube