-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
This walkthrough builds a minimal LoupixDeck plugin that contributes a single command — clicking the assigned button writes a line to the host log.
- .NET 9 SDK
- An IDE that supports .NET 9 (Rider, Visual Studio 2022 17.12+, or VS Code with the C# Dev Kit)
- LoupixDeck installed locally so you can drop the built plugin into its plugin folder and watch it load
- A local copy of the
LoupixDeck.PluginSdkNuGet package (build the SDK repository once — it writes the.nupkgto./nupkg/)
dotnet new classlib -n MyPlugin -f net9.0
cd MyPluginThe SDK is consumed as a NuGet package from a local feed. Add a nuget.config
next to the .csproj:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="LoupixDeck.PluginSdk" value="..\..\LoupixDeck.PluginSdk\nupkg" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>Then reference the package:
dotnet add package LoupixDeck.PluginSdk --version 1.2.*Important: Do not copy the SDK DLL into your plugin's output folder. The host provides the SDK assembly — bundling it causes load conflicts. The default NuGet behavior is correct; do not set
<Private>true</Private>.
Replace the generated Class1.cs with MyPlugin.cs:
using LoupixDeck.PluginSdk;
namespace MyPlugin;
public sealed class HelloPlugin : LoupixPlugin
{
private IPluginHost _host = null!;
public override PluginMetadata Metadata { get; } = new()
{
Id = "hello",
Name = "Hello Plugin",
Version = new Version(1, 0, 0),
SdkVersion = SdkInfo.Version,
Author = "you",
Description = "Minimal example plugin."
};
public override void Initialize(IPluginHost host)
{
_host = host;
_host.Logger.Info("Hello plugin loaded.");
}
public override IEnumerable<IPluginCommand> GetCommands()
{
yield return new SayHelloCommand(() => _host);
}
}
internal sealed class SayHelloCommand(Func<IPluginHost> hostAccessor) : IPluginCommand
{
public CommandDescriptor Descriptor { get; } = new()
{
CommandName = "Hello.SayHello",
DisplayName = "Say hello",
Group = "Hello"
};
public ButtonTargets SupportedTargets => ButtonTargets.All;
public Task Execute(CommandContext ctx)
{
hostAccessor().Logger.Info($"Hello from {ctx.Target}!");
return Task.CompletedTask;
}
}A few rules baked into this sample:
- Exactly one concrete
LoupixPluginsubclass per assembly. The host picks it by reflection and ignores everything else. -
Metadata.SdkVersionis alwaysSdkInfo.Version. The host refuses to load a plugin whoseSdkVersion.Majordoesn't match its own. -
CommandDescriptor.CommandNameis the stable identifier persisted into user button configurations. Treat it as a public API — renaming it later breaks every config that referenced it.
Next to the .csproj, create a plugin.json. The host reads this file before
loading the assembly to determine the plugin's identity, SDK compatibility and
which DLL to load:
{
"id": "hello",
"name": "Hello Plugin",
"version": "1.0.0",
"sdkVersion": "1.6",
"entryAssembly": "MyPlugin.dll",
"platform": "Windows"
}| Field | Purpose |
|---|---|
id |
Stable plugin identifier. Must match the folder name under the host's plugin root and the Metadata.Id in your LoupixPlugin subclass. |
name |
Display name shown in the host UI. |
version |
Your plugin's version. Keep in sync with PluginMetadata.Version. |
sdkVersion |
SDK contract version you compiled against. The host enforces a major-version match (a host on SDK 2.x refuses a plugin built against 1.x). |
entryAssembly |
File name of the DLL containing your LoupixPlugin subclass. |
platform |
Target OS: Windows, Linux, or All for cross-platform plugins. Plugins for an OS the current host is not running on are skipped silently. |
Make sure the manifest is copied to the build output by adding the following to
your .csproj:
<ItemGroup>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>dotnet build -c ReleaseThe output lands in bin/Release/net9.0/ and contains both MyPlugin.dll and
plugin.json.
Create a folder named after Metadata.Id inside the host's plugins\
directory (located next to the LoupixDeck executable — see
Debugging for details) and copy your DLL and plugin.json
into it:
<LoupixDeck install dir>\plugins\hello\
├── MyPlugin.dll
└── plugin.json
Start LoupixDeck. Open the command-selection menu on any button — the Hello → Say hello entry should appear. Assign it, press the button, and the host log shows the line.
- For text that updates on a button (clock, sensor value, scene name) → see
IDisplayCommand. - For settings UI (API keys, endpoints) → see Settings Page.
- For dynamic menus listing remote state (OBS scenes, sensors) → see Dynamic Menus.
- To attach a debugger and iterate quickly → see Debugging.
Getting started
API reference
Advanced
Operations
Release notes