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
- Clone the repository and initialize submodules:
git clone https://github.com/microsoft/PowerToys.git
cd PowerToys
git submodule update --init --recursive
- 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.slnto your desired name. - Update the C++ class names in
MyNewModule.handMyNewModule.cppto 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:
-
Create WinUI 3 XAML files under
src/settings-ui/(e.g.,MyNewModuleSettings.xaml). -
Implement the code-behind in C# (e.g.,
MyNewModuleSettings.cs) to bind controls to the JSON schema defined inmodule.json. -
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
- Open
src/PowerToys.slnxin Visual Studio 2022. - Select the Debug | x64 configuration to ensure debug symbols are generated.
- Build the solution. The build system invokes CMake for each module and packages binaries into the installer layout.
Local Testing
- Launch
PowerToys.exefrom thex64/Debugoutput 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:
- Update the version field in
module.jsonto reflect release status. - Run the packaging script
tools/build/build.cmd /p:Configuration=Releaseto generate.msixassets. - Open a Pull Request against the
mainbranch following the guidelines inCONTRIBUTING.md. - 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 implementPowerToysModuleInterfacefromsrc/common/. - The
tools/project_template/ModuleTemplate.ziparchive provides a complete scaffold including CMake configuration, manifest files, and starter UI code. - Module registration occurs automatically through the
module.jsonmanifest 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →