Skip to main content

Plugin development quick start

Build an independent plugin with public SDK 3.6.0, compile and package the example, and check activation in an API 3 Host.

This guide targets FolderRewind 1.9 and Plugin API 3.6. App, plugin product, package and assembly versions are independent.

Prerequisites​

Install .NET 10 SDK, Node.js 24 and Python 3.10+, an editor supporting .NET 10, and a Host supporting API 3.6. Get the projects from the website source repository.

Public SDK baseline

The examples use public Abstractions 3.6.0 for API 3.6 and newer compatible Hosts, including FolderRewind 1.9.6 / Host API 3.9. Restore from NuGet.org. If network or version resolution fails, inspect sources and diagnostics rather than referencing FolderRewind.dll. Assembly identity remains 3.0.0.0.

Create an independent library​

dotnet new classlib -n MyFirstPlugin -f net10.0
dotnet add MyFirstPlugin package FolderRewind.Plugin.Abstractions --version 3.6.0

Reference only FolderRewind.Plugin.Abstractions. Set Private="false" on that package reference. Do not reference the application, WinUI, Models or Runtime, or bundle the Abstractions DLL.

Implement the lifecycle​

The following is the buildable MinimalPlugin source:

MinimalPlugin/Plugin.cs
using FolderRewind.Plugin.Abstractions;

namespace MinimalPlugin;

public sealed class Plugin : IFolderRewindPlugin
{
public ValueTask<PluginActivationResult> ActivateAsync(
IPluginActivationContext context, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
return ValueTask.FromResult(PluginActivationResult.Empty);
}

public ValueTask DeactivateAsync(CancellationToken cancellationToken)
=> ValueTask.CompletedTask;
}

During activation, read settings/config snapshots and register capabilities. The Host exposes them only after validation and atomic commit. This minimal lifecycle example contributes no backup command.

Static manifest and settings​

manifest.json
{
"manifestVersion": 3,
"pluginId": "com.example.minimal",
"version": "1.0.0",
"name": "MinimalPlugin",
"description": "API 3.6 documentation example; use test data.",
"author": "FolderRewind documentation",
"pluginApi": {
"major": 3,
"minor": 6
},
"entryAssembly": "MinimalPlugin.dll",
"entryType": "MinimalPlugin.Plugin",
"settingsSchema": "settings.schema.json",
"architectures": [
"any"
],
"configKinds": [],
"requestedHostServices": [],
"capabilities": [],
"artifactFormats": [],
"artifactTransformers": [],
"restoreStrategies": [],
"hasBackupCompletionObserver": false
}
settings.schema.json
{
"schemaVersion": 1,
"settings": []
}

Use manifestVersion 3, pluginApi 3.6 and exact camelCase fields. The entry type is fully qualified. Even a plugin without settings needs a valid empty settings schema.

Build, package and install​

From the website repository root:

node scripts/pack-plugin.mjs MinimalPlugin
Get-FileHash .\artifacts\examples\MinimalPlugin-1.0.0.frplugin -Algorithm SHA256

The ZIP-based .frplugin has manifest.json, settings.schema.json and the entry DLL directly at its root. No Abstractions DLL or extra top-level plugin directory is allowed.

Use local install in plugin management and review the declarations. New installs are disabled; code first runs after explicit Enable. Normal transitions are live; restart only when the Host reports RequiresRestart.

Verify and troubleshoot​

Check product, version, provenance, requested services and runtime state. For failures, check API compatibility, entry type, typed settings and manifest/registration agreement. Enabled intent alone does not prove activation succeeded.

Continue with the tutorial, API reference and packaging guide.