Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
node_modules
dist
out
.DS_Store
.eslintcache
*.log*

# Development certificate
devcert.pfx

# Windows SDK packages and generated files
.winapp

# Node-gyp build artifacts
addon/build
addon/node_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
out
dist
pnpm-lock.yaml
LICENSE.md
tsconfig.json
tsconfig.*.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
singleQuote: true
semi: false
printWidth: 100
trailingComma: none
108 changes: 108 additions & 0 deletions WindowsAppSDK-ProjectTemplates/electron/electron-win-app/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Electron Windows App (Electron + React + Native Addon)

**You are a desktop app developer** building an Electron + React app with C++/WinRT native addon. When implementing features, first check if Windows APIs (`Windows.*`) or Windows App SDK APIs (`Microsoft.*`) can be used before falling back to other solutions.

## Commands
- One-time setup: Run `npm install` (triggers `postinstall` which restores packages, builds addon, and sets up debug identity)
- Daily dev (hot reload): `npm run dev`
- Build addon after C++ changes: `npm run build-addon`
- Build everything: `npm run build-all` (addon + electron)
- Package MSIX: `npm run package-msix`

## AI Agent Task Loop

**For AI coding assistants: Follow these steps for feature implementations.**

### Where to implement

| If the feature involves... | Implement in |
|---------------------------|--------------|
| UI, user interaction, styling | `src/renderer/` (React) |
| File I/O, IPC handlers, app logic | `src/main/` (Node.js) |
| Windows/WinAppSDK APIs | `addon/addon.cc` (C++/WinRT) |

→ Use native addon when calling WinRT (`Windows.*`) or Windows App SDK (`Microsoft.*`) namespaces. See [Adding native Windows capabilities](#adding-native-windows-capabilities).

### Build → Test → Debug

1. **Build**: Native → `npm run build-addon`; Main → restart dev; Renderer → hot-reloads
2. **Test**: Run `npm run dev`, check terminal for logs/errors. See [Debugging](#debugging).

## Project Structure & Architecture

```
electron-win-app/
├── src/
│ ├── main/ # Main process (Node.js) - IPC handlers, app logic
│ ├── preload/ # Bridge: exposes safe IPC via contextBridge
│ └── renderer/ # Renderer process (React) - UI
├── addon/ # Native addon (C++/WinRT) - Windows APIs
├── .winapp/ # SDK packages, headers, libs (generated)
├── Assets/ # MSIX package assets
├── appxmanifest.xml # MSIX manifest
└── winapp.yaml # winapp CLI config
```

**Data flow:** Renderer → IPC → Main → N-API → Native Addon

*See `showNotification` in `addon/addon.cc` and `src/main/index.ts` for a working example.*

## Adding native Windows capabilities

### 1. Add function in C++ addon
Edit `addon/addon.cc`:
```cpp
void YourNewFunction(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// TODO: Get args, call WinRT APIs, return result
}

// Register in Init()
exports.Set("yourNewFunction", Napi::Function::New(env, YourNewFunction));
```

### 2. Rebuild addon
```bash
npm run build-addon
```

### 3. Add IPC handler in main process
Edit `src/main/index.ts`:
```typescript
ipcMain.handle('your-new-method', (_event, arg1, arg2) => {
return nativeAddon.yourNewFunction(arg1, arg2)
})
```

### 4. Expose in preload (if needed)
Edit `src/preload/index.ts` to add to `contextBridge.exposeInMainWorld`

### 5. Call from renderer
```typescript
const result = await window.electron.ipcRenderer.invoke('your-new-method', arg1, arg2)
```

## Package Identity

Some Windows APIs require Package Identity (notifications, background tasks, etc.). Debug identity is set up automatically via `npm install`.

- Re-setup if needed: `npm run setup-debug`
- Clear (when removing project): `npm run clean-debug`

## Debugging

**Terminal is the primary log destination.** During `npm run dev`, all logs (main, renderer, native) appear in the terminal.

**Logging by layer:**
- **Renderer**: `import { logger } from './utils/logger'` → `logger.info('tag', 'msg')`
- **Main**: `console.log()` / `console.error()`
- **Native**: Throw `Napi::Error` or return error to main process

**AI Agents:** Check the terminal running `npm run dev` for all error messages.

### Common issues
| Issue | Solution |
|-------|----------|
| Identity-required API fails | Run `npm run setup-debug` |
| Addon build fails | Check `.winapp/lib/` exists, run `winapp restore` |
| IPC timeout | Check main process logs for errors |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
207 changes: 207 additions & 0 deletions WindowsAppSDK-ProjectTemplates/electron/electron-win-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# Electron Windows App

An Electron application template with React, TypeScript, and Windows native capabilities through C++ addons and sparse MSIX packaging.

## What's Included

- **Electron + React + TypeScript**: Modern web development with hot reload
- **Native Windows Integration**: C++ addon (node-gyp) for accessing Windows Runtime (WinRT) APIs
- **Sparse MSIX Packaging**: Provides Package Identity for Windows notifications, protocols, and other identity-required features
- **WinApp CLI**: Simplified workflows for Windows app development and packaging

## Prerequisites

- Node.js (LTS version recommended)
- Visual Studio 2019 or later with C++ build tools
- Windows 10 SDK (10.0.19041.0 or later)

## Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

## Quick Start

### First-Time Setup

```bash
# Install dependencies, build native addon, and setup debug identity
npm install
```

The `postinstall` script automatically:
- Restores WinApp packages
- Generates a development certificate
- Builds the C++ addon
- Sets up Electron debug identity

### Development

```bash
# Start with hot reload (React only)
npm run dev
```

For C++ addon changes:
```bash
# Rebuild the native addon
npm run build-addon

# Then restart dev server
npm run dev
```

## Build Commands

### Development Builds

```bash
# Build Electron app only
npm run build

# Build everything (addon + Electron)
npm run build-all

# Build unpacked for testing (x64)
npm run build:unpack

# Build unpacked for ARM64
npm run build:unpack:arm64
```

### MSIX Package

```bash
# Package as MSIX (x64)
npm run package-msix

# Package as MSIX (ARM64)
npm run package-msix:arm64
```

The MSIX packages will be created in the `./dist` folder, signed with the development certificate.

## Project Structure

```
electron-win-app/
├── src/
│ ├── main/ # Electron main process (Node.js)
│ ├── preload/ # Preload scripts (bridge)
│ └── renderer/ # React frontend
├── addon/ # C++ native addon
│ └── binding.gyp # Node-gyp configuration
├── build/ # Native Windows components
├── Assets/ # App icons and assets
├── appxmanifest.xml # MSIX manifest
├── devcert.pfx # Development certificate (auto-generated)
└── winapp.yaml # WinApp CLI configuration
```

## Useful Commands

```bash
# Format code
npm run format

# Lint code
npm run lint

# Type check
npm run typecheck

# Clean build artifacts
npm run clean

# Setup debug identity (run after clean)
npm run setup-debug

# Clear debug identity
npm run clean-debug
```

## Adding Windows Features

This template uses a C++ native addon to access Windows APIs (WinRT). When you need to use a Windows API that isn't available in JavaScript, follow these steps:

### Step 1: Add C++ function in addon

Edit [addon/addon.cc](addon/addon.cc) to add your new Windows API wrapper:

```cpp
#include <winrt/Windows.System.h> // Add necessary WinRT headers

void YourNewFunction(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();

// Get arguments from JavaScript
std::string arg1 = info[0].As<Napi::String>().Utf8Value();

// Call WinRT API
winrt::init_apartment();
// ... your WinRT code here ...

// Return result to JavaScript
return Napi::String::New(env, "result");
}

// Register in Init() function at the bottom of the file
exports.Set("yourNewFunction", Napi::Function::New(env, YourNewFunction));
```

### Step 2: Update binding.gyp (if needed)

If your API requires additional libraries, edit [addon/binding.gyp](addon/binding.gyp):

```json
"libraries": [
"WindowsApp.lib",
"YourAdditionalLib.lib" // Add new libs here
]
```

### Step 3: Rebuild the addon

```bash
npm run build-addon
```

### Step 4: Add IPC handler in main process

Edit [src/main/index.ts](src/main/index.ts):

```typescript
ipcMain.handle('your-new-method', (_event, arg1) => {
return nativeAddon.yourNewFunction(arg1)
})
```

### Step 5: Call from renderer

```typescript
const result = await window.electron.ipcRenderer.invoke('your-new-method', arg1)
```

### Common Windows APIs Examples

| Feature | WinRT Namespace | Example Use |
|---------|-----------------|-------------|
| Notifications | `Windows.UI.Notifications` | Toast notifications |
| File Picker | `Windows.Storage.Pickers` | Native file dialogs |
| Share | `Windows.ApplicationModel.DataTransfer` | Share content |
| Clipboard | `Windows.ApplicationModel.DataTransfer` | Advanced clipboard |
| System Info | `Windows.System` | Device info, memory |

See [AGENTS.md](AGENTS.md) for detailed architecture and more examples.

## Troubleshooting

- **Build errors**: Ensure Visual Studio C++ tools and Windows SDK are installed
- **Certificate issues**: Run `npm run clean-debug` and `npm run setup-debug`
- **Hot reload not working**: Only React changes hot reload; C++ changes require `npm run build-addon` and restart

## Resources

- [Electron Documentation](https://www.electronjs.org/docs)
- [WinApp CLI](https://github.com/microsoft/winappcli)
- [Windows App SDK](https://docs.microsoft.com/windows/apps/windows-app-sdk/)
- [Node-gyp Guide](https://github.com/nodejs/node-gyp)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Native Windows Addon (C++/WinRT)

C++ addon using N-API and WinRT. Provides Windows APIs not available in Node.js.

## Key files
- `addon.cc`: C++ implementation with WinRT calls
- `binding.gyp`: node-gyp build configuration

## When to modify
- Adding new Windows/WinAppSDK API calls
- Exposing new native methods to main process

## Dependencies
- Headers: `.winapp/include/`
- Libraries: `.winapp/lib/`
- Run `winapp restore` if missing

*For implementation patterns and debugging, see root [AGENTS.md](../../AGENTS.md).*
Loading