Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DevToys-app/DevToys/llms.txt

Use this file to discover all available pages before exploring further.

DevToys is built on an open, MEF-based extensibility model. Any developer can ship a .devtoys file — a standard NuGet package renamed with that extension — and DevToys will load it automatically at startup alongside the built-in tools. Extensions can add GUI tools, CLI tools, Smart Detection detectors, custom tool groups, and more, all through the same DevToys.Api contracts used by the app itself.

What is an Extension?

An extension is a .NET class library targeting net8.0 that references the DevToys.Api NuGet package and exports MEF (Managed Extensibility Framework) components. When DevToys starts, it scans its Plugins folder for .devtoys files, extracts them, and uses MEF to discover every exported type inside them. Because the extension model is pure MEF, you use familiar [Export] and [Import] attributes throughout — there is no custom plugin registration API to learn.
// Minimal MEF wiring for a GUI tool
[Export(typeof(IGuiTool))]
[Name("MyTool")]
[ToolDisplayInformation(
    IconFontName = "FluentSystemIcons",
    IconGlyph = '\uE108',
    GroupName = PredefinedCommonToolGroupNames.Converters,
    ResourceManagerAssemblyIdentifier = nameof(MyResourceAssemblyIdentifier),
    ResourceManagerBaseName = "MyProject.Strings",
    ShortDisplayTitleResourceName = nameof(Strings.ShortDisplayTitle))]
internal sealed class MyGuiTool : IGuiTool
{
    public UIToolView View => new(GUI.Stack().Vertical());
    public void OnDataReceived(string dataTypeName, object? parsedData) { }
}

Two Kinds of Tools

GUI Tool

Implements IGuiTool. Renders an interactive UIToolView inside the DevToys window, built entirely with the GUI.* fluent factory API. Supports Smart Detection — the app can automatically route clipboard data to your tool.

CLI Tool

Implements ICommandLineTool. Exposes a sub-command through the DevToys CLI (devtoys.cli). Decorated with [CommandName] and [CommandLineOption] properties; returns an integer exit code from InvokeAsync.
A single extension assembly can export both an IGuiTool and an ICommandLineTool for the same feature. This is the recommended pattern: users get a graphical experience in the desktop app and a scriptable interface from the terminal.

How Extensions Are Loaded

DevToys looks for .devtoys files in the per-user Plugins folder at startup. Each file is a .nupkg renamed to .devtoys; DevToys extracts it and loads all assemblies it finds inside. The process is:
  1. App starts and scans the Plugins folder.
  2. Each .devtoys package is extracted to a temporary installation directory.
  3. MEF composes the extension assemblies together with the host.
  4. Every [Export]-decorated type becomes available in the app — new menu items, CLI commands, and detectors appear immediately.
DevToys must be restarted after installing or uninstalling an extension. The Extensions Manager will show an informational banner reminding you to restart.

IResourceAssemblyIdentifier

Every extension assembly must export exactly one IResourceAssemblyIdentifier implementation. The app uses this to resolve localized strings from your .resx files and to load any custom fonts you bundle.
[Export(typeof(IResourceAssemblyIdentifier))]
[Name(nameof(MyResourceAssemblyIdentifier))]
public sealed class MyResourceAssemblyIdentifier : IResourceAssemblyIdentifier
{
    public ValueTask<FontDefinition[]> GetFontDefinitionsAsync()
        => ValueTask.FromResult(Array.Empty<FontDefinition>());
}
The Name you give this class must match the ResourceManagerAssemblyIdentifier property of every [ToolDisplayInformation] attribute in your assembly.

Key Attributes at a Glance

Every exported component uses a consistent set of MEF metadata attributes. The table below summarizes the most important ones; follow the links in the sidebar for full per-topic documentation.
AttributeApplies toPurpose
[Name("...")]All exportsSets the unique internal component name used by [Order] and cross-component references
[ToolDisplayInformation(...)]IGuiToolIcon, group, localized strings for the sidebar entry
[CommandName(...)]ICommandLineToolCLI sub-command name, alias, and description
[TargetPlatform(Platform.X)]Any exportRestricts the component to Windows, macOS, or Linux; omit to support all platforms
[Order(Before/After = "...")]IGuiTool, GuiToolGroupControls the sort position relative to another named component
[MenuPlacement(MenuPlacement.Footer)]IGuiToolMoves the sidebar entry to the footer instead of the body
[NotSearchable]IGuiToolExcludes the tool from the search index
[NotFavorable]IGuiToolPrevents the tool from being added to favorites
[NoCompactOverlaySupport]IGuiToolDisables Compact Overlay (picture-in-picture) mode for the tool

Explore the Extension SDK

GUI Tool

Build a full interactive tool with IGuiTool and the GUI.* fluent API.

CLI Tool

Expose your tool on the command line with ICommandLineTool.

Smart Detection

Automatically route clipboard content to your tool with IDataTypeDetector.

Settings

Persist user preferences with SettingDefinition and ISettingsProvider.

Publish

Package your extension as a .devtoys file and share it on NuGet.org.

Build docs developers (and LLMs) love