Releases: PicGo/PicGo-Core
v2.0.0
Features
PicGo Server (Local HTTP API)
The local server has been rebuilt to be more robust and secure. It now supports automatic port detection and optional authentication, making it safer to run in shared environments.
How to use:
Simply run the following command to start the server:
picgo server- Smart Port Management: By default, it uses port
36677. If the port is busy, PicGo will intelligently detect if another PicGo instance is running and reuse it, or automatically find the next available port. - Upload Endpoint: Send
POST /uploadrequests with:- JSON body:
{ "list": ["/path/to/image.png"] }. if list is not provided, it will upload images from the clipboard. - Multipart form-data:
filesfield.
- JSON body:
- Health Check:
POST /heartbeatto check server status.
Security & Authentication:
You can now protect your upload server with a secret token.
- Set a secret: Use the
--secretflag, set thePICGO_SERVER_SECRETenv var, or configuresettings.server.secret. - Authenticate requests: If secret is set, clients must provide the secret via the
Authorization: Bearer <secret>header,X-PicGo-Secretheader, or?secret=query parameter.
For plugin authors and Node.js users
- New Router APIs: Use
picgo.server.registerGet,picgo.server.registerPost, andpicgo.server.mountto add custom routes safely. - Programmatic Control: You can now control the server lifecycle via
picgo.server.listen(),picgo.server.shutdown(), and check status withpicgo.server.isListening().
PicGo Cloud Login
We have introduced a seamless login experience for PicGo Cloud. You can now authenticate directly via your browser without manually copying tokens.
How to use:
picgo login- Browser Flow: This command opens your default browser for a secure login (PKCE). Once authorized, PicGo automatically saves your token.
- Manual Token: If you cannot open a browser (e.g., on a headless server), you can still log in manually using
picgo login [token]. - Logout: Run
picgo logoutto remove your credentials.
For plugin authors and Node.js users
- New Auth API: Use
picgo.cloud.login([token])andpicgo.cloud.logout()to manage authentication programmatically.
PicGo Config Sync
Keep your configuration synchronized across multiple devices with conflict resolution and optional End-to-End Encryption (E2EE).
How to use:
picgo config sync- Smart Sync: PicGo performs a 3-way merge (Snapshot + Local + Remote) to ensure no settings are lost.
- Conflict Resolution: If conflicts occur (e.g., you changed the same setting on two different computers), the CLI will present a diff tree and ask you to choose:
Use Local,Use Remote, orAbort. - Privacy First: Sensitive fields like your Cloud Token are never synced.
Encryption Options:
You can choose how your data is protected in the cloud:
picgo config sync --encrypt e2eeauto: Default behavior.sse(Server-Side Encryption): We use AES-256-GCM to encrypt your config on our servers. No PIN is required.e2ee(End-to-End Encryption): Uses PBKDF2 + AES-256-GCM. Your config is encrypted locally before uploading. A PIN will be required to decrypt it on other devices.
Breaking Changes
- Node.js v20.19.0+ is now required.
- If Authentication is enabled: If you configure a server secret (
--secretorsettings.server.secret), all clients (including plugins making requests to the local server) must provide the correct credentials. Unauthorized requests to/uploadwill receive a401 Unauthorizederror.
v1.8.1
Features
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): JavaScriptRegExpsource (no surrounding/).replace(string, required): Replacement string (supports$1,$2, ...).enable(boolean, optional): defaults totrue; only explicitfalsedisables the rule.global(boolean, optional): maps to the regexgflag; defaults tofalse.ignoreCase(boolean, optional): maps to the regexiflag; defaults tofalse.
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 inoriginImgUrl(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
afterUploadPluginswill see the rewrittenimgUrlinctx.output; useoriginImgUrlto access the original URL produced by the uploader.picgo.upload()(Node.js API) returnsIImgInfo[]with the rewrittenimgUrl; useoriginImgUrlif you need the pre-rewrite value.originImgUrlis only set when PicGo actually rewrites the URL; otherwise it staysundefined.
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
{
"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
{
"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
{
"settings": {
"urlRewrite": {
"rules": [
{
"match": "_",
"replace": "-",
"global": true
}
]
}
}
}TIPS: 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):
{
"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
{
"settings": {
"urlRewrite": {
"rules": [
{
"match": "^https://raw.githubusercontent.com/([^/]+)/([^/]+)/([^/]+)/(.*)$",
"replace": "https://cdn.jsdelivr.net/gh/$1/$2@$3/$4"
}
]
}
}
}v1.8.0
Feature
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 TestFor 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 configv1.7.0
Refactor
Breaking change: The picgo init command is no longer available. Please use npx picgo-init to initialize PicGo plugin template.
For more details, please refer to PicGo-Init.
And this refactor reduces the size of PicGo core package. Enjoy!