Skip to content

Blender 2.80: Addon API

Version Info

Make sure the "blender" key in the bl_info dictionary is set to:
(2, 80, 0) not (2, 8, 0) or (2, 79, 0)

Example: "blender": (2, 80, 0),

Otherwise, this error is reported:

Exception: Add-on 'ADDON_NAME' has not been upgraded to 2.8, ignoring


Module Registration

Module registration (bpy.utils.register_module) convenience function has been removed, since keeping track of this information adds unnecessary overhead.

Add-on's should assign their classes to a tuple or list and register/unregister them directly.


classes = (

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

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

Tip: To avoid having to copy & paste the functions above, you can use bpy.utils.register_classes_factory utility function.

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

Tip: If you need to register only one class, then add a trailing "," to the classes list.

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

Otherwise this error is reported:

TypeError: 'RNAMetaPropGroup' object is not iterable

Tip: If you have an addon with many classes, the list can be generated using this patch:

Class Registration

See #52599 for proposal and details.

Access (bpy.types)

Classes registered by addons are no longer available in bpy.types. Instead addons can import their own modules and access the classes directly.

However subclasses of [Header, Menu, Operator, Panel, UIList] remain accessible from bpy.types.


In Blender2.7x it was too easy to accidentally register multiple classes with the same name.

To prevent collisions 2.8x enforces naming conventions (already in use across much of Blender's code-base) for classes bl_idname.

For operator bl_idname, the same naming conventions as in 2.7x remain. For headers, menus and panels, the bl_idname is expected to match the class name (automatic if none is specified).

The bl_idname convention is: UPPER_CASE_{SEPARATOR}_mixed_case, in the case of a menu the regular expression is:


The separator for each identifier is listed below:

  • Header -> _HT_
  • Menu -> _MT_
  • Operator -> _OT_
  • Panel -> _PT_
  • UIList -> _UL_

Valid Examples:

  • class OBJECT_OT_fancy_tool (and bl_idname = "object.fancy_tool")
  • class MyFancyTool (and bl_idname = "MYADDON_MT_MyFancyTool")
  • class SOME_HEADER_HT_my_header
  • class PANEL123_PT_myPanel (lower case is preferred but mixed case is supported).

Class names:

Matching the class name to the bl_idname is optional.

Class Property Registration

Classes that contain properties from bpy.props now use Python's type annotations (see PEP 526) and should be assigned using a single colon : in Blender 2.8x instead of equals = as was done in 2.7x:


class MyOperator(Operator):
    value = IntProperty()


class MyOperator(Operator):
    value: IntProperty()

Using the 2.7x syntax in 2.80 or later will result in this error:

Warning: class Foo "contains a property which should be an annotation!"