Obsidian Automatic Image Upload: PicGo-Core Integration with Chevereto Image Hosting in Practice
This article was last updated 220 days ago. The information herein may have developed or changed. If anything is outdated, please leave a comment in the comments section.
Article Abstract
To resolve the issue of frequent errors when using the Obsidian plugin with the PicGo App to upload images to the Chevereto image hosting service under macOS, stable uploading is achieved by switching to PicGo-Core. This solution adopts a local installation method to bypass system permission restrictions, utilizing the Node.js core engine to directly call the Chevereto API, thereby eliminating cross-application communication. The configuration process includes creating a custom directory, manually initializing config.json, interactively setting upload parameters, and double-verifying the availability of the image hosting API via curl and PicGo-Core. Ultimately, this enables seamless invocation by the Obsidian “image auto upload” plugin, improving the stability and automation of image uploading during writing, which is especially suitable for blog writing scenarios that rely on local image hosting for disaster recovery backup.
Qwen3-14B · 2026-06-18

1 Introduction

I usually use Obsidian (Markdown) under macOS to write blogs. During the writing process, inserting images is inevitable, so the image hosting solution has become an unavoidable issue.

My blog's final image hosting is hosted on Cloudflare R2 , but to achieve disaster recovery backup, the actual workflow is slightly more complex: when I write, images are first uploaded to the self-hosted Chevereto image hosting(Reference article:Tips & Tricks Series: Achieving Efficient Image Uploading and URL Retrieval with Chevereto + PicGo + Obsidian), and then synchronized and copied to R2 via rclone (Reference article:Home Data Center Series: Building an Off-site Disaster Recovery Image Hosting for Chevereto Using rclone and Cloudflare R2)。

In other words, when writing locally, I have always relied on the Chevereto image hosting in my local network, and how to smoothly upload images inserted in Obsidian to Chevereto and generate linksrelies on the Image Auto Upload plugin in Obsidian working with PicGo App to complete:

image.png

The key player is thisImage Auto Uploadplugin. If you select “PicGo(App)” as the default uploader in the plugin settings (as shown above), it works fine in most cases. However, the problem is that it occasionally throws errors for no apparent reason:

upload failed, check dev consol

as shown below:

image.png

This issue is not uncommon; a quick Google search reveals a ton of similar feedback:
image.png

Common “solutions” are nothing more than: restarting Obsidian, disabling/enabling the plugin, restarting the entire system, or simply uninstalling and reinstalling the PicGo App. But essentially, this is caused by unstable communication between the Image Auto Upload plugin and the PicGo App. I have encountered this a few times myself, and restarting macOS usually restored it, so I didn't bother to look into it deeply.

However, after recently upgrading the OS version of my m4pro Mac mini to Tahoe 26, this familiar bug appeared again:“upload failed, check dev consol”. To be honest, this kind of minor issue has happened more than once. Every time, I either had to restart or reinstall the plugin, which was quite annoying. That being the case, I decided to stop struggling with the PicGo App and switch directly to another upload mode supported by the plugin:PicGo-Core。

This method completely bypasses the desktop App, does not rely on the local loopback interface, and instead directly calls the core upload logic of Node.js. It is cleaner and eliminates intermediate steps that could go wrong.


💡 Supplementary Note:

PicGo-Core It can be understood as the “command-line core version” of PicGo: it is not a desktop application with a GUI, but a Node.js-based upload engine. All image hosting upload logic is executed by it, and the plugin only needs to call it directly.

In contrast,PicGo App is more like a UI wrapper for PicGo-Core, and the plugin needs to communicate with it via the local loopback interface. This introduces two problems: first, some systems/browsers restrict local communication; second, the communication chain has an extra layer, making it more prone to errors.

Therefore, the advantages of PicGo-Core are: lightweight, direct, independent of local Apps, capable of running even in headless server environments, and offering higher stability.


2 Installing PicGo-Core under macOS

1 Overview

Generally speaking, the advantage of global installation (sudo npm install -g picgo) is that the command is available everywhere, allowing you to type picgo directly in any directory. However, the disadvantage is also obvious: configuration paths and dependency paths are scattered across system directories. Once the system or Node.js version is upgraded, permission issues or missing paths may occur.

On the other hand, local installation (installing to the user directory, such as ~/.picgo/) is more “self-sufficient”: configuration files, plugins, and the core program are all concentrated in one place. Even if the system is upgraded or permission rules change, it won't be heavily affected. The only “cost” is that you have to remember to call its full path (e.g., ~/.picgo/node_modules/.bin/picgo), but this can be easily resolved through plugin settings or an alias.

Especially on M-series chip macOS (such as my m4pro Mac mini) , global installation often runs into issues:

  • The system tightens write permissions for directories like /usr/local/lib, so sudo npm install -g either throws an error directly or installs successfully but cannot be found by the Obsidian plugin.
  • Obsidian plugins run in the Electron sandbox, and sometimes they cannot read the global PATH of your shell environment. As a result, even though it is installed, the plugin still reports “picgo not found”.
  • Even if it barely runs, the global path is prone to becoming invalid after upgrading Node or macOS.

For example:

image.png

Therefore, after struggling with the pitfalls of ”global installation” for a long time, I finally choselocal installation, which is more stable and better aligns with macOS's trend of “gradually tightening permissions”.

2 Installing Homebrew and Node.js (Optional)

Since npm is required to install picgo-core and related plugins, and npm is the package manager for Node.js, which is not integrated into macOS by default, you need to install Node.js first.

  1. Install brew(Optional, can be skipped if already installed)

On macOS, directly go to the official page link on GitHub (https://github.com/Homebrew/brew/releases/download/) to download the pkg installer. The current latest version is 4.5.15. After downloading, just click to install.

Note: I am used to using brew to install Node.js. If you have already installed brew, you can skip this step.

  1. Install Node.js

Run the following command to install Node.js v20:

brew install node@20

Currently, some dependencies of PicGo are still based on CommonJS, while newer versions of Node.js have stricter ESM module loading policies. In a Node 22+ environment, an ERR_REQUIRE_ESM error may occur. Therefore, using Node.js 20 LTS can avoid this issue.

If you have already installed Node 22+ and encounter the ERR_REQUIRE_ESM error when PicGo starts, the solution is to install Node.js 20 LTS. You can refer to the following steps:

brew install node@20
brew link node@20 --force --overwrite

Then use the following steps to confirm:

node -v
which node

If successful, it will output something like:

v20.20.1
/opt/homebrew/bin/node

3 Installing PicGo-Core and Chevereto Plugin via Local Installation

  1. Create directory

It is recommended to place the local mode of PicGo-Core in the user's home directory under the .picgo folder:

mkdir ~/.picgo
  1. Create a valid package.json file

Directly in the~/.picgofolder, create a new package.json file:

touch ~/.picgo/package.json

The content is as follows:

{
  "name": "picgo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "picgo": "^1.5.9",
    "picgo-plugin-chevereto": "^1.1.0"
  }
}

Note: The reason for not using thenpm init -ycommand to initialize package.json is that in newer versions of Node.js / npm (such as Node 24 with npm 11), if the name field in package.json starts with a dot (i.e., .picgo), it will be judged as an invalid name, directly causing npm init -y to report an error like: ”Invalid name: ‘.picgo'”. However, for Obsidian to work properly with PicGo-Core, it requires the main directory of PicGo to be~/.picgo(this is a very deep pitfall that took me several days to figure out~), so we can only manually create the package.json file.

  1. Install PicGo-Core and plugins

Install PicGo-Core and the required plugins in this directory (using the Chevereto plugin as an example here):

cd ~/.picgo
npm install picgo picgo-plugin-chevereto

image.png

  1. Confirm installation path

After installation, the executable file of PicGo-Core will be at~/.picgo/node_modules/picgo/bin/picgo, which can be confirmed with the following command:

ls -l ~/.picgo/node_modules/picgo/bin/picgo

image.png

Later, in the settings of the WordPress plugin image auto upload , as long as you specify this path, you can directly call PicGo-Core to upload images.

4 Configuring the ”picgo-plugin-chevereto” Plugin

After installing PicGo-Core locally and introducing the picgo-plugin-chevereto plugin, you need to configure the plugin's uploader to upload images to the Chevereto image hosting service. Through the command-line tool provided by PicGo-Core, you can interactively set up the uploader information.


It is worth noting that, in theory, when running the picgo set uploader chevereto command, PicGo-Core will prompt you interactively to enter Chevereto's API URL and Key, automatically generate or update the configuration to the configuration file (config.json), and write the PicGo-Core plugin information to complete the initialization of the uploader. However, in some environments, such as using a non-default directory (like ~/picgo instead of ~/.picgo) or other system differences, this command may fail to generate the configuration file properly, throwing a “No uploader named chevereto” error, similar to:

mac_1759281205765.png

In this case, you can first manually create a valid config.json file (which feels a bit like overcomplicating things~), and then explicitly specify the configuration file path in the command. This way, PicGo-Core can correctly load the plugin and uploader, ensuring no issues occur when the Obsidian plugin calls it.


First, create a config.json configuration file:

touch ~/.picgo/config.json 

The configuration file format is demonstrated using my own setup (the content after url and key can be real or not, because the main purpose of the config.json file here is just to allow thepicgo set uploader cheveretocommand to enter the interactive setup process normally):

{
  "picBed": {
    "uploader": "chevereto",
    "chevereto": {
      "url": "http://192.168.10.99:8090/api/1/upload",
      "key": "1234567890",
      "source_param": "",
      "url_param": ""
    },
    "current": "chevereto"
  },
  "picgoPlugins": {
    "picgo-plugin-chevereto": true
  }
}

Then use the following command format to set up the uploader:

~/.picgo/node_modules/.bin/picgo set uploader chevereto --config ~/.picgo/config.json

After execution, you will be prompted in turn to enter Chevereto's API URL, API Key, upload file field name, and other information:

image.png

Note: During the interactive setup process, if the content after the url and key fields in the config.json file is real information, you only need to press Enter throughout; if it is not real information, you will need to manually enter the real content during the setup process.

5 Verifying PicGo-Core Upload Functionality

After completing the installation and plugin configuration of PicGo-Core, the first step is to verify whether the image hosting API is working properly. You can first use the curl command to directly call the Chevereto API to upload an image and confirm that the server-side interface has no issues. Taking my Chevereto image hosting address as an example (the first-Fflush privileges;xxxxxxxxis the key corresponding to the Chevereto image hosting album):

curl -X POST "http://192.168.10.99:8090/api/1/upload" \
  -F "xxxxxxxx" \
  -F "source=@/Volumes/data/ishot/chatgpt.png"

If the upload is successful, the terminal will return JSON data similar to the following, which contains the image URL (the actual URL is in a regular format):

{
  "success": true,
  "image": {
    "url": "http://192.168.10.99:8090/images/2025/09/19/chatgp.png",
    ...
  }
}

As shown in the figure below:

image.png

After confirming that the API is available, you can use PicGo-Core to perform an upload test. Since we installed it locally to ~/.picgo/, the command is as follows:

~/.picgo/node_modules/.bin/picgo upload /Volumes/data/ishot/chatgpt.png --config ~/.picgo/config.json

If PicGo-Core is configured correctly, a success prompt will be displayed in the terminal after the upload is complete, and the image URL will be returned, similar to the following:

[PicGo SUCCESS]: 
http://192.168.10.99:8090/images/2025/09/19/chatgptc13e706aae1fefad.png

As shown in the figure below:

image.png

Through these two verification steps, we can confirm that:

The Chevereto API is working normally

PicGo-Core and the picgo-plugin-chevereto plugin are configured correctly and can successfully upload images

The subsequent Obsidian “image auto upload” plugin calls to PicGo-Core for uploading can also smoothly generate image URLs


The purpose of using curl to test the API first is to confirm that the image hosting interface itself is available, ruling out network or Chevereto configuration issues. Since PicGo-Core's actual upload also relies on the same API, if the curl test fails, PicGo-Core will not succeed no matter how it is configured. The reason for adding this step is that after upgrading the M1 Mac mini, which deploys the Chevereto image host, to Tahoe 26, Docker Desktop for Mac malfunctioned due to insufficient space on the built-in 256G hard drive. This happened to cause issues with the Chevereto container, which took me quite a while to troubleshoot.

Next, use the PicGo-Core command lineto upload, verifying whether the plugin and the local core program are running correctly and can generate the image URLs required by Obsidian. This sequence also facilitates troubleshooting: first confirm the server side is normal, then confirm the local PicGo-Core configuration is correct, thereby ensuring that subsequent Obsidian plugin calls will not fail due to interface or local environment issues.


6 Obsidian “image auto upload” Plugin Settings

At this point, only one last step remains: modify the ”image auto upload” plugin settings in Obsidian, which requires changing 3 places:

Change the default uploader to ”PicGo-Core”

Fill in the PicGo-Core path with the path of the locally installed PicGo-Core:

~/.picgo/node_modules/.bin/picgo

And turn on the ”Modify PATH” option

As shown in the figure below:

image.png

With this, everything is complete, and you can once again happily take screenshots with iShot and paste them directly into Obsidian.

3

4 Afterword

This hassle is actually a typical example:A seemingly insignificant minor issue, yet behind it lies a chain of details involving plugin invocation methods, inter-app communication, and system security policiesand so on. Previously, when writing, I used the PicGo App in conjunction with the Obsidian plugin. Although it occasionally threw errors, restarting usually resolved most of them. However, after upgrading to Tahoe 26 this time, the “upload failed, check dev consol” error appeared again, which finally made me resolve to stop procrastinating, thoroughly sort out the entire chain, and look for a more reliable alternative.

Ultimately, switching to PicGo-Coreactually made the process much cleaner: there is no cross-app API communication, nor any reliance on local loopback interfaces; all logic is executed directly by the Node.js core program. As a result, the Obsidian plugin only needs to call the core functionality, raising both stability and controllability to a new level.

In terms of positioning,PicGo App is more suitable for users accustomed to visual configuration and drag-and-drop uploading; while PicGo-Core is more tailored for command-line users and automation scenariosStrictly speaking, there is no absolute superior or inferior between the two, but in terms of my own experience,PicGo-Core's stability and controllability are clearly far superior, especially in high-frequency, continuous scenarios like writing, less tinkering and fewer errors are what matter most.

For me, the rhythm of writing is more important than anything else, and tools should be a quiet and reliable presence. Now that this Obsidian + PicGo-Core + Chevereto workflow is running smoothly, at least for the foreseeable future, my train of thought won't be suddenly interrupted by "upload failed" again.

After all the tinkering, it actually proves an old truth:Sometimes, instead of constantly patching up old solutions, it's better to change perspective and simply take a more stable path.。


By the way,the steps for deploying and configuring PicGo-Core and the Obsidian plugin under Windows are generally similar, just install Node.js first, then perform local or global installation, plugin configuration, and upload testing. However, the Windows environment may encounter some minor pitfalls, such as path separators, administrator privileges, firewalls, or antivirus software blocking Node.js network access. Since I don't usually do my main writing on Windows and am too lazy to verify these details, this article won't expand on Windows platform operations. In contrast,installing PicGo-Core locally on macOS is more convenient and involves less tinkering, which is also why this platform was chosen for practice in this article.


View Related Categories · 3 Matches
📌 Content Structure Prompt:
This content is part of the following knowledge map, where you can view the complete content path: Blog Knowledge Map。
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews