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

> Learn to create a new PowerToys module from scratch with this step-by-step guide. Discover how to leverage the project template and integrate your module seamlessly. Get started today!

- Repository: [Microsoft/PowerToys](https://github.com/microsoft/PowerToys)
- Tags: how-to-guide
- Published: 2026-02-25

---

**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:

```bash
git clone https://github.com/microsoft/PowerToys.git
cd PowerToys
git submodule update --init --recursive

```

2. Extract the template archive into a new folder under `src/modules/`:

```bash
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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/MyNewModule.h) and [`MyNewModule.cpp`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/src/PowerToysModuleRegistry.cpp).

## Implementing the PowerToysModuleInterface

Every PowerToys module must implement the abstract base class defined in [`src/common/PowerToysModuleInterface.h`](https://github.com/microsoft/PowerToys/blob/main/src/common/PowerToysModuleInterface.h).

### Core Class Structure

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

```cpp
#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`](https://github.com/microsoft/PowerToys/blob/main/MyNewModuleSettings.cs)) to bind controls to the JSON schema defined in [`module.json`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/tools/project_template/README.md).

### How does the PowerToys Runner discover new modules?

The runner performs runtime discovery by scanning for [`module.json`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/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`](https://github.com/microsoft/PowerToys/blob/main/IPCHost.cs) and [`IPCHost.cpp`](https://github.com/microsoft/PowerToys/blob/main/IPCHost.cpp) implementations that handle cross-process messaging, enabling advanced scenarios like real-time settings synchronization or background task coordination.