Skip to content

Configuration ​

PicGo requires a configuration file to run. If you don’t specify one, PicGo will start with the default config file.

Default config file ​

The default config file is ~/.picgo/config.json, where ~ is your home directory.

  • Linux and macOS: ~/.picgo/config.json
  • Windows: C:\Users\<your-username>\.picgo\config.json

Generate automatically ​

In most cases you only need to configure an Uploader, so you can run picgo set uploader to enter the interactive prompt. After configuration succeeds, PicGo will generate the config file automatically—no copying/pasting required. For more commands, see CLI Commands.

Note

After configuring your image host, don’t forget to select the uploader you want to use via picgo use uploader.

bash
$ picgo set uploader
? Choose a(n) uploader (Use arrow keys)
  smms
❯ tcyun
  github
  qiniu
  imgur
  aliyun
  upyun
(Move up and down to reveal more choices)

Create manually ​

If you want to create the config file manually, you need to create the directory and JSON file yourself, and at minimum include the following fields (this is why the CLI-generated config is recommended):

json
{
  "picBed": {
    "uploader": "picgo-cloud", // the default image host is PicGo Cloud
    "current": "picgo-cloud"
  },
  "settings": {
    "picgoCloud": {
      "token": "" // automatically written after picgo login, or you can fill in an existing token manually
    }
  },
  "picgoPlugins": {} // reserved for plugins
}

If you already have a PicGo Cloud token, you can fill it in the token field directly. Otherwise, run picgo login and the token will be written automatically.

picBed ​

As PicGo’s most important configuration section, picBed contains the currently selected image host and the configuration for all image hosts.

Plugin authors

If an Uploader is named xxx, its configuration should be placed under picBed.xxx. This is important for the PicGo Electron app to render configuration UI.

picBed.uploader ​

  • type: string
  • default: picgo-cloud

Indicates which image host is currently selected. The default is picgo-cloud.

picBed.current ​

Same purpose as picBed.uploader. This exists mainly for compatibility with the PicGo Electron app and may be removed in the future.

picBed.smms 1.4.7+ ​

Configuration for the SM.MS uploader (now migrated to S.EE). The service is now paid (no longer the original free plan). Get your token from S.EE Dashboard. You can also refer to PicGo’s wiki.

Migration note

If you previously configured backupDomain with an old domain (for example smms.app or sm.ms), remove this field or change it to s.ee; otherwise uploads may fail.

Defaults:

json
{
  "token": "", // API token from https://s.ee/user/dashboard/
  "backupDomain": "" // optional; keep empty to use default s.ee
}

picBed.qiniu ​

Configuration for the Qiniu image host. Refer to PicGo’s wiki.

Defaults:

json
{
  "accessKey": "",
  "secretKey": "",
  "bucket": "", // bucket name
  "url": "", // custom domain
  "area": "z0" | "z1" | "z2" | "na0" | "as0", // region code
  "options": "", // URL suffix, e.g. ?imgslim
  "path": "" // custom storage path, e.g. img/
}

picBed.upyun ​

Configuration for UpYun. Refer to PicGo’s wiki.

Defaults:

json
{
  "bucket": "", // bucket name / service name
  "operator": "", // operator
  "password": "", // password
  "options": "", // image processing options
  "path": "", // custom storage path, e.g. img/
  "url": "" // CDN domain, must include http:// or https://
}

picBed.tcyun ​

Configuration for Tencent Cloud COS. Refer to PicGo’s wiki.

Defaults:

json
{
  "secretId": "",
  "secretKey": "",
  "bucket": "", // bucket name (differs between v4 and v5)
  "appId": "",
  "area": "", // region, e.g. ap-beijing-1
  "path": "", // custom storage path, e.g. img/
  "customUrl": "", // custom domain, must include http:// or https://
  "version": "v5" | "v4" // COS version: v4 or v5
}

picBed.github ​

Configuration for using GitHub as an image host. Refer to PicGo’s wiki.

Defaults:

json
{
  "repo": "", // repo in the form username/reponame
  "token": "", // github token
  "path": "", // custom storage path, e.g. img/
  "customUrl": "", // custom domain, must include http:// or https://
  "branch": "" // branch name, default is main
}

picBed.aliyun ​

Configuration for Alibaba Cloud OSS. Refer to PicGo’s wiki.

Defaults:

json
{
  "accessKeyId": "",
  "accessKeySecret": "",
  "bucket": "", // bucket name
  "area": "", // region code
  "path": "", // custom storage path
  "customUrl": "", // custom domain, must include http:// or https://
  "options": "" // image processing options (PicGo 2.2.0+ / PicGo-Core 1.4.0+)
}

picBed.imgur ​

Configuration for Imgur. Refer to PicGo’s wiki.

Imgur app creation is no longer available

Imgur no longer supports creating new apps. This configuration only works for users who already have an existing clientId; new users can no longer obtain a clientId through the old app creation flow.

Defaults:

json
{
  "clientId": "", // Imgur clientId
  "proxy": "" // proxy address (HTTP proxy only)
}

picBed.proxy ​

Custom proxy configuration. PicGo uses request for network requests (image uploading, etc.). picBed.proxy is used as request’s proxy option. Only HTTP proxies are supported. An empty value means no proxy.

Example:

json
{
  "proxy": "http://127.0.0.1:1081",
}

uploader 1.8.0+ ​

PicGo supports multiple named configurations per uploader type.

The source of truth is stored under uploader.<type>:

  • uploader.<type>.configList: an array of configs.
  • uploader.<type>.defaultId: the _id of the active config.

Each item in configList includes metadata fields:

  • _id (UUID v4)
  • _configName (unique within the same uploader type, case-insensitive)
  • _createdAt / _updatedAt (timestamps)

For plugin compatibility, picBed.<type> is a read-only mirror of the active config and will be overwritten when you switch configs.

Migration

If you previously configured an uploader under picBed.<type>, PicGo migrates it automatically on startup.

Example:

json
{
  "uploader": {
    "github": {
      "defaultId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "configList": [
        {
          "_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
          "_configName": "Work",
          "_createdAt": 1700000000000,
          "_updatedAt": 1700000000000,
          "repo": "user/repo",
          "token": "******"
        }
      ]
    }
  }
}

To manage or switch configs, see CLI Commands (picgo use uploader ..., picgo uploader ...) or use the Node.js API (ctx.uploaderConfig).

Note

ctx.uploaderConfig.use, createOrUpdate, copy, rename, and remove persist their changes. listUploaderTypes, getConfigList, and getActiveConfig are read-only queries. To use an existing configuration for just one upload, use the upload options below.

Per-upload configuration 3.1.0+ ​

Starting with PicGo-Core 3.1.0, you can specify an uploader type, configuration name, or configuration ID for each upload without first running picgo use uploader. This does not change the default uploader, any uploader's active configuration, or the local configuration file. The next upload without these options still uses the original defaults.

All three entry points use the same parameter names and lookup rules: CLI flags --uploader / --configName / --configId, query parameters of the same names on HTTP /upload, and fields in picgo.upload(input, options).

ParameterPurpose
uploaderA registered uploader type, such as github. When provided, lookup is limited to that type.
configNameThe name of a saved configuration. Matching ignores surrounding whitespace and letter case. Chinese names are supported.
configIdThe _id of a saved configuration, matched exactly. The ID stays the same when the configuration is renamed.

Use the more readable configName for everyday calls. Names only need to be unique within an uploader type; different types can have configurations with the same name.

Options providedConfiguration used
None of the three parametersThe existing default configuration, without creating a configuration copy or overriding the default uploader.
Only uploaderThe configuration referenced by that type's defaultId; if the ID is missing or invalid, the first configuration of that type.
uploader with configName or configIdThe matching configuration within the specified uploader type.
Only configName or configIdSearch all registered uploader types; exactly one configuration must match.
Both configId and configNameUse a unique ID match first. If the ID cannot be uniquely matched, try the name.

Parameters must be non-empty strings. If no configuration matches or the final result is ambiguous, PicGo reports an error instead of silently using the default uploader. An unregistered uploader also causes an error rather than expanding the search to other types. Specifying only an uploader type with no saved configuration fails, except that picgo-cloud can use the current login without a saved uploader configuration. These options do not switch PicGo Cloud accounts.

To find a configuration ID, inspect uploader.<type>.configList in the local configuration file or call picgo.uploaderConfig.getConfigList(type), then use the relevant entry's _id. These parameters reference saved configurations; they are not a way to pass uploader credentials such as tokens in the URL.

See the examples for CLI uploads, HTTP uploads, and Node.js uploads.

Configuration isolation and persistence

Uploads with these options use independent configuration copies, so concurrent requests can use different configurations. Plugins that explicitly call saveConfig / removeConfig still write to the configuration file. The guarantee of not changing saved configuration applies to choosing the upload destination itself. See Per-upload context for plugin integration details.

picgoPlugins ​

This section stores all plugin names and is mainly used to determine whether a plugin is enabled or disabled. It is generated by PicGo automatically—you don’t need to edit it.

Example:

json
{
  "picgo-plugin-xxx": true, // enabled
  "picgo-plugin-yyy": false // disabled
}

settings ​

General settings not tied to a specific uploader/transformer/plugin.

settings.server 2.0+ ​

Local server settings (used by picgo server and programmatic server startup).

  • settings.server.port (number | string): preferred port. Defaults to 36677.
  • settings.server.host (string): bind host. Defaults to 127.0.0.1.
  • settings.server.secret (string, optional): shared secret for local server authentication.

If a secret is set, PicGo enables authentication for POST /upload and all plugin routes. The final secret is resolved by priority: CLI --secret → environment PICGO_SERVER_SECRET → config settings.server.secret. The value is trimmed; whitespace-only values disable authentication.

Example:

json
{
  "settings": {
    "server": {
      "port": 36677,
      "host": "127.0.0.1",
      "secret": "your-shared-secret"
    }
  }
}

settings.picgoCloud 2.0+ ​

PicGo Cloud (https://cloud.picgo.app) login and sync preferences.

  • settings.picgoCloud.token (string): Cloud token saved by picgo login (cloud.picgo.app) or browser login flow. Local-only (not synced).
  • settings.picgoCloud.encryptionMethod (string): preferred encryption method for config sync.
    • e2ee → end-to-end encryption
    • sse → server-side encryption
    • auto → let sync decide; default when missing

These fields are treated as local-only values during config sync: they do not conflict with or overwrite cloud values. For login and manual sync usage, see picgo login and picgo config sync.

Example:

json
{
  "settings": {
    "picgoCloud": {
      "token": "YOUR_TOKEN",
      "encryptionMethod": "e2ee"
    }
  }
}

settings.urlRewrite.rules 1.8.1+ ​

Opt-in URL rewrite rules. When configured, PicGo applies URL rewrite after uploader execution and before afterUploadPlugins.

  • type: Array<Rule>
  • default: not set (no rewrite; no warnings)

Each rule supports:

  • match (string, required): JavaScript RegExp source (no surrounding /).
  • replace (string, required): Replacement string (supports $1, $2, ...).
  • enable (boolean, optional): defaults to true; only explicit false disables the rule.
  • global (boolean, optional): maps to the regex g flag; defaults to false.
  • ignoreCase (boolean, optional): maps to the regex i flag; defaults to false.

Behavior:

  • Rules are evaluated in array order; first enabled match wins (only one rule is applied per image).
  • If rewrite changes imgUrl, PicGo stores the original URL in originImgUrl (set once and never overwritten).
  • Invalid regex patterns are logged and skipped without failing the upload.
  • If a rewrite produces an empty string, PicGo logs a warning and continues.

For plugin authors and Node.js users ​

  • afterUploadPlugins will see the rewritten imgUrl in ctx.output; use originImgUrl to access the original URL produced by the uploader.
  • picgo.upload() (Node.js API) returns IImgInfo[] with the rewritten imgUrl; use originImgUrl if you need the pre-rewrite value.
  • originImgUrl is only set when PicGo actually rewrites the URL; otherwise it stays undefined.

Examples ​

Example (simple prefix rewrite / switch to CDN):

Rewrite:

  • https://example.com/images/2026/1.png
  • → https://cdn.example.com/blog-images/2026/1.png
json
{
  "settings": {
    "urlRewrite": {
      "rules": [
        {
          "match": "https://example.com/images/",
          "replace": "https://cdn.example.com/blog-images/"
        }
      ]
    }
  }
}

Example (ignore case: normalize file extension):

Rewrite:

  • https://cdn.example.com/blog-images/2026/1.PNG
  • → https://cdn.example.com/blog-images/2026/1.png
json
{
  "settings": {
    "urlRewrite": {
      "rules": [
        {
          "match": "PNG",
          "replace": "png",
          "ignoreCase": true
        }
      ]
    }
  }
}

Example (global: replace all underscores in the URL):

Rewrite:

  • https://cdn.example.com/blog_images/2026/hello_world.png
  • → https://cdn.example.com/blog-images/2026/hello-world.png
json
{
  "settings": {
    "urlRewrite": {
      "rules": [
        {
          "match": "_",
          "replace": "-",
          "global": true
        }
      ]
    }
  }
}

Regex and escaping

match is a JavaScript regular expression source. For advanced patterns you may need to escape backslashes in JSON strings, e.g. \\. for a literal dot.

Advanced: capture groups ($1, $2, ...)

Rewrite:

  • https://example.com/images/2026/1.png
  • → https://cdn.example.com/blog-images/2026/1.png

If your match uses parentheses to capture parts of the URL, you can reference them in replace (e.g. $1 for the first group, $2 for the second). In this example, $1 is the captured images, and $2 is the rest of the path (2026/1.png):

json
{
  "settings": {
    "urlRewrite": {
      "rules": [
        {
          "match": "^https://example.com/(images)/(.*)$",
          "replace": "https://cdn.example.com/blog-$1/$2"
        }
      ]
    }
  }
}

Advanced example (rewrite GitHub raw URLs to jsDelivr):

Rewrite:

  • https://raw.githubusercontent.com/user/repo/main/path/to/1.png
  • → https://cdn.jsdelivr.net/gh/user/repo@main/path/to/1.png
json
{
  "settings": {
    "urlRewrite": {
      "rules": [
        {
          "match": "^https://raw.githubusercontent.com/([^/]+)/([^/]+)/([^/]+)/(.*)$",
          "replace": "https://cdn.jsdelivr.net/gh/$1/$2@$3/$4"
        }
      ]
    }
  }
}

config.snapshot.json 2.0+ ​

When you run picgo config sync, PicGo creates a snapshot file named config.snapshot.json under baseDir (the same directory as config.json). It stores a baseline { version, updatedAt, data } for 3-way merges and preserves comments.

You generally shouldn’t edit this file manually. If it is missing, PicGo will recreate it on the next sync and treat the local config as the source of truth when re-seeding the cloud config.

transformer ​

This section stores configuration for Transformers provided by third-party plugins.

Plugin authors

If a Transformer is named xxx, its configuration should be placed under transformer.xxx. This helps the PicGo Electron app render its UI.

Default: {}

picgo-plugin-* ​

If you develop a PicGo plugin and it requires configuration, you should place the plugin configuration at the top level, under a key that matches the plugin package name:

Example:

json
"picgo-plugin-xxx": {
  "config1": "",
  "config2": ""
}