Skip to main content
desktop-app Desktop app development guide — Electron and Tauri for cross-platform apps.
Triggers: desktop app, Electron, Tauri, mac app, windows app
Zur Installation springen Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/popup-studio-ai/bkit-claude-code --skill desktop-appDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... name desktop-app classification capability classification-reason Specialized domain knowledge with limited model overlap deprecation-risk low effort low description Desktop app development guide — Electron and Tauri for cross-platform apps.
Triggers: desktop app, Electron, Tauri, mac app, windows app
agent bkit:pipeline-guide allowed-tools ["Read","Write","Edit","Glob","Grep","Bash","WebSearch"] user-invocable true
Desktop App Development Expertise
Overview
A guide for developing desktop apps using web technologies (HTML, CSS, JavaScript).
Support Windows, macOS, and Linux simultaneously with a single codebase.
Framework Selection Guide
Framework Selection by Tier (v1.3.0)
Framework Tier Recommendation Use Case Tauri Tier 2 ⭐ Primary Lightweight (3MB), Rust security Electron Tier 3 Supported Mature ecosystem, VS Code-like apps
AI-Native Recommendation : Tauri
35% YoY growth
20-40MB memory vs Electron's 200-400MB
Mobile support (iOS/Android) via Tauri 2.0
Rust backend = memory safety
Ecosystem Recommendation : Electron
Mature tooling
Node.js integration
Proven at scale (VS Code, Slack)
Level-wise Recommendations
Starter → Tauri (v2) [Tier 2]
- Simpler setup than Electron
- Smaller output bundles (~3MB vs ~150MB)
Dynamic → Tauri + auto-update [Tier 2]
- Includes server integration, auto-update
- Lower memory footprint
Enterprise → Tauri [Tier 2] or Electron [Tier 3]
- Tauri for performance and security
- Electron for complex Node.js integration
Electron Guide
Project Creation
npm create @electron-vite/create my-electron-app
cd my-electron-app
npm install
npm run dev
Folder Structure
my-electron-app/
├── src/
│ ├── main/ # Main process (Node.js)
│ │ └── index.ts # App entry point, window management
│ ├── preload/ # Preload script
│ │ └── index.ts # Renderer↔Main bridge
│ └── renderer/ # Renderer process (Web)
│ ├── src/ # React/Vue code
│ └── index.html # HTML entry point
├── resources/ # App icons, assets
├── electron.vite.config.ts # Build configuration
├── electron-builder.yml # Deployment configuration
└── package.json
Core Concept: Process Separation ┌─────────────────────────────────────────────────────┐
│ Electron App │
├─────────────────────────────────────────────────────┤
│ Main Process (Node.js) │
│ - System API access (files, network, etc.) │
│ - Window creation/management │
│ - Menu, tray management │
├─────────────────────────────────────────────────────┤
│ Preload Script (Bridge) │
│ - Safe main↔renderer communication │
│ - Expose only specific APIs │
├─────────────────────────────────────────────────────┤
│ Renderer Process (Chromium) │
│ - Web UI (React, Vue, etc.) │
│ - DOM access │
│ - No direct Node.js API access (security) │
└─────────────────────────────────────────────────────┘
Main Process
import { app, BrowserWindow , ipcMain } from 'electron' ;
import { join } from 'path' ;
let mainWindow : BrowserWindow | null = null ;
function createWindow ( ) {
mainWindow = new BrowserWindow ({
width : 1200 ,
height : 800 ,
webPreferences : {
preload : join (__dirname, '../preload/index.js' ),
sandbox : false ,
},
});
if (process.env .NODE_ENV === 'development' ) {
mainWindow.loadURL ('http://localhost:5173' );
mainWindow.webContents .openDevTools ();
} else {
mainWindow.loadFile (join (__dirname, '../renderer/index.html' ));
}
}
app.whenReady ().then (createWindow);
app.on ('window-all-closed' , () => {
if (process.platform !== 'darwin' ) {
app.quit ();
}
});
ipcMain.handle ('read-file' , async (event, filePath) => {
const fs = await import ('fs/promises' );
return fs.readFile (filePath, 'utf-8' );
});
Preload Script
import { contextBridge, ipcRenderer } from 'electron' ;
contextBridge.exposeInMainWorld ('electronAPI' , {
readFile : (filePath : string ) => ipcRenderer.invoke ('read-file' , filePath),
saveFile : (content : string ) => ipcRenderer.invoke ('save-file' , content),
getVersion : () => process.env .npm_package_version ,
platform : process.platform ,
});
declare global {
interface Window {
electronAPI : {
readFile : (path : string ) => Promise <string >;
saveFile : (content : string ) => Promise <void >;
getVersion : () => string ;
platform : NodeJS .Platform ;
};
}
}
Renderer Process
import { useState } from 'react' ;
function App ( ) {
const [content, setContent] = useState ('' );
const handleOpenFile = async ( ) => {
const result = await window .electronAPI .readFile ('/path/to/file.txt' );
setContent (result);
};
return (
<div className ="app" >
<h1 > My Electron App</h1 >
<p > Platform: {window.electronAPI.platform}</p >
<button onClick ={handleOpenFile} > Open File</button >
<pre > {content}</pre >
</div >
);
}
export default App ;
Creating Menus
import { Menu , app, shell } from 'electron' ;
const template : Electron .MenuItemConstructorOptions [] = [
{
label : 'File' ,
submenu : [
{ label : 'New File' , accelerator : 'CmdOrCtrl+N' , click : () => {} },
{ label : 'Open' , accelerator : 'CmdOrCtrl+O' , click : () => {} },
{ type : 'separator' },
{ label : 'Quit' , role : 'quit' },
],
},
{
label : 'Edit' ,
submenu : [
{ label : 'Undo' , role : 'undo' },
{ label : 'Redo' , role : 'redo' },
{ type : 'separator' },
{ label : 'Cut' , role : 'cut' },
{ label : 'Copy' , role : 'copy' },
{ label : 'Paste' , role : 'paste' },
],
},
{
label : 'Help' ,
submenu : [
{
label : 'Documentation' ,
click : () => shell.openExternal ('https://docs.example.com' ),
},
],
},
];
if (process.platform === 'darwin' ) {
template.unshift ({
label : app.getName (),
submenu : [
{ role : 'about' },
{ type : 'separator' },
{ role : 'services' },
{ type : 'separator' },
{ role : 'hide' },
{ role : 'unhide' },
{ type : 'separator' },
{ role : 'quit' },
],
});
}
export const menu = Menu .buildFromTemplate (template);
System Tray
import { Tray , Menu , nativeImage } from 'electron' ;
import { join } from 'path' ;
let tray : Tray | null = null ;
export function createTray ( ) {
const icon = nativeImage.createFromPath (join (__dirname, '../../resources/icon.png' ));
tray = new Tray (icon.resize ({ width : 16 , height : 16 }));
const contextMenu = Menu .buildFromTemplate ([
{ label : 'Open' , click : () => {} },
{ type : 'separator' },
{ label : 'Quit' , role : 'quit' },
]);
tray.setToolTip ('My App' );
tray.setContextMenu (contextMenu);
}
Tauri Guide
Project Creation
npm create tauri-app my-tauri-app
cd my-tauri-app
npm install
npm run tauri dev
Folder Structure my-tauri-app/
├── src/ # Frontend (React, Vue, etc.)
│ ├── App.tsx
│ └── main.tsx
├── src-tauri/ # Tauri backend (Rust)
│ ├── src/
│ │ ├── main.rs # Main entry point
│ │ └── lib.rs # Command definitions
│ ├── tauri.conf.json # Tauri configuration
│ └── Cargo.toml # Rust dependencies
├── public/
└── package.json
Command Definition (Rust)
use tauri::command;
#[command]
fn greet (name: &str ) -> String {
format! ("Hello, {}!" , name)
}
#[command]
async fn read_file (path: &str ) -> Result <String , String > {
std::fs::read_to_string (path)
.map_err (|e| e.to_string ())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run () {
tauri::Builder::default ()
.invoke_handler (tauri::generate_handler![greet, read_file])
.run (tauri::generate_context!())
.expect ("error while running tauri application" );
}
Calling from Frontend
import { invoke } from '@tauri-apps/api/core' ;
function App ( ) {
const [greeting, setGreeting] = useState ('' );
const handleGreet = async ( ) => {
const result = await invoke ('greet' , { name : 'World' });
setGreeting (result as string );
};
const handleReadFile = async ( ) => {
try {
const content = await invoke ('read_file' , { path : '/path/to/file.txt' });
console .log (content);
} catch (error) {
console .error (error);
}
};
return (
<div >
<button onClick ={handleGreet} > Greet</button >
<p > {greeting}</p >
</div >
);
}
Web vs Desktop Differences
File System Access
const fs = require ('fs' );
fs.writeFileSync ('/path/to/file.txt' , 'content' );
await invoke ('write_file' , { path : '/path/to/file.txt' , content : 'content' });
System Integration Things impossible on web but possible on desktop:
- System tray icon
- Global shortcuts
- Native notifications
- Drag and drop (file path access)
- Full clipboard control
- Native menus
Offline Support Web: Requires Service Worker, limited
Desktop: Works offline by default
⚠️ Server integration features must handle offline!
Build & Deployment
Electron Build
appId: com.example.myapp
productName: My App
directories:
buildResources: resources
files:
- '!**/.vscode/*'
- '!src/*'
- '!electron.vite.config.*'
mac:
artifactName: ${name}-${version}-${arch}.${ext}
target:
- dmg
- zip
icon: resources/icon.icns
win:
artifactName: ${name}-${version}-${arch}.${ext}
target:
- nsis
icon: resources/icon.ico
linux:
target:
- AppImage
- deb
npm run build:mac
npm run build:win
npm run build:linux
Auto-update
import { autoUpdater } from 'electron-updater' ;
autoUpdater.checkForUpdatesAndNotify ();
autoUpdater.on ('update-available' , () => {
});
autoUpdater.on ('update-downloaded' , () => {
autoUpdater.quitAndInstall ();
});
Tauri Build
Desktop PDCA Checklist
Phase 1: Schema □ Decide local data storage method (SQLite, JSON file, etc.)
□ Decide if cloud sync is needed
Phase 3: Mockup □ Consider platform-specific UI guidelines (macOS, Windows)
□ Plan keyboard shortcuts
□ Design menu structure
Phase 6: UI □ Support dark/light mode
□ Handle window resizing
□ Handle platform-specific UI differences (window control positions, etc.)
Phase 7: Security □ Don't expose Node.js APIs directly (use contextBridge)
□ Security handling when loading external URLs
□ Encrypt sensitive data storage
Phase 9: Deployment □ Code signing (macOS Notarization, Windows Signing)
□ Set up auto-update
□ App Store submission (if needed)
Useful Libraries
Electron Library Purpose electron-store Local settings/data storage electron-updater Auto-update electron-log Logging better-sqlite3 SQLite database
Tauri Library Purpose tauri-plugin-store Settings storage tauri-plugin-sql SQLite support tauri-plugin-log Logging tauri-plugin-updater Auto-update
Requesting from Claude
Project Creation "Set up a [app description] app project with Electron + React.
- Use electron-vite
- Support system tray
- Set up auto-update"
Feature Implementation "Implement file open/save functionality.
- Use native file dialogs
- Save recent file list
- Support drag and drop"
Build Configuration "Create electron-builder configuration.
- macOS: DMG + notarization
- Windows: NSIS installer
- Auto-update server integration"
Mehr aus diesem Repository