Skip to main content
This guide covers the complete process of creating a new PowerToys utility. Follow each section in order for best results.

Overview

A PowerToys module is a self-contained utility integrated into the PowerToys ecosystem. Modules can be:
  • UI-only: Standalone applications launched on-demand (e.g., ColorPicker)
  • Background service: Always-running services (e.g., Awake, LightSwitch)
  • Hybrid: Combination of UI and background logic (e.g., ShortcutGuide, FancyZones)
  • C++/C# interop: Mixed native and managed code (e.g., PowerRename)

Prerequisites

Before starting:
  1. ✅ Complete the Getting Started guide
  2. ✅ Successfully build and run PowerToys.slnx
  3. ✅ Understand debugging techniques
  4. ✅ Familiarize yourself with coding style
Optional:
  • WiX v5 toolset (for building installer)
  • Multiple monitors (for testing multi-display utilities)

Planning Your Module

1. Design Decisions

Answer these questions before coding:

2. Study Similar Modules

UI-only modules:
  • ColorPicker - Simple activation and UI
  • PowerOCR - On-demand text recognition
  • MeasureTool - Overlay-based measurement
Background services:
  • Awake - Keep-alive service
  • LightSwitch - System theme monitor
  • AlwaysOnTop - Window state management
Hybrid modules:
  • FancyZones - Service + editor UI
  • ShortcutGuide - Background + overlay
  • Workspaces - Complex UI + window management
C++/C# interop:
  • PowerRename - Explorer extension + UI
  • FileLocksmith - Shell integration + UI
  • ImageResizer - Context menu + processing
Explore similar modules in src/modules/ to understand patterns and best practices.

Module Architecture

Folder Structure

Create your module under src/modules/:

Step 1: Create Module Interface

The Module Interface is required - it’s how PowerToys Runner communicates with your module.

Using the Project Template

  1. Use the module template:
  2. Copy generated files to src\modules\YourModule\YourModuleModuleInterface\
  3. Update all GUIDs in project files
  4. Update namespaces and class names

Module Interface Structure

Key components in dllmain.cpp:

1. Settings Structure

2. Module Class

3. Required Methods

Module Identification:
GPO Policy Support:
You must add your module to GPO settings in src/common/GPOWrapper/GPOWrapper.cpp
Lifecycle Management:
Settings Management:
Hotkey Support (optional):

Export Module

At the end of dllmain.cpp:

Step 2: Register Module with Runner

Your module must be registered in multiple locations:

1. src/runner/modules.h

Add to the module list:

2. src/runner/modules.cpp

Add module loading:

3. src/common/logger/logger.h

Add logging category:

4. src/runner/settings_window.h and .cpp

Add to settings enumeration and mapping.
Search for an existing module name (e.g., “FancyZones”) in these files to find all locations that need updates.

Step 3: Build Module Service/UI

This is the main functionality of your module.

C++ Service Example

C# WinUI App Example

Create WinUI 3 Blank App project:

Project Configuration

Set the output path in your .vcxproj or .csproj:

Step 4: Settings Integration

Integrate your module with PowerToys Settings UI.

1. Create Settings Classes

src/settings-ui/Settings.UI.Library/YourModuleProperties.cs:
src/settings-ui/Settings.UI.Library/YourModuleSettings.cs:

2. Create ViewModel

src/settings-ui/Settings.UI/ViewModels/YourModuleViewModel.cs:

3. Create Settings Page

src/settings-ui/Settings.UI/SettingsXAML/Views/YourModulePage.xaml:

4. Add Resource Strings

src/settings-ui/Settings.UI/Strings/en-us/Resources.resw:

Step 5: OOBE Page

Create Out-of-Box Experience page for new users. src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeYourModule.xaml:
Add to src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs:

Step 6: Installer Integration

Add your module to the WiX installer.

1. Create WiX Component File

installer/PowerToysInstallerVNext/YourModule.wxs:

2. Update Product.wxs

installer/PowerToysInstallerVNext/Product.wxs: Add to <Feature Id="CoreFeature">:

3. Update File Generation Script

installer/PowerToysInstallerVNext/generateFileComponents.ps1: Add at the end:

Step 7: Build and Test

Build Your Module

Debug Your Module

  1. Set runner as startup project
  2. Start debugging (F5)
  3. Enable your module in Settings
  4. Attach to your module’s process:
    • Press Ctrl+Alt+P
    • Search for PowerToys.YourModule.exe
    • Attach debugger
See Debugging Guide for details.

Test Scenarios

  • Module appears in Settings UI
  • Enable/disable works correctly
  • Settings persist after restart
  • Hotkey activation works (if applicable)
  • Module starts with PowerToys
  • Module logs correctly
  • No crashes or memory leaks
  • Works in elevated and non-elevated modes
  • OOBE page displays correctly

Step 8: Testing

Write comprehensive tests for your module.

Unit Tests

Create test project: src/modules/YourModule/Tests/YourModule-UnitTests/ See Testing Guide for details.

UI Tests

Create UI test project: src/modules/YourModule/Tests/YourModule-UITests/ See Testing Guide for details.

Fuzz Tests (if applicable)

If your module handles file I/O or user input, implement fuzz tests. See Testing Guide for details.

Step 9: Documentation

Developer Documentation

Create doc/devdocs/modules/your-module.md:

User Documentation

The PowerToys team will create Microsoft Learn documentation for users.

Common Pitfalls

Module Not Loading

Symptoms: Module doesn’t appear in Settings Check:
  • Module registered in modules.h and modules.cpp
  • DLL path correct in module_dlls array
  • Module key matches everywhere
  • Module interface exports powertoy_create() correctly

Settings Not Persisting

Symptoms: Settings reset after restart Check:
  • Settings saved to correct path: %LOCALAPPDATA%\Microsoft\PowerToys\YourModule\settings.json
  • JSON serialization correct
  • Settings loaded in init_settings()
  • File watcher implemented for settings changes

Module Crashes Runner

Symptoms: PowerToys crashes when module loads Check:
  • No exceptions in module constructor
  • Proper error handling in interface methods
  • Resources cleaned up in destructor
  • No memory leaks
  • Logs show error details

Hotkey Not Working

Symptoms: Hotkey doesn’t activate module Check:
  • Hotkey parsed correctly in settings
  • get_hotkeys() returns correct hotkey
  • on_hotkey() handles activation
  • Module is enabled
  • No conflicting hotkeys

Checklist

Before submitting your module:

Code Complete

  • Module interface implemented
  • Service/UI implemented
  • Settings integration complete
  • OOBE page created
  • Installer integration done
  • Tests written and passing
  • Documentation created

Quality

  • Code follows style guidelines
  • No hardcoded strings (use resources)
  • Proper error handling
  • Logging implemented
  • No memory leaks
  • Thread-safe where needed

Testing

  • Builds successfully
  • Unit tests pass
  • UI tests pass (if applicable)
  • Fuzz tests implemented (if handling file I/O)
  • Tested in Debug and Release
  • Tested elevated and non-elevated
  • Tested on multiple monitors (if applicable)
  • Tested clean install

Integration

  • Registered in runner
  • GPO support added
  • Settings UI complete
  • OOBE page works
  • Installer includes module
  • Telemetry events defined

Next Steps

Building

Build your module and PowerToys

Debugging

Debug your module effectively

Testing

Write comprehensive tests

Contributing

Submit your module via pull request

Getting Help

If you need assistance:
  1. Check existing modules for examples
  2. Review developer documentation
  3. Open an issue with tag Needs-Team-Response
  4. Join discussions in the PowerToys repository
Thank you for contributing to PowerToys! 🎉