Creating a formatted list of plugins currently installed and whether they are enabled or disabled

I was looking for a clean way to get a list of my currently installed plugins as well as which are enabled/disabled. I also wanted to have them as links to there own pages with the idea being I could regenerate the list whenever I added more plugins (I tend to add none then several at once) and those without already created pages would have ghost links made. I was not able to get it to add the github repo as I couldnt find a consistent place they were listed (manifest files were inconsistent for this). Closest thing I could find to this was the issue of: Create a note from list of installed plugins Its not the cleanest code but figured I would share in case anyone wanted to manage there plugins in a similar way.

The code is below, written in python and executed via the execute code plugin. The vault path is dynamically provided by execute code so it should work without modifications.


import os
import json
import re

def get_value_from_json(file_path, key):
    with open(file_path, 'r') as json_file:
        data = json.load(json_file)
    return data.get(key, None)

community_plugin_folder_path = os.path.join(@vault_path, ".obsidian/plugins")
core_plugins_file_path =os.path.join(@vault_path, ".obsidian/core-plugins-migration.json")
community_plugins_file_path = os.path.join(@vault_path, ".obsidian/community-plugins.json")

plugin_folders = [name for name in os.listdir(community_plugin_folder_path) if os.path.isdir(os.path.join(plugin_path, name))]

#read in list of core plugins and activation state
with open(core_plugins_file_path, 'r') as f:
    core_plugins_dict = json.load(f)
#read in list of enabled community plugins
with open(community_plugins_file_path, 'r') as f:
    community_plugins_list = json.load(f)

key_name = 'name'
key_id = 'id'

community_plugin_name_list = list()

for plugin in plugin_folders:
	file_path = plugin_path + "/" + plugin + "/manifest.json"
	community_plugin_name_list.append((get_value_from_json(file_path, key_name),get_value_from_json(file_path, key_id)))

#split into enabled and not enabled lists. Do both core and community plugins, add (core) or (community) to end for tracking in name
enabled_plugins = list()
disabled_plugins = list()

for key, value in core_plugins_dict.items():

    key += " (core)"

    if value:

for plugin_name, plugin_id in community_plugin_name_list:
	plugin_name += " (community)"
	if plugin_id in community_plugins_list:

#output list of enabled plugins
print(f"Enabled Plugins ")
for name in enabled_plugins:
	name = re.sub(r'[\/\\<>"|?*]', '-', name)
	print(f"- [[{name}]]: ")

#output list of disabled plugins
print(f"Disabled Plugins ")
for name in disabled_plugins:
	name = re.sub(r'[\/\\<>"|?*]', '-', name)
	print(f"- [[{name}]]: ")

The Output it gives for me is:

Enabled Plugins

  • [[Admonition (community)]]:
  • [[Advanced Tables (community)]]:
  • [[Apply Patterns (community)]]:
  • [[Buttons (community)]]:
  • [[Checkbox Reorder (community)]]:
  • [[Creases (community)]]:
  • [[Customizable Menu (community)]]:
  • [[Dataview (community)]]:
  • [[Execute Code (community)]]:
  • [[Hotkeys for templates (community)]]:
  • [[Packrat (community)]]:
  • [[Paste Mode (community)]]:
  • [[Paste URL into selection (community)]]:
  • [[Periodic Notes (community)]]:
  • [[Prominent Bookmarked Files (community)]]:
  • [[Reading Time (community)]]:
  • [[Regex Find-Replace (community)]]:
  • [[Reminder (community)]]:
  • [[Search on Internet (community)]]:
  • [[Tasks (community)]]:
  • [[Templater (community)]]:
  • [[Timestamp Notes (community)]]:
  • [[backlink (core)]]:
  • [[bookmarks (core)]]:
  • [[canvas (core)]]:
  • [[command-palette (core)]]:
  • [[daily-notes (core)]]:
  • [[editor-status (core)]]:
  • [[file-explorer (core)]]:
  • [[file-recovery (core)]]:
  • [[global-search (core)]]:
  • [[graph (core)]]:
  • [[note-composer (core)]]:
  • [[outgoing-link (core)]]:
  • [[outline (core)]]:
  • [[page-preview (core)]]:
  • [[switcher (core)]]:
  • [[sync (core)]]:
  • [[tag-pane (core)]]:
  • [[templates (core)]]:
  • [[word-count (core)]]:
    Disabled Plugins
  • [[Convert url to preview (iframe) (community)]]:
  • [[Excalidraw (community)]]:
  • [[Google Calendar (community)]]:
  • [[Graph Analysis (community)]]:
  • [[Importer (community)]]:
  • [[Ozan’s Image in Editor Plugin (community)]]:
  • [[RSS Reader (community)]]:
  • [[Sliding Panes (Andy’s Mode) (community)]]:
  • [[Tag Wrangler (community)]]:
  • [[Tasks Calendar Wrapper (community)]]:
  • [[audio-recorder (core)]]:
  • [[markdown-importer (core)]]:
  • [[properties (core)]]:
  • [[publish (core)]]:
  • [[random-note (core)]]:
  • [[slash-command (core)]]:
  • [[slides (core)]]:
  • [[workspaces (core)]]:
  • [[zk-prefixer (core)]]:

I plan to add the github url to the right of the :


Thanks. I wanted to do the same thing. But I’m not a programmer. How do I use this code?


  1. Make sure you have Python installed on your system. If you don’t have it, you can get the installation package from the official source
  2. Take note of where the Python interpreter is installed (e.g. /usr/bin/Python)
  3. Install the “Execute Code” Obsidian community plugin
  4. In it’s settings, under “Language specific settings”, select “Python”
  5. In the Python-specific settings which will then display, under “Python path”, insert the information from step 2
  6. In a new note, insert a code block with the type “Python”
  7. In the body of the code block, paste the code from @thomaspholland`s message
  8. Be aware that the code has the same error on two lines; the variable plugin_path has to be replaced with community_plugin_folder_path
  9. Switch to “Reading mode”; if you now move the mouse over the code block, on it’s bottom line, a “run” button should appear
  10. Click the button. If all went well, the list of plugins will be displayed immediately below the code block as shown above.