Add Update Checking to Your Blender Add-on
A drop-in Python module that gives any Blender add-on update notifications in two lines. Zero config, free, and you keep hosting your own files.
If you sell a Blender add-on as a .zip, your customers will never be told when you ship a fix. That is structural to how Blender's repositories work, not something you did wrong — but it is fixable from your side in about five minutes.
This is how.
The whole integration
Download addon_update_checker.py and copy it into your add-on. It can sit in the root, in a subfolder, or anywhere up to three levels deep — it walks parent directories to find your blender_manifest.toml.
Then in __init__.py:
from . import addon_update_checker
def register():
# your registration code
...
# register the update checker LAST
addon_update_checker.register()
def unregister():
# unregister the update checker FIRST
addon_update_checker.unregister()
# your unregistration code
...
That is a functioning update check. The module reads your ID and version from the manifest, asks once per session whether anything newer exists, and stores the answer.
The ordering is not stylistic. Register last so the checker sees a fully-registered add-on; unregister first so it releases its classes before yours go away. Getting it backwards produces the class-registration errors that look like a Blender bug and are not.
Showing it to the user
The check on its own is silent. You choose where the notice appears, and there are two supported places.
Preferences panel — the recommended one
Inherit the properties mixin and call one draw helper:
from . import addon_update_checker
class MyAddonPreferences(bpy.types.AddonPreferences,
addon_update_checker.AddonUpdateCheckerProperties):
bl_idname = __package__
my_setting: bpy.props.BoolProperty(name="My Setting")
def draw(self, context):
layout = self.layout
layout.prop(self, "my_setting")
layout.separator()
addon_update_checker.draw_update_section_for_prefs(layout, context)
The mixin is what adds the auc_use_gizmo_notifications property, so the user has a switch for the viewport overlay described below. Skip the mixin and that switch has nowhere to live.
Panel notification
A one-liner in any panel's draw. It renders nothing at all unless an update is actually available, so it costs you no vertical space in the normal case:
class MY_PT_MainPanel(bpy.types.Panel):
bl_label = "My Addon"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "My Addon"
def draw(self, context):
layout = self.layout
addon_update_checker.draw_update_section_for_panel(layout, context)
layout.operator("my.operator")
This is the one most users will actually see, because far more people open your N-panel than open Preferences.
Viewport gizmo overlays
Also available, disabled by default, and it should stay that way. Users can turn it on themselves in preferences if they want it.
Do not enable it for them. An add-on that draws into the viewport uninvited is the kind of thing that gets uninstalled, and the panel notification already does the job without competing for the same space as everyone else's overlays.
When auto-detection is not what you want
Two escape hatches, both optional.
A custom add-on ID, when the manifest ID is not the one you registered:
def register():
addon_update_checker.register(addon_id="my-custom-addon-id")
An explicit parent add-on name, when the module cannot work out which add-on it belongs to — usually in an unusual package layout:
def register():
addon_update_checker.register(parent_addon_name="my_addon_name")
The module also generates its classes dynamically, so several add-ons in the same Blender install can each ship a copy without colliding. That matters more than it sounds: as soon as two of your own add-ons are installed together, a naively-written updater breaks both.
What it does not do
Worth being clear, because it changes whether this fits your setup.
It does not host your files It reports that version 2.4 exists. The download stays wherever you already sell it.
It does not take a cut There is nothing to take a cut of. It never touches a transaction.
It does not require open source Unlike a GitHub-releases updater, nothing about your code needs to be public.
It does not change how you sell Gumroad, your own site, a store, a Patreon tier — all unaffected.
It does not replace Blender's own updates If you ship on extensions.blender.org, Blender already handles this. You do not need it.
Before you ship it
Claim your add-on ID first. Register it on the dashboard so it matches your blender_manifest.toml. IDs are owned — once claimed, nobody else can publish under yours. Publishing add-on updates covers the account side.
Publish the version when you release, not before. The check compares against whatever number is published. Publishing 2.4 before the file is downloadable means a notice pointing at nothing.
Test the "already current" path. The common bug in hand-rolled updaters is a notice that never clears because the version comparison is a string compare, and "2.10" sorts below "2.9".
Say something in your changelog. The notice is more persuasive when it can tell someone what they are getting.
Should you use this or write your own?
Genuinely worth asking, and there are cases where the answer is no.
Ship on extensions.blender.org if you can. Blender handles updates natively there. Nothing here improves on that. The blocker is GPL-compatible licensing, which is why most commercial add-ons cannot.
Use CG Cookie's blender-addon-updater if your source is public. It polls GitHub, GitLab or Bitbucket tags and installs the new version in one click — it does the download step too, which this does not. If your repo is public and tagged, it is a strong option.
Write your own if you want the download step and cannot open your source. It is not a hard problem. Budget for the parts that are annoying rather than hard: not blocking the UI thread, not hammering your server on every startup, version comparison that handles pre-release tags, and behaving when the user is offline.
Use this if you sell a closed-source add-on outside the extensions platform and want the check working this afternoon rather than next weekend.
Why it is free
I sell add-ons, and nearly all of them are .zip downloads with exactly this problem. Building an updater for my own products would have solved my problem and left everyone else's alone. A version anybody can point at is more useful, and charging for it would defeat the point of building it.
There is no paid tier and no plan for one. The full detail is on the features page, and the API reference is public if you would rather call the endpoint directly than use the module.