PicGo-Core
September 24, 2026 ยท View on GitHub
Special thanks to
ModelflareModelflare: Full strength, stable, nothing watered down. Global SOTA models at a lower cost. |
CastalyCastaly: Full strength, no upscaling. 40+ image and video models, including NSFW. |
NocoBaseAI + No-Code Build reliable business systems |
NeonFast Postgres Databases for Teams and Agents |
PicGo-Core

A tool for image uploading. Both CLI & api supports. It also supports plugin system, please check Awesome-PicGo to find powerful plugins.
More details please see the Homepage of PicGo.
Typora supports PicGo-Core natively.
Installation
PicGo requires Node.js >= 20.19.0 or >= 22.12.0. For older PicGo versions (<= v1.5.x), Node.js >= 16 is sufficient. Cause we need the stability of ES Module support.
Global install
npm install picgo -g
# or
yarn global add picgo
Local install
npm install picgo -D
# or
yarn add picgo -D
Usage
Use in CLI
PicGo uses
SM.MS(S.EE)as the default upload image host.
Show help:
$ picgo -h
Usage: picgo [options] [command]
Options:
-v, --version output the version number
-d, --debug debug mode
-s, --silent silent mode
-c, --config <path> set config path
-p, --proxy <url> set proxy for uploading
-h, --help display help for command
Commands:
install|add [options] <plugins...> install picgo plugin
uninstall|rm <plugins...> uninstall picgo plugin
update [options] <plugins...> update picgo plugin
set <module> [name] [configName] configure config of picgo modules (uploader/transformer/plugin)
upload|u [input...] upload, go go go
use [module] [name] [configName] use module (uploader/transformer/plugin) of picgo
get get current picgo module config (uploader/transformer/plugins)
i18n [lang] change picgo language
uploader manage uploader configurations
server [options] run PicGo as a standalone server
login [token] login to cloud.picgo.app
logout logout from cloud.picgo.app
cloud manage PicGo Cloud
help [command] display help for command
Upload a picture from path
picgo upload /xxx/xx/xx.jpg
Upload with a saved configuration
Use --configName to choose a saved configuration for one upload. Add --uploader when the same name exists in multiple uploader types. You can also use --configId; a unique ID match takes precedence over the name, and an unresolved ID falls back to the name when provided.
picgo upload ./photo.png --configName=Work
picgo upload ./photo.png --uploader=github --configName="Work Images"
picgo upload ./photo.png --uploader=github --configId=your-config-id --configName=Work
# Upload from the clipboard with a saved configuration.
picgo upload --configName=Work
These options use the same lookup rules as HTTP and SDK uploads and do not change saved defaults. Without these options, picgo upload retains its existing default behavior. Existing local input files are retained after upload; only temporary multipart files and clipboard images created by PicGo are cleaned up. Clipboard filenames keep the existing YYYYMMDDHHmmssSSS.png format.
Upload a picture from clipboard
picture from clipboard will be converted to
png
picgo upload
Thanks to vs-picgo && Spades-S for providing the method to upload picture from clipboard.
Run as a server
picgo server -p 36677 -h 127.0.0.1
Select a configuration for one upload
Add uploader, configName, or configId to POST /upload to choose an existing saved configuration for that request. Configuration names are recommended for readability. Use URL encoding for names containing spaces, Chinese characters, or other special characters:
const url = new URL('http://127.0.0.1:36677/upload')
url.searchParams.set('uploader', 'github')
url.searchParams.set('configName', 'Work')
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ list: ['/absolute/path/photo.png'] })
})
const result = await response.json()
The same query parameters work with an empty body for clipboard uploads, JSON without list or with an empty list, and multipart uploads using the files field. If server authentication is enabled, include your existing Authorization: Bearer <secret> header.
| Upload options | Behavior |
|---|---|
| No upload options | Existing default upload behavior. |
uploader=github | Use GitHub's currently selected configuration (defaultId, falling back to its first configuration). |
uploader=github&configName=Work | Find Work within GitHub, ignoring case and surrounding whitespace. |
configName=Work | Search registered uploader types; exactly one configuration must match. |
configId=<id> | Search by exact ID, optionally restricted by uploader. IDs remain stable when configurations are renamed. |
Both configId and configName | Use a unique ID match first; if it cannot be uniquely resolved, try the name. |
Unknown uploaders, missing or ambiguous configurations, and blank or repeated upload parameters return HTTP 400 with { success: false, result: [], items: [], code, message }. Messages explain the lookup failure or ambiguity; specify uploader to disambiguate names shared across types. Invalid upload options never fall back to the global default uploader. Existing authentication failures remain HTTP 401.
Upload options do not change global defaults or save the requested configuration to disk. Concurrent requests can use different configurations. Plugins that read configuration through the context passed to their lifecycle handler see the request's configuration; plugins that cache global configuration may need adaptation. Explicit plugin persistence and Cloud session maintenance retain their normal behavior. uploader=picgo-cloud uses the current Cloud login; these options do not switch Cloud accounts.
Applications providing a custom internal server upload adapter must forward the optional UploadOptions argument to picgo.upload: uploadPaths(paths, options) forwards to picgo.upload(paths, options), and uploadClipboard(options) forwards to picgo.upload(undefined, options). Existing adapters can still handle requests without selectors, but ignoring these options will ignore the requested destination.
Login to PicGo Cloud
picgo login
# or
picgo login <token>
Logout from PicGo Cloud
picgo logout
Check PicGo Cloud login status
Use picgo cloud auth status to inspect the current PicGo Cloud login state without triggering an interactive login. The check is non-blocking: when there is no local token it returns immediately without any network request.
picgo cloud auth status
# machine-readable output
picgo cloud auth status --format json
The command sets a process exit code so it can be used in scripts:
| Status | Meaning | Exit code |
|---|---|---|
logged_in | Token is valid | 0 |
logged_out | No local token | 1 |
invalid | Token exists but is rejected by the server (401) | 2 |
error | Probe failed (network / server error) | 3 |
The --format json output is a single line, e.g.:
{"status":"logged_in","loggedIn":true,"user":"someone","plan":1}
Inspect current module config
Use picgo get to read the currently selected picgo modules. Each subcommand supports --format pretty|json (defaults to pretty).
# current uploader type (resolved as picBed.uploader -> picBed.current -> picgo-cloud)
picgo get uploader
# current transformer (defaults to path)
picgo get transformer
# installed plugins with enabled/disabled state
picgo get plugins
# machine-readable output
picgo get uploader --format json
picgo get plugins --format json
In json mode each command prints a single parseable line, e.g.:
{"uploader":"github"}
{"transformer":"path"}
{"plugins":[{"name":"picgo-plugin-xxx","enabled":true}]}
Manage uploader configs
Since v1.8.0, PicGo-Core supports multiple configurations per uploader. Just like the configuration of the Electron version of PicGo.
You can use picgo set uploader <type> [configName] to configure different uploader configurations.
And you can use picgo use uploader <type> [configName] to switch between different uploader configurations.
For example:
picgo set uploader github Test
picgo use uploader github Test
For more details, you can use picgo uploader -h to check the help of uploader management:
Usage: picgo uploader [options] [command]
Options:
-h, --help display help for command
Commands:
list [type] list uploader configurations
rename <type> <oldName> <newName> rename a config
copy <type> <configName> <newConfigName> copy a config (does not switch current uploader)
rm <type> <configName> remove a config
Init a picgo plugin template
Note: the plugin's template initializer has moved to the standalone picgo-init package.
You can use the following command to init a picgo plugin template:
npx picgo-init plugin <your-plugin-folder>
Use in node project
Common JS
const { PicGo } = require('picgo')
ES Module
import { PicGo } from 'picgo'
API usage example
const picgo = new PicGo()
// upload a picture from path
picgo.upload(['/xxx/xxx.jpg'])
// upload a picture from clipboard
picgo.upload()
The SDK accepts the same selectors in the second argument:
import { PicGo, UploadOptionError } from 'picgo'
const picgo = new PicGo()
try {
await picgo.upload(['/absolute/path/photo.png'], {
uploader: 'github',
configName: 'Work'
})
// A globally unique name can identify both the uploader and its configuration.
await picgo.upload(undefined, { configName: 'Work' })
} catch (error) {
if (error instanceof UploadOptionError) {
console.error(error.code, error.message)
} else {
throw error
}
}
Invalid upload options reject the upload promise before processing inputs. Error codes are INVALID_UPLOAD_OPTION, UNKNOWN_UPLOADER, UPLOAD_CONFIG_NOT_FOUND, and UPLOAD_CONFIG_AMBIGUOUS. Temporary setConfig/unsetConfig calls on a scoped upload context affect that upload only; explicit saveConfig/removeConfig calls remain persistent. Existing SDK calls without upload options keep their behavior.
Development
Use Node.js >= 22.13 and pnpm 11.7.0 for repository development. The package manager is pinned in package.json; pnpm-workspace.yaml records the allowed esbuild installation script. This tooling requirement does not change PicGo's published runtime requirements.
pnpm install --frozen-lockfile
pnpm lint
pnpm test
pnpm build
Documentation
For more details, you can checkout documentation.