Creating a New PowerToys Module from Scratch: Step-by-Step Guide

PowerToys modules are self-contained Visual Studio solutions that implement the PowerToysModuleInterface and plug into the PowerToys Runner, with Microsoft providing a project template in tools/project_template/ModuleTemplate.zip that automatically generates the CMake configuration, module manifest, and settings UI scaffolding.

Developing a new module for the microsoft/PowerToys repository requires implementing a specific C++ interface to integrate with the runner's lifecycle. By using the official module template, you can bypass boilerplate setup and focus on core functionality while ensuring full compatibility with the PowerToys architecture and build system.

Prerequisites for PowerToys Module Development

Before creating a new module, verify your environment matches the build requirements used by the main PowerToys solution. The project template relies on the same CMake infrastructure as the core application.

  • Visual Studio 2022 (17.4 or newer) with the Desktop development with C++ workload and the C++ CMake tools for Windows component installed.
  • CMake 3.21 or newer for processing the build configuration files.
  • Windows 10 version 1803 or newer (or Windows 11) for runtime compatibility.
  • Git for cloning the repository and updating submodules.

Scaffolding a New Module from the Template

The fastest way to create a PowerToys module is to use the pre-built template archive located in the repository's tools directory.

Locating and Extracting the Template

  1. Clone the repository and initialize submodules:
git clone https://github.com/microsoft/PowerToys.git
cd PowerToys
git submodule update --init --recursive
  1. Extract the template archive into a new folder under src/modules/:
mkdir -p src/modules/MyNewModule
unzip tools/project_template/ModuleTemplate.zip -d src/modules/MyNewModule

The template contains a complete solution skeleton including CMake lists, asset folders, and starter UI files. Detailed usage instructions are available in tools/project_template/README.md.

Customizing the Module Identity

After extraction, replace all placeholder identifiers with your module name:

  • Rename the solution file from MyNewModule.sln to your desired name.
  • Update the C++ class names in MyNewModule.h and MyNewModule.cpp to match your module.
  • Modify the namespace declarations in all header and implementation files.

Configuring the Module Manifest

Edit src/modules/<YourModule>/module.json to define runtime metadata:

  • Set the "name" and "description" fields for display in the Settings UI.
  • Define activation hotkeys and settings schema entries.
  • Specify version information and author details.

The runner discovers modules automatically by scanning these JSON files, eliminating the need for manual registration in src/PowerToysModuleRegistry.cpp.

Implementing the PowerToysModuleInterface

Every PowerToys module must implement the abstract base class defined in src/common/PowerToysModuleInterface.h.

Core Class Structure

Create a class derived from PowerToysModuleInterface in your module's main header and source files:

#include <common/PowerToysModuleInterface.h>

class MyNewModule : public PowerToysModuleInterface {
public:
    virtual void onHotKey() override;
    virtual void enable() override;
    virtual void disable() override;
    virtual bool is_enabled() override;
    virtual void destroy() override;
};

The onHotKey callback serves as the primary entry point for user-triggered actions, while enable and disable manage the module's lifecycle state.

Adding Settings UI

For modules requiring configuration:

  1. Create WinUI 3 XAML files under src/settings-ui/ (e.g., MyNewModuleSettings.xaml).

  2. Implement the code-behind in C# (e.g., MyNewModuleSettings.cs) to bind controls to the JSON schema defined in module.json.

  3. Store localized strings and icons in src/modules/<YourModule>/Resources/.

Building and Testing Your Module

PowerToys uses a master solution file that aggregates all modules for unified compilation.

Compilation Steps

  1. Open src/PowerToys.slnx in Visual Studio 2022.
  2. Select the Debug | x64 configuration to ensure debug symbols are generated.
  3. Build the solution. The build system invokes CMake for each module and packages binaries into the installer layout.

Local Testing

  • Launch PowerToys.exe from the x64/Debug output folder.
  • Verify your module appears in the Settings UI and responds to hotkey triggers.
  • Create a unit test project under src/modules/<YourModule>.Tests/ using the Microsoft C++ Test Framework (CppUnitTest) to validate core logic.

Contributing Your Module Upstream

To submit your module for inclusion in the main PowerToys distribution:

  1. Update the version field in module.json to reflect release status.
  2. Run the packaging script tools/build/build.cmd /p:Configuration=Release to generate .msix assets.
  3. Open a Pull Request against the main branch following the guidelines in CONTRIBUTING.md.
  4. Include a Design Doc describing the module's purpose, UI specifications, and any IPC contracts.

The CI pipeline automatically executes the full build suite, unit tests, and code-style validation defined in the repository checks.

Summary

  • PowerToys modules are standalone Visual Studio solutions that live under src/modules/ and implement PowerToysModuleInterface from src/common/.
  • The tools/project_template/ModuleTemplate.zip archive provides a complete scaffold including CMake configuration, manifest files, and starter UI code.
  • Module registration occurs automatically through the module.json manifest file; no manual registry edits are required.
  • Build and debug using src/PowerToys.slnx, which aggregates all modules into a single solution.
  • Submit contributions via GitHub PR with accompanying design documentation and unit tests.

Frequently Asked Questions

What is the PowerToysModuleInterface?

The PowerToysModuleInterface is an abstract C++ base class defined in src/common/PowerToysModuleInterface.h that defines the contract between the PowerToys Runner and individual modules. It declares lifecycle methods like enable(), disable(), and onHotKey() that the runner invokes to manage module state and handle user input.

Where is the official module template located?

Microsoft provides the official scaffolding in tools/project_template/ModuleTemplate.zip within the microsoft/PowerToys repository. This archive contains a pre-configured solution with CMake lists, asset folders, and boilerplate code. Extract this ZIP into src/modules/<YourModuleName> and follow the renaming instructions in tools/project_template/README.md.

How does the PowerToys Runner discover new modules?

The runner performs runtime discovery by scanning for module.json files in the src/modules/ directory tree. Each manifest file contains metadata, activation settings, and schema definitions that the runner uses to load the module dynamically. This JSON-based approach eliminates the need to modify src/PowerToysModuleRegistry.cpp when adding new modules.

Do PowerToys modules support IPC for complex integrations?

Yes. Modules requiring communication between the background runner process and the Settings UI can use the IPC contracts located in src/common/ipc/. The repository provides IPCHost.cs and IPCHost.cpp implementations that handle cross-process messaging, enabling advanced scenarios like real-time settings synchronization or background task coordination.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →