C.W.K.
Stream
Lesson 07 of 07 · published

Writing Your Own Plugin (a Touch)

~12 min · tauri, plugins, authoring, architecture

Level 0Web Tourist
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Most of the time, the answer to 'should this be a plugin?' is no — it should be a module. Know the difference before you reach for the bigger hammer."

When NOT to Write a Plugin

If functionality only your one app uses, it does not need to be a plugin. Put it in a Rust module (commands.rs, storage.rs) and register the commands normally — that's simpler, has less ceremony, and is exactly what a healthy Tauri core looks like (Cinder's split modules are this). A plugin adds packaging overhead; pay it only when you get something back.

When a Plugin Earns Its Keep

Write a plugin when you want to reuse a feature across multiple apps, distribute it for others to use, or bundle native mobile code (Swift/Kotlin) behind a unified API. A plugin packages Rust commands, a JS API, permission definitions, and optional mobile native code into one installable unit — the same shape as the official plugins you've been consuming. The moment 'I want this in my next app too' is true, a plugin is the right container.

The Shape of a Plugin

At its core a plugin is a tauri::plugin::Builder with a name, an invoke handler for its commands, and a permission set. The CLI scaffolds the whole structure for you with tauri plugin new (or the create command), generating the Rust crate, the JS package, and the permissions skeleton. You fill in commands the same way you write app commands — the plugin wrapper is what makes them portable and grant-controlled.

Code

A minimal plugin skeleton·rust
use tauri::{plugin::{Builder, TauriPlugin}, Runtime};

#[tauri::command]
fn do_thing() -> String { "from the plugin".into() }

// A plugin is a named Builder bundling its own commands.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![do_thing])
        .build()
}

// An app then uses it exactly like an official plugin:
//   .plugin(my_plugin::init())
Let the CLI generate the structure·bash
# Scaffold a full plugin (Rust crate + JS package + permissions).
npm create tauri-plugin my-plugin
# or, inside a project:
npm run tauri plugin new my-plugin

External links

Exercise

Decide-and-justify: take three features (e.g. 'my app's note storage', 'a reusable QR-code generator', 'a wrapper around a mobile-only native API') and label each 'module' or 'plugin', with one sentence why. Then, optionally, run tauri plugin new and read the generated structure to see what a plugin actually packages. The judgment of module-vs-plugin is the real lesson.
Hint
App-only storage → module. Reusable-across-apps generator → plugin. Mobile native API wrapper → plugin (plugins are how you bundle Swift/Kotlin). 'Will another app or another developer use this?' is the deciding question.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.