A single button click to reinstall all community plugins after cloning/pulling git repository that ignores plugins

Use case or problem

I ignore the plugins directory of my Obsidian vault by adding .obsidian/plugins/* to my .gitignore, since it may take 10MB (not a lot in relative size in a video game project, but a lot in a pure textual novel project - also some devs like keeping non-modified third-party code in external repositories rather than copying them).

Obsidian already knows which plugins are used thanks to core-plugins.json and community-plugins.json. While core plugins are pre-installed, community plugins are not, and Obsidian doesn’t exploit the data in community-plugins.json to automatically reinstall those plugins.

It makes sense to wait for user approval to start downloading community plugins due to safety risks and bandwidth usage. However, currently, even after enabling community plugins, user needs to manually search and install every plugin by reading the community-plugins.json file, which may be tedious with 10+ plugins (and require to open a .json with an external editor).

Proposed solution

First, Obsidian could showing the list of expected plugins in the Community plugins section, by reading the lines from community-plugins.json. The plugins would appear in a special section “Configured plugins not installed yet” or “Plugins to install” (you can find a better wording) shown above or below the “Installed plugins section”.

One button “Install” to the right of each entry would allow the user to install each plugin easily.

One button at the top “Install all” would even allow them to install all the plugins at once.

Possible difficulty: plugins installed via BRAT, as they would need to go through BRAT. But even if not supported, that would fix 90% of the issue and BRAT devs could then implement an extra button to install the remaining plugins.

Current workaround (optional)

a. Open .obsidian/community-plugins.json, read each line marked “true”, search corresponding plugin (knowing that “ID name” in json is not always 100% matching Readable Name), install, enable
b. (not tested) Follow Reinstall plugins without losing configuration setting the version of each plugin to 0, and force update of all plugins

Related feature requests (optional)

For the “set version to 0” technique we mentioned above

Some users troubled with what to put in gitignore and mentioning they also have a heavy plugins folder.

I have the same issue. I cloned the vault from my github but none of the plugins are installed. This is my .gitignore

# Exclude plugins
.obsidian/plugins/*/*

# Do not exclude the plugins config files
!.obsidian/plugins/*/data.json

# Exclude themes data (actually selected theme is in .obsidian/appearance.json, so it is versioned)
.obsidian/themes

# Exclude workspace cache
.obsidian/workspace.json

# Exclude workspace cache specific to mobile devices
.obsidian/workspace-mobile.json

# Exclude OS settings and caches
.trash/
.DS_Store

It would be nice to see (and be able to copy) the plugin id on the plugin’s page when browsing community plugins.
It would also to be able to search by plugin id.
It would also be nice to have an obsidian URI to install a plugin given its id. Example : obsidian://install-plugin?id=obsidian-excalidraw-plugin

I found a solution workaround!

Use the following script for Linux/Mac users. (I haven’t tested on Mac but it should work.) Create a file called open-plugins.sh at the root of your vault folder, paste the following script and run it from a terminal.

This script will read your community plugins file, open each plugin’s page in Obsidian successively, you only need to click “Install” and “Enable”. Then go back to the terminal, press a key and install the next one! No more searching for plugins!

#!/usr/bin/env bash

# Detect platform and set open command
if [[ "$(uname)" == "Darwin" ]]; then
  OPEN_CMD="open"
else
  OPEN_CMD="xdg-open"
fi

# Read the community plugins from the obsidian vault at `.obsidian/community-plugins.json`
sed -e 's/[][]//g' -e 's/[",]//g' -e '/^\s*$/d' -e 's/^[[:space:]]*//' -e 's/^/obsidian:\/\/show-plugin?id=/' .obsidian/community-plugins.json | while read -r line; do
  echo "$line"
  # Open the plugin link in Obsidian
  $OPEN_CMD "$line" &>/dev/null
  # Wait for the user to press a key before continuing
  read -n 1 -s -r -p "Press any key to continue..." </dev/tty
  # Clear the line
  echo
done

For Windows users, create the file open-plugins.bat and paste this instead (I haven’t tested it because I don’t have a Windows machine at the moment) :

@echo off
REM !!!!! Untested script! I don't have a Windows machine to test it on. !!!!!

REM Read the community plugins from the obsidian vault at `.obsidian/community-plugins.json`
for /f "usebackq delims=" %%A in (`powershell -NoProfile -Command ^
    "Get-Content .obsidian/community-plugins.json | `
    Select-String -NotMatch '^\s*(\[|\]|,|$)' | `
    ForEach-Object { $_.ToString().Trim().Trim('""',',') }"`) do (
    set "plugin=%%A"
    setlocal enabledelayedexpansion
    set "url=obsidian://show-plugin?id=!plugin!"
    echo !url!
    REM Open the URL in Obsidian
    start "" "!url!"
    REM Wait for a key press before continuing
    pause
    endlocal
)

I’ve been using this little script to initialize plugins after cloning my vault. You can just run it in the Obsidian dev tools, it will switch off “safe mode”, download, and enable plugins in community-plugins.json. It uses a bunch of internal APIs so it might stop working later, but its worked pretty well for me so far :sweat_smile:.

async function installPlugin(pluginId) {
    const github = "https://raw.githubusercontent.com";
    const communityPluginsUrl = `${github}/obsidianmd/obsidian-releases/HEAD/community-plugins.json`;
    const plugins = await fetch(communityPluginsUrl).then(r => r.json());
    const info = plugins.find(p => p.id == pluginId);
    if (!info) {
        console.log(`Plugin ${pluginId} not found`);
    } else {
        console.log(`Installing plugin ${pluginId}`);
        const manifestUrl = `${github}/${info.repo}/HEAD/manifest.json`;
        const manifest = await fetch(manifestUrl).then(r => r.json());
        await app.plugins.installPlugin(info.repo, manifest.version, manifest);
        await app.plugins.enablePlugin(pluginId);
    }
}

async function installPlugins() {
    // Turn off restricted mode
    if (!app.plugins.isEnabled()) {
        await app.plugins.setEnable(true)
    }

    // Install all the plugins in community-plugins.json that aren't installed
    for (const pluginId of app.plugins.enabledPlugins) {
        if (!app.plugins.manifests.hasOwnProperty(pluginId)) {
            await installPlugin(pluginId);
        }
    }
}

await installPlugins()

I like your solution better because it’s actually platform agnostic.
How do you access the devtools ?

CTRL+Shift+I will open up the devtools and then you can just paste stuff in the console.

Somewhat related you might want to look at either the Settings management plugin, which helps changing the configuration quickly. Not sure if you can copy it out and into other vaults easily, but it’s worth taking a look.

Or possibly the Sync config folder to common folder plugin might be of aid, as it can copy all of the config into a common folder, which then should be easier to copy/sync, and which then can be used as a base for the next vault.

I wrote this plugin when I encountered the issue of needing to download missing plugins and configure them according to a configuration file upon launching Obsidian. It might be useful for you as well.

Thanks, I used the API level script in the console (checked the script one more time before allow pasting, as usual for safety), and it worked!

Thanks, from now on I’ll track data.json to keep my plugin config too.

I made sure to ignore .obsidian/plugins/*/* on the line before, not .obsidian/plugins/* or .obsidian/plugins/** which would exclude the whole plugin folders and prevent re-inclusion of data.json.

# Exclude plugins
.obsidian/plugins/*/*

# Do not exclude the plugins config files
!.obsidian/plugins/*/data.json

I haven’t tried it yet (just needed a quick script for the rare case when I change machine), but it looks very useful!

It seems only available on GitHub, is it because of its particular status of “meta plugin” that needs access to plugin data in upper and sibling folders so that it couldn’t be installed as a community plugin (which wouldn’t have access to other plugin folders for security reasons)?


Sorry for the late reply — it’s in Community plugins now: Community Install Manager (current release v1.2.1). Not blocked as a “meta plugin”; earlier it was GitHub-only because of the review queue.

You don’t need plugin data.json or binaries in git.
Settings and Plugins live in the installer’s own JSON files.

On the working machine

  1. Install Community Install Manager from Browse and enable it.
  2. Open Settings => Community Install Manager.
  3. Click Export.
  4. Commit these two files:
    • .obsidian/community-plugins-list.json
    • .obsidian/community-plugins-settings.json
  5. You don’t need to keep anything under .obsidian/plugins/ in git - not the plugin binaries and not each plugin’s data.json. The two JSON files above are enough. Whenever the setup changes, run Export again so the list and settings stay up to date in those files.

On a new machine after clone

  1. Open the cloned vault in Obsidian (Restricted mode off).
  2. Browse => install only Community Install Manager => Enable.
  3. Open Settings => Community Install Manager.
  4. Optional: click Preview first. It’s a dry-run - shows which plugins will be installed, skipped (already there), or re-pinned (wrong version), and whether settings would be applied. Nothing is downloaded or changed yet, so you can check the list before Import touches the vault.
  5. Click Import when the preview looks right.