"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.