Revit Plugin types

Revit provides three options for plugin types: Command, Application, and DBApplication. They behave differently and appear in different places in the Revit menu.

Command (IExternalCommand)

The Command is the simplest type of Revit plugin. Think of it as a single method for a specific task (e.g., renumbering views, organizing sheets, or placing multiple elements with one click).
In the Revit menu, Commands are always placed under the External Tools button in the Add-Ins tab – you cannot customize this placement. You can only assign the command name and description through the manifest file (more about the manifest file later)
Commands are implemented using the IExternalCommand interface. Below is a simple example of a Command showing the path of the current project.
C#
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;

namespace RevitMastery.Revit
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class RevitMasteryCommand : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			// Get the basic Revit application and the current document objects
			UIApplication uiApp = commandData.Application;
			Document doc = uiApp.ActiveUIDocument.Document;

			// Get the path of the current document
			var documentPath = doc.PathName;

			// Check if the document path is empty. Based on that, prepare the document	message.
			var documentMessage = documentPath == "" ? "The current project is not yet saved." : "The current project path is: " + documentPath;
			TaskDialog.Show("TestPlugin", documentMessage);

			return Result.Succeeded;
		}
	}
}
To make your Command appear in Revit, it must be registered with a manifest file. Each command must be registered separately, which can be tedious for multiple instances.
If you are not sure about the registration process, it is described step-by-step in the Start Revit API Programming Guide.
An example of a Command manifest file:
XML
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
 <AddIn Type="Command">
  <Name>Revit Mastery Command</Name>
  <FullClassName>RevitMastery.Revit.RevitMasteryCommand</FullClassName>
  <Text>Revit Mastery</Text>
  <Description>Revit Mastery plugin as a command.</Description>
  <VisibilityMode>AlwaysVisible</VisibilityMode>
  <Assembly>D:\Repos\RevitMastery\RevitMastery.Revit\bin\Debug\net8.0-windows\RevitMastery.Revit.dll</Assembly>
  <AddInId>b053b38b-79ca-4f56-8f42-4dc890563e78</AddInId>
  <VendorId>Kamil Korus</VendorId>
  <VendorDescription>Kamil Korus from revitmastery.com</VendorDescription>
 </AddIn>
</RevitAddIns>
Commands are great for testing. Just prepare a method and try it. However, as your plugin grows, you may want your custom ribbon and buttons. For these, you need the Application plugin type.

Application (IExternalApplication)

The Application plugin type is what we typically think of as a “plugin.” It allows the creation of custom tabs, buttons, and other Revit menu items (controls). Then, in the code, the controls (e.g., buttons) are linked with specific actions (methods).
The created Revit menu items can be customized and styled. You can add button images, create descriptions, and tooltips. This adds a “styling touch” – nice to have when you create the plugin for yourself, and crucial if you prepare it for a client.
The Application code differs from the Command. The Command “executes” a single method when clicked, while the Application performs actions on Revit’s opening (startup) and closing (shutdown). Typically, it creates custom Revit menu tabs, panels, and buttons and links the buttons with commands (methods) to be fired when clicked. The actual code is then placed in the commands linked with buttons – in the example below the “Show project path” button is linked with the command we created before.
C#
using System.IO;
using System.Reflection;
using System.Windows.Media.Imaging;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI;

namespace RevitMastery.Revit
{
  [Transaction(TransactionMode.Manual)]
  [Regeneration(RegenerationOption.Manual)]
  public class RevitMasteryApplication : IExternalApplication
  {
    public Result OnStartup(UIControlledApplication application)
    {
      var assemblyPath = Assembly.GetExecutingAssembly().Location;

      var ribbonName = "Revit Mastery";
      application.CreateRibbonTab(ribbonName);
      var panel = application.CreateRibbonPanel(ribbonName, "Revit Mastery Panel");

      var buttonData = new PushButtonData(
        typeof(RevitMasteryCommand).FullName, 
        "Show project path", 
        assemblyPath, 
        typeof(RevitMasteryCommand).FullName);
      var button = panel.AddItem(buttonData) as PushButton;
      button.ToolTip = "Shows the localization path of the current project.";
      
      Uri imageUri = new Uri(Path.Combine(Path.GetDirectoryName(assemblyPath), "Resources", "Images", "description_32.png"));    
      BitmapImage image = new BitmapImage(imageUri);
      button.LargeImage = image;            

      return Result.Succeeded;
    }

    public Result OnShutdown(UIControlledApplication application)
    {
      return Result.Succeeded;
    }
  }
}
Similar to Commands, the Application plugin type also must be registered with a manifest file. Conveniently, one Application needs one manifest file, no matter how many buttons or other controls it creates in the Revit menu.
Once again, if you are not sure about the registration process, it is described step-by-step in the Start Revit API Programming Guide.
XML
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
 <AddIn Type="Application">
   <Name>Revit Mastery Application</Name>
   <FullClassName>RevitMastery.Revit.RevitMasteryApplication</FullClassName>
   <Text>Revit Mastery</Text>
   <Description>Revit Mastery plugin as an application.</Description>
   <VisibilityMode>AlwaysVisible</VisibilityMode>
   <Assembly>D:\Repos\RevitMastery\RevitMastery.Revit\bin\Debug\net8.0-windows\RevitMastery.Revit.dll</Assembly>
   <AddInId>a1f29cab-4880-4e59-86b2-c6fbb0dccb92</AddInId>
   <VendorId>Kamil Korus</VendorId>
   <VendorDescription>Kamil Korus from revitmastery.com</VendorDescription>
 </AddIn>
</RevitAddIns>

DBApplication (IExternalDBApplication)

Revit API offers the third possibility, DBApplication. This is the least known plugin type and for a reason (I have yet never used it in practice). It enables adding methods to be fired on Revit’s opening (startup) and closing (shutdown) – similar to the Application, but it has constraints: no possibility to modify Revit UI. Theoretically, there are cases for its use. Practically, given the restrictions, it is rare.

Summary

There are two Revit plugin types used in practice: the simple Command (IExternalCommand) and the more powerful Application (IExternalApplication).
You can always start easily with Commands to test methods without bothering about Revit menu items. Then, you can expand your plugin into an Application and link your Commands with custom buttons.
Do you want to become the Revit Programmer of the Future?