tauri-native-menus — native context menus in Tauri v2 tauri-native-menus, Commitment-tauri, community, native context menus in Tauri v2, ide skills, implementing popup menus in Tauri v2, debugging menu event handling issues, Claude Code, Cursor, Windsurf

v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing native context menu integration in Tauri v2 applications tauri-native-menus is a skill for implementing native context menus in Tauri v2 applications, covering menu event handling and migration.

Features

Implements native context menus in Tauri v2 applications
Provides guidance on adding right-click context menus to UI elements
Supports popup menus in Tauri v2
Covers migration from web-based menus to native menus
Offers debugging solutions for menu event handling issues

# Core Topics

StefKors StefKors
[0]
[0]
Updated: 3/8/2026

Agent Capability Analysis

The tauri-native-menus skill by StefKors is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance. Optimized for native context menus in Tauri v2, implementing popup menus in Tauri v2, debugging menu event handling issues.

Ideal Agent Persona

Perfect for Frontend Agents needing native context menu integration in Tauri v2 applications

Core Value

Empowers agents to implement native context menus in Tauri v2 using React, providing a seamless user experience with native menu integration and event handling, while avoiding common pitfalls such as directly using muda

Capabilities Granted for tauri-native-menus

Implementing right-click context menus in UI elements
Migrating from web-based menus to native menus in Tauri v2
Debugging menu event handling issues in React frontend applications

! Prerequisites & Limits

  • Requires Tauri v2 application setup
  • Limited to React frontend development
  • Native menu implementation may vary across different operating systems
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

tauri-native-menus

Learn how to implement native context menus in Tauri v2 apps with our expert guide. Master menu event handling and migration from web-based menus.

SKILL.md
Readonly

Tauri v2 Native Context Menus

Guide for implementing native context menus in Tauri v2 applications. This skill documents the correct approach and common pitfalls when integrating native menus with a React frontend.

When to Apply

Reference this guide when:

  • Adding right-click context menus to UI elements
  • Implementing popup menus in Tauri v2
  • Migrating from web-based menus to native menus
  • Debugging menu event handling issues

Critical Knowledge

Do NOT Use muda Directly

Tauri v2 uses muda internally for menu management, but do not use muda's event system directly in a Tauri application.

Why it fails:

  • muda::MenuEvent::set_event_handler() does not receive events in Tauri's event loop
  • muda::MenuEvent::receiver() channel never receives menu click events
  • Tauri manages its own event loop and intercepts muda events

What happens:

rust
1// This will NOT work - events never fire 2muda::MenuEvent::set_event_handler(Some(|event| { 3 // This closure is never called in Tauri context 4})); 5 6// This also does NOT work 7let receiver = muda::MenuEvent::receiver(); 8if let Ok(event) = receiver.try_recv() { 9 // Never receives events 10}

Use Tauri's Native Menu API

Instead, use Tauri's built-in menu API which properly integrates with its event system:

rust
1use tauri::menu::{MenuBuilder, MenuItem, PredefinedMenuItem}; 2use tauri::Window; 3 4#[tauri::command] 5pub async fn show_context_menu( 6 window: Window, 7 request: ShowContextMenuRequest, 8) -> Result<(), String> { 9 // Build menu using Tauri's API 10 let mut menu_builder = MenuBuilder::new(&window); 11 12 for item in &request.items { 13 match item { 14 ContextMenuItemOrSeparator::Item(menu_item) => { 15 // Use compound ID format: "ctx:{request_id}:{item_id}" 16 let compound_id = format!("ctx:{}:{}", request.request_id, menu_item.id); 17 let tauri_item = MenuItem::with_id( 18 &window, 19 &compound_id, 20 &menu_item.label, 21 !menu_item.disabled.unwrap_or(false), 22 None::<&str>, 23 ).map_err(|e| e.to_string())?; 24 menu_builder = menu_builder.item(&tauri_item); 25 } 26 ContextMenuItemOrSeparator::Separator => { 27 let separator = PredefinedMenuItem::separator(&window) 28 .map_err(|e| e.to_string())?; 29 menu_builder = menu_builder.item(&separator); 30 } 31 } 32 } 33 34 let menu = menu_builder.build().map_err(|e| e.to_string())?; 35 36 // Show as popup menu at cursor position 37 window.popup_menu(&menu).map_err(|e| e.to_string())?; 38 39 Ok(()) 40}

Handle Events in App Setup

Register a global menu event handler in your lib.rs setup:

rust
1// In tauri::Builder::default().setup(|app| { ... }) 2app.on_menu_event(move |app, event| { 3 let event_id = event.id().0.as_str(); 4 5 // Handle context menu events (format: "ctx:{request_id}:{item_id}") 6 if event_id.starts_with("ctx:") { 7 let parts: Vec<&str> = event_id.splitn(3, ':').collect(); 8 if parts.len() == 3 { 9 let request_id = parts[1]; 10 let item_id = parts[2]; 11 app.emit( 12 "context-menu:clicked", 13 serde_json::json!({ 14 "requestId": request_id, 15 "itemId": item_id, 16 }), 17 ).ok(); 18 } 19 return; 20 } 21 22 // Handle other menu events... 23});

Frontend Event Handling

Listen for context menu events in React:

tsx
1import { listen } from "@tauri-apps/api/event" 2 3// Store a stable requestId per component instance 4const requestIdRef = useRef(`file-row-${file.path}-${Date.now()}`) 5const handlersRef = useRef<Map<string, () => void>>(new Map()) 6 7// Set up handlers map 8useEffect(() => { 9 const handlers = new Map<string, () => void>() 10 handlers.set("action-1", handleAction1) 11 handlers.set("action-2", handleAction2) 12 handlersRef.current = handlers 13}, [handleAction1, handleAction2]) 14 15// Listen for context menu events 16useEffect(() => { 17 const requestId = requestIdRef.current 18 const unlisten = listen<{ requestId: string; itemId: string }>( 19 "context-menu:clicked", 20 (event) => { 21 if (event.payload.requestId === requestId) { 22 const handler = handlersRef.current.get(event.payload.itemId) 23 if (handler) handler() 24 } 25 }, 26 ) 27 return () => { 28 unlisten.then((fn) => fn()) 29 } 30}, []) 31 32// Trigger context menu on right-click 33const handleContextMenu = useCallback(async (e: React.MouseEvent) => { 34 e.preventDefault() 35 e.stopPropagation() 36 37 await showContextMenu({ 38 requestId: requestIdRef.current, 39 items: [ 40 { type: "item", id: "action-1", label: "Action 1" }, 41 { type: "separator" }, 42 { type: "item", id: "action-2", label: "Action 2" }, 43 ], 44 }) 45}, [])

Let the OS handle menu positioning by not specifying coordinates:

rust
1// Pass None for position - menu appears at cursor 2window.popup_menu(&menu)?;

Avoid Manual Coordinate Conversion

Do NOT try to convert frontend coordinates to screen coordinates manually:

rust
1// DON'T DO THIS - coordinate systems differ between: 2// - CSS pixels (logical) vs physical pixels 3// - Window-relative vs screen-relative 4// - Different scale factors on Retina displays 5let screen_x = window_pos.x + client_x; // WRONG

TypeScript Types

typescript
1export interface ContextMenuItem { 2 id: string 3 label: string 4 disabled?: boolean 5} 6 7export type ContextMenuItemOrSeparator = 8 | { type: "item"; id: string; label: string; disabled?: boolean } 9 | { type: "separator" } 10 11export interface ShowContextMenuRequest { 12 requestId: string 13 items: ContextMenuItemOrSeparator[] 14 x?: number // Optional, not used when relying on cursor position 15 y?: number 16}

Rust Types

rust
1#[derive(Debug, Clone, Serialize, Deserialize)] 2pub struct ContextMenuItem { 3 pub id: String, 4 pub label: String, 5 pub disabled: Option<bool>, 6} 7 8#[derive(Debug, Clone, Serialize, Deserialize)] 9#[serde(tag = "type")] 10pub enum ContextMenuItemOrSeparator { 11 #[serde(rename = "item")] 12 Item(ContextMenuItem), 13 #[serde(rename = "separator")] 14 Separator, 15} 16 17#[derive(Debug, Clone, Serialize, Deserialize)] 18#[serde(rename_all = "camelCase")] // Important: match frontend naming 19pub struct ShowContextMenuRequest { 20 pub request_id: String, 21 pub items: Vec<ContextMenuItemOrSeparator>, 22 pub x: Option<f64>, 23 pub y: Option<f64>, 24}

Common Mistakes

MistakeWhy It FailsSolution
Using muda::MenuEvent::set_event_handler()Tauri intercepts muda eventsUse app.on_menu_event()
Using muda::MenuEvent::receiver()Events never delivered to channelUse app.on_menu_event()
Manual coordinate conversionCSS vs physical pixels, scale factorsLet OS position at cursor
Missing #[serde(rename_all = "camelCase")]Frontend sends camelCase, Rust expects snake_caseAdd serde attribute
Using &AppHandle in MenuItem::with_id()Borrow doesn't implement ManagerUse &window instead

Dependencies

toml
1# Cargo.toml - muda is NOT needed as a direct dependency 2# Tauri v2 includes it internally 3 4[dependencies] 5tauri = { version = "2", features = ["menu"] } 6serde = { version = "1", features = ["derive"] } 7serde_json = "1"

References

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is tauri-native-menus?

Perfect for Frontend Agents needing native context menu integration in Tauri v2 applications tauri-native-menus is a skill for implementing native context menus in Tauri v2 applications, covering menu event handling and migration.

How do I install tauri-native-menus?

Run the command: npx killer-skills add StefKors/Commitment-tauri/tauri-native-menus. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for tauri-native-menus?

Key use cases include: Implementing right-click context menus in UI elements, Migrating from web-based menus to native menus in Tauri v2, Debugging menu event handling issues in React frontend applications.

Which IDEs are compatible with tauri-native-menus?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for tauri-native-menus?

Requires Tauri v2 application setup. Limited to React frontend development. Native menu implementation may vary across different operating systems.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add StefKors/Commitment-tauri/tauri-native-menus. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use tauri-native-menus immediately in the current project.

Related Skills

Looking for an alternative to tauri-native-menus or another community skill for your workflow? Explore these related open-source skills.

View All

widget-generator

Logo of f
f

f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.

149.6k
0
AI

flags

Logo of vercel
vercel

flags is a Next.js feature management skill that enables developers to efficiently add or modify framework feature flags, streamlining React application development.

138.4k
0
Browser

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI