Skip to content
Testing
Skill

/desktop-app

Desktop app development guide — Electron and Tauri for cross-platform apps. Triggers: desktop app, Electron, Tauri, mac app, windows app

From plugin
bkit
58944 skills34 agents2 commands21 hooks
Install
$ npx -y skills add popup-studio-ai/bkit-claude-code --skill desktop-app --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/desktop-app

Context preview

The summary Claude sees to decide when to auto-load this skill.

Desktop app development guide — Electron and Tauri for cross-platform apps. Triggers: desktop app, Electron, Tauri, mac app, windows app

SKILL.md

desktop-app.SKILL.md
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: Electron
Read more
Ships withbkit

A 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.

Get the whole plugin