Skip to main content 홈 크리에이터 seive27 opius-workspace desktop-app
desktop-app Desktop app development guide — Electron and Tauri for cross-platform apps.
Triggers: desktop app, Electron, Tauri, mac app, windows app, 데스크톱 앱.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/Seive27/opius-workspace --skill desktop-app명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Voice agents represent the frontier of AI interaction - humans speaking naturally with AI systems.
Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.
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"