PicGo-Core

September 24, 2026 ยท View on GitHub

Special thanks to

Modelflare sponsorship

Modelflare

Modelflare: Full strength, stable, nothing watered down. Global SOTA models at a lower cost.

Castaly sponsorship

Castaly

Castaly: Full strength, no upscaling. 40+ image and video models, including NSFW.

NocoBase sponsorship

NocoBase

AI + No-Code Build reliable business systems

Neon sponsorship

Neon

Fast Postgres Databases for Teams and Agents


PicGo-Core

standard GitHub Build Status npm PicGo Convention node

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 optionsBehavior
No upload optionsExisting default upload behavior.
uploader=githubUse GitHub's currently selected configuration (defaultId, falling back to its first configuration).
uploader=github&configName=WorkFind Work within GitHub, ignoring case and surrounding whitespace.
configName=WorkSearch 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 configNameUse 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:

StatusMeaningExit code
logged_inToken is valid0
logged_outNo local token1
invalidToken exists but is rejected by the server (401)2
errorProbe 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.