/desktop-app
Desktop app development guide — Electron and Tauri for cross-platform apps. Triggers: desktop app, Electron, Tauri, mac app, windows app
Claude Code
$ npx -y skills add ww-w-ai/bkit-claude-code --skill desktop-app --agent claude-code
Codex
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a codex -y
Cursor
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a cursor -y
Gemini CLI
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a gemini-cli -y
GitHub Copilot
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a github-copilot -y
OpenCode
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a opencode -y
Windsurf
$ npx skills add ww-w-ai/bkit-claude-code --skill desktop-app -a windsurf -y
SKILL.md
desktop-app.SKILL.mdname: 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
# Create with electron-vite (recommended)
npm create @electron-vite/create my-electron-app
cd my-electron-app
# Install dependencies
npm install
# Start development server
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
// src/main/index.ts
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,
},
});
// Dev mode: Load Vite server
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:5173');
mainWindow.webContents.openDevTools();
} else {
// Production: Load built files
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// IPC: Handle requests from renderer
ipcMain.handle('read-file', async (event, filePath) => {
const fs = await import('fs/promises');
return fs.readFile(filePath, 'utf-8');
});Preload Script
// src/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron';
// APIs to safely expose to renderer
contextBridge.exposeInMainWorld('electronAPI', {
// Read file
readFile: (filePath: string) => ipcRenderer.invoke('read-file', filePath),
// Save file dialog
saveFile: (content: string) => ipcRenderer.invoke('save-file', content),
// App version
getVersion: () => process.env.npm_package_version,
// Platform
platform: process.platform,
});
// Type definitions (for use in renderer)
declare global {
interface Window {
electronAPI: {
readFile: (path: string) => Promise<string>;
saveFile: (content: string) => Promise<void>;
getVersion: () => string;
platform: NodeJS.Platform;
};
}
}Renderer Process
// src/renderer/src/App.tsx
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
// src/main/menu.ts
import { Menu, app, shell } from 'electron';
const template: ElectronRead more
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
# Create with electron-vite (recommended) npm create @electron-vite/create my-electron-app cd my-electron-app # Install dependencies npm install # Start development server 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
// src/main/index.ts
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,
},
});
// Dev mode: Load Vite server
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:5173');
mainWindow.webContents.openDevTools();
} else {
// Production: Load built files
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// IPC: Handle requests from renderer
ipcMain.handle('read-file', async (event, filePath) => {
const fs = await import('fs/promises');
return fs.readFile(filePath, 'utf-8');
});Preload Script
// src/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron';
// APIs to safely expose to renderer
contextBridge.exposeInMainWorld('electronAPI', {
// Read file
readFile: (filePath: string) => ipcRenderer.invoke('read-file', filePath),
// Save file dialog
saveFile: (content: string) => ipcRenderer.invoke('save-file', content),
// App version
getVersion: () => process.env.npm_package_version,
// Platform
platform: process.platform,
});
// Type definitions (for use in renderer)
declare global {
interface Window {
electronAPI: {
readFile: (path: string) => Promise<string>;
saveFile: (content: string) => Promise<void>;
getVersion: () => string;
platform: NodeJS.Platform;
};
}
}Renderer Process
// src/renderer/src/App.tsx
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
// src/main/menu.ts
import { Menu, app, shell } from 'electron';
const template: ElectronA Claude Code plugin that verifies AI-generated code against its own design specs. Three commands. Anyone — even someone vibe-coding for the first time — can ship robust, production-quality software.
Other skills on bkit.
More skills from other plugins.
agentmail
Use your assigned AgentMail inbox to read email tasks, explicitly send or reply, and check delivery. Provided automatically by…
adr-create
Create a new Architecture Decision Record with sequential numbering and AgentDB registration
Questions about desktop-app.
- Which coding agents can use desktop-app?
- desktop-app installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

