Install
$ agentstack add skill-impertio-studio-tauri-2-claude-skill-package-tauri-syntax-menu ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
tauri-syntax-menu
Quick Reference
Menu Item Types (Rust)
| Type | Builder | Purpose | |------|---------|---------| | MenuItem | MenuItemBuilder | Basic clickable text item | | CheckMenuItem | CheckMenuItemBuilder | Toggleable checkbox item | | IconMenuItem | IconMenuItemBuilder | Item with icon | | PredefinedMenuItem | -- | OS-native standard items | | Submenu | SubmenuBuilder | Nested menu container |
PredefinedMenuItem Types (both Rust and JS)
Platform-standard items: About, Hide, HideOthers, ShowAll, CloseWindow, Quit, Copy, Cut, Paste, SelectAll, Undo, Redo, Minimize, Zoom, Separator, Fullscreen, Services, BringAllToFront.
SubmenuBuilder Convenience Methods (Rust)
| Method | Creates | |--------|---------| | .text(id, text) | MenuItem with ID and text | | .separator() | Menu separator line | | .quit() | PredefinedMenuItem::Quit | | .undo() | PredefinedMenuItem::Undo | | .redo() | PredefinedMenuItem::Redo | | .cut() | PredefinedMenuItem::Cut | | .copy() | PredefinedMenuItem::Copy | | .paste() | PredefinedMenuItem::Paste | | .select_all() | PredefinedMenuItem::SelectAll |
TrayIconBuilder Key Methods (Rust)
| Method | Signature | Description | |--------|-----------|-------------| | new() | () -> Self | Create builder | | with_id(id) | (impl Into) -> Self | Set custom ID | | icon(image) | (Image) -> Self | Set tray icon | | tooltip(text) | (impl Into) -> Self | Set tooltip | | title(text) | (impl Into) -> Self | Set title | | menu(menu) | (&Menu) -> Self | Attach context menu | | show_menu_on_left_click(bool) | (bool) -> Self | Show menu on left click (default: true) | | icon_as_template(bool) | (bool) -> Self | macOS template icon | | on_menu_event(F) | (F) -> Self | Menu click handler | | on_tray_icon_event(F) | (F) -> Self | Tray icon click handler | | build(manager) | (impl Manager) -> Result | Build tray icon |
JS Menu Classes
| Class | Import | Description | |-------|--------|-------------| | Menu | @tauri-apps/api/menu | Menu container | | MenuItem | @tauri-apps/api/menu | Clickable text item | | Submenu | @tauri-apps/api/menu | Nested menu | | CheckMenuItem | @tauri-apps/api/menu | Toggleable item | | PredefinedMenuItem | @tauri-apps/api/menu | OS-standard item | | TrayIcon | @tauri-apps/api/tray | System tray icon |
JS TrayIcon Event Types
| Event Type | Description | |------------|-------------| | Click | Tray icon clicked | | DoubleClick | Tray icon double-clicked | | Enter | Cursor entered tray icon | | Move | Cursor moved over tray icon | | Leave | Cursor left tray icon |
JS TrayIcon Mouse Buttons
Left, Right, Middle
Critical Warnings
NEVER call Builder::on_menu_event() in Tauri 2 -- it was removed. Use App::on_menu_event() or the builder .on_menu_event() method instead.
NEVER use Tauri v1 menu type names (CustomMenuItem, SystemTray, MenuItem for predefined items) -- they are renamed in v2.
ALWAYS call .build() on MenuBuilder and SubmenuBuilder -- forgetting .build() produces a builder, not a usable menu.
ALWAYS match menu event IDs as strings using event.id().as_ref() in Rust -- menu item IDs are compared as string references, not typed enums.
ALWAYS use Menu.new() (not new Menu()) in JavaScript -- menu items are created via async factory methods.
Essential Patterns
Pattern 1: Application Menu (Rust)
use tauri::menu::{MenuBuilder, SubmenuBuilder, PredefinedMenuItem};
tauri::Builder::default()
.menu(|app| {
let file_menu = SubmenuBuilder::new(app, "File")
.text("new", "New")
.text("open", "Open")
.separator()
.quit()
.build()?;
let edit_menu = SubmenuBuilder::new(app, "Edit")
.undo()
.redo()
.separator()
.cut()
.copy()
.paste()
.select_all()
.build()?;
MenuBuilder::new(app)
.item(&file_menu)
.item(&edit_menu)
.build()
})
.on_menu_event(|app, event| {
match event.id().as_ref() {
"new" => println!("New file"),
"open" => println!("Open file"),
_ => {}
}
})
.run(tauri::generate_context!())
.expect("error running app");
Pattern 2: Application Menu (JavaScript)
import { Menu, MenuItem, Submenu, PredefinedMenuItem, CheckMenuItem } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
await Submenu.new({
text: 'File',
items: [
await MenuItem.new({
text: 'Open',
accelerator: 'CmdOrCtrl+O',
action: () => { console.log('Open clicked'); },
}),
await MenuItem.new({
text: 'Save',
accelerator: 'CmdOrCtrl+S',
action: () => { console.log('Save clicked'); },
}),
await PredefinedMenuItem.new({ item: 'Separator' }),
await PredefinedMenuItem.new({ item: 'Quit' }),
],
}),
await Submenu.new({
text: 'View',
items: [
await CheckMenuItem.new({
text: 'Dark Mode',
checked: false,
action: (item) => { console.log('Toggled'); },
}),
],
}),
],
});
await menu.setAsAppMenu();
Pattern 3: Context Menu (JavaScript)
// Show context menu at cursor position
await menu.popup();
// Show context menu at specific position
await menu.popup({ x: 100, y: 200 });
Pattern 4: System Tray (Rust)
use tauri::tray::TrayIconBuilder;
use tauri::menu::MenuBuilder;
use tauri::image::Image;
tauri::Builder::default()
.setup(|app| {
let menu = MenuBuilder::new(app)
.text("show", "Show Window")
.text("hide", "Hide Window")
.separator()
.text("quit", "Quit")
.build()?;
let _tray = TrayIconBuilder::new()
.icon(Image::from_path("icons/tray.png")?)
.tooltip("My Tauri App")
.menu(&menu)
.show_menu_on_left_click(true)
.on_menu_event(|app, event| {
match event.id().as_ref() {
"show" => {
if let Some(w) = app.get_webview_window("main") {
w.show().unwrap();
}
}
"quit" => app.exit(0),
_ => {}
}
})
.on_tray_icon_event(|tray, event| {
println!("Tray event: {:?}", event);
})
.build(app)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error running app");
Pattern 5: System Tray (JavaScript)
import { TrayIcon } from '@tauri-apps/api/tray';
import { Menu, MenuItem } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
await MenuItem.new({ text: 'Show', action: () => showWindow() }),
await MenuItem.new({ text: 'Quit', action: () => exit(0) }),
],
});
const tray = await TrayIcon.new({
icon: 'icons/tray-icon.png',
tooltip: 'My App',
menu,
action: (event) => {
if (event.type === 'Click') {
console.log('Tray clicked with', event.button);
}
},
});
// Update at runtime
await tray.setTooltip('Updated tooltip');
await tray.setIcon('icons/new-icon.png');
await tray.setVisible(false);
Pattern 6: Menu Item Management (JavaScript)
// Dynamic menu manipulation
await menu.append(await MenuItem.new({ text: 'New Item', action: () => {} }));
await menu.prepend(await MenuItem.new({ text: 'First Item', action: () => {} }));
await menu.insert(1, await MenuItem.new({ text: 'At Index 1', action: () => {} }));
await menu.remove('item-id');
await menu.removeAt(0);
const item = await menu.get('item-id');
const allItems = await menu.items();
Menu Event Handling (Rust)
// On the builder
.on_menu_event(|app, event| {
match event.id().as_ref() {
"new" => println!("New file"),
"open" => println!("Open file"),
_ => {}
}
})
The event.id() returns a MenuId. Use .as_ref() to get a &str for pattern matching.
Tray Configuration in tauri.conf.json
{
"app": {
"trayIcon": {
"iconPath": "icons/icon.png",
"iconAsTemplate": true
}
}
}
Permissions
Menu operations require core:menu:default and tray operations require core:tray:default in the capability file.
{
"permissions": [
"core:menu:default",
"core:tray:default"
]
}
v1 to v2 Migration Names
| Tauri v1 | Tauri v2 | |----------|----------| | Menu | MenuBuilder | | CustomMenuItem | MenuItemBuilder | | Submenu | SubmenuBuilder | | MenuItem (predefined) | PredefinedMenuItem | | SystemTray | TrayIconBuilder | | SystemTrayEvent | TrayIconEvent |
Reference Links
- [references/methods.md](references/methods.md) -- Complete API signatures for Menu, Tray, and all item types
- [references/examples.md](references/examples.md) -- Working code examples for menu and tray patterns
- [references/anti-patterns.md](references/anti-patterns.md) -- What NOT to do with menus and tray, with WHY explanations
Official Sources
- https://v2.tauri.app/develop/menu/
- https://v2.tauri.app/develop/system-tray/
- https://v2.tauri.app/reference/javascript/api/namespacemenu/
- https://v2.tauri.app/reference/javascript/api/namespacetray/
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Tauri-2-Claude-Skill-Package
- License: MIT
- Homepage: https://github.com/OpenAEC-Foundation
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.