How to Register and Unregister a Blender Add-on

This guide explains how to properly register and unregister add-on scripts in Blender using the Python API (bpy). You will learn how to define standard register() and unregister() functions, manage custom classes with bpy.utils, handle multiple classes efficiently, and ensure your script can be cleanly enabled, disabled, and tested within Blender.


The Role of Register and Unregister Functions

Blender uses two dedicated entry-point functions to control add-on lifecycle:

  • register(): Called when the add-on is enabled. It loads your custom operators, panels, menus, and properties into Blender's runtime memory.
  • unregister(): Called when the add-on is disabled or reloaded. It removes all registered elements to prevent memory leaks and UI conflicts.

Both functions are required for any script intended to function as an official Blender add-on.


Basic Single-Class Registration

To register a single class (such as an Operator or Panel), use bpy.utils.register_class() and bpy.utils.unregister_class().

import bpy

class OBJECT_OT_simple_operator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Simple Operator"

    def execute(self, context):
        self.report({'INFO'}, "Operator Executed")
        return {'FINISHED'}

def register():
    bpy.utils.register_class(OBJECT_OT_simple_operator)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_simple_operator)

if __name__ == "__main__":
    register()

Managing Multiple Classes

When an add-on contains multiple classes, define a tuple or list containing all classes, then iterate through it during registration and unregistration. It is best practice to unregister classes in reverse order.

import bpy

# Define custom classes
class MYADDON_OT_action(bpy.types.Operator):
    bl_idname = "myaddon.action"
    bl_label = "Perform Action"

    def execute(self, context):
        return {'FINISHED'}

class MYADDON_PT_panel(bpy.types.Panel):
    bl_idname = "MYADDON_PT_panel"
    bl_label = "My Add-on"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "My Addon"

    def draw(self, context):
        self.layout.operator("myaddon.action")

# Collect classes in an ordered list or tuple
classes = (
    MYADDON_OT_action,
    MYADDON_PT_panel,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()

Alternative: Using register_classes_factory

For larger add-ons with numerous classes, Blender provides a built-in utility function bpy.utils.register_classes_factory that automatically creates standard register and unregister functions from a sequence of classes:

import bpy

classes = (
    MYADDON_OT_action,
    MYADDON_PT_panel,
)

register, unregister = bpy.utils.register_classes_factory(classes)

if __name__ == "__main__":
    register()

Handling Custom Properties

If your add-on attaches custom properties to existing Blender data structures (such as bpy.types.Scene), create them inside register() and delete them inside unregister() using del:

def register():
    bpy.utils.register_class(MYADDON_PT_panel)
    bpy.types.Scene.my_custom_float = bpy.props.FloatProperty(name="Value", default=1.0)

def unregister():
    bpy.utils.unregister_class(MYADDON_PT_panel)
    del bpy.types.Scene.my_custom_float

Testing Directly in the Text Editor

The if __name__ == "__main__": block at the end of the script allows you to test the add-on directly within Blender's Text Editor by clicking Run Script. It registers the classes immediately without requiring you to install or enable the script through the Preferences window.