GitPaste uploads images to GitHub and inserts their public links into the active editor. It is a VS Code Web Extension, so the same extension runs in desktop VS Code, GitHub Codespaces, vscode.dev, and github.dev.
The first release supports GitHub only. The upload layer is provider-based so more storage platforms can be added without changing the editor and paste workflow.
Credential security: vs-picgo's GitHub uploader requires the token to be written in plaintext to its configuration file. GitPaste does not write GitHub tokens to extension settings or settings.json. Use VS Code's built-in GitHub sign-in without managing a PAT, or provide a PAT that GitPaste stores in VS Code SecretStorage.
Features
Paste a clipboard image into Markdown and MDX in VS Code for the Web.
Upload one or more images selected from the VS Code file picker.
Drag one or more image files into a Markdown or MDX editor to upload them at the drop location.
Upload an image from a workspace-relative path, VS Code URI, or HTTP URL.
Replace the Markdown image under the cursor and optionally delete its old remote file.
Delete a GitPaste-hosted Markdown image from GitHub and remove its local reference from the editor.
Authenticate with VS Code's built-in GitHub sign-in or a fine-grained personal access token.
Customize the repository, branch, directory, filename, public URL, commit message, and inserted text.
Handle filename conflicts by renaming, overwriting, or asking each time.
Automatically retry transient GitHub and network failures with request timeouts, cancellation, and rate-limit awareness.
Retry or skip failed batch items and clean up files from an incomplete upload.
Use the same extension bundle in browser and desktop extension hosts.
Setup
Run GitPaste: Configure GitHub Repository from the Command Palette.
Choose whether to save the repository for the current workspace or globally, then enter it as owner/repository, followed by its branch and image directory.
Sign in with GitHub, or provide a fine-grained token with Contents: Read and write access to that repository.
Copy an image and open a Markdown or MDX file. In VS Code for the Web, paste with Ctrl+V or Cmd+V. On desktop, use Ctrl+Alt+U or Cmd+Alt+U.
Personal access tokens are stored in VS Code SecretStorage, not as plaintext configuration in settings.json.
For a fine-grained PAT, its Resource owner must own the target repository and its Repository access must include that repository. Organization repositories may also require administrator approval or SSO authorization.
After PAT authentication is selected, GitPaste asks for the PAT again if SecretStorage is unavailable instead of silently switching to VS Code's GitHub session.
Commands
Command
Windows/Linux
macOS
Upload Image from Clipboard (desktop)
Ctrl+Alt+U
Cmd+Alt+U
Paste and Upload Image (Web)
Ctrl+V
Cmd+V
Upload Images from Explorer
Ctrl+Alt+E
Cmd+Alt+E
Upload Image from Path or URL
Ctrl+Alt+O
Cmd+Alt+O
Replace Image at Cursor
Command Palette or editor context menu; in Web, then paste the replacement image
Command Palette or editor context menu; in Web, then paste the replacement image
Delete GitPaste Image
Place the cursor inside the image syntax, then use the editor context menu or Command Palette
Place the cursor inside the image syntax, then use the editor context menu or Command Palette
Check Configuration
Command Palette
Command Palette
Configure GitHub Repository
Command Palette
Command Palette
Set/Clear Personal Access Token
Command Palette
Command Palette
Copy the image itself, not its URL. In VS Code for the Web, Ctrl/Cmd+V uploads image clipboard data while text and other clipboard content continue to use normal paste. The GitPaste clipboard shortcut is desktop-only because browsers expose binary clipboard data only through a real paste event.
You can also drag image files from a file manager into a Markdown or MDX editor. GitPaste inserts upload placeholders at the mouse release position, then replaces them with the finished links. Non-image files keep VS Code's normal drop behavior.
If an image is pasted while the editor is in Plain Text or another unsupported language mode, GitPaste shows a prompt explaining that Markdown or MDX is required and offers to open the language selector.
Explorer and path/URL uploads keep the insertion target captured when the command starts. Moving the cursor or editing elsewhere in the same document does not redirect the result. Edits before the target move it with the surrounding text; changing text that overlaps the target cancels insertion and offers cleanup if the remote upload already completed.
Repository Configuration Scope
Configure GitHub Repository asks where to save the repository, branch, and image directory:
Current workspace writes them to workspace settings. Use this for project-specific image repositories. Workspace values take precedence over global values while that workspace is open.
Global writes them to user settings and uses the same target in every project without a workspace override.
Credentials are never written to either settings scope. GitHub sessions are managed by VS Code, and PATs remain in VS Code SecretStorage.
Filename Conflicts
gitpaste.github.conflictStrategy controls what happens when the generated remote path already exists.
Value
Behavior
Important detail
rename
Finds the first free numeric suffix, such as photo-2.png or photo-3.png.
Default and safest option; preserves the existing file.
overwrite
Reads the current GitHub file SHA and replaces that file.
Keeps the same remote path and normally the same public URL. The old content cannot be automatically restored by GitPaste.
prompt
Asks whether to rename or overwrite for each conflict.
Canceling stops the current operation.
The default filename template includes ${random}, so conflicts are uncommon unless the template is customized.
Upload Failure Recovery
GitPaste automatically retries temporary network failures and GitHub responses with status 408, 429, 500, 502, 503, or 504 using bounded exponential backoff. It honors GitHub's Retry-After header, applies a timeout to every GitHub request, and reports the remaining API quota and reset time when GitHub provides them. Permission failures, exhausted retries, and other permanent errors continue to the manual recovery flow below.
If an image in a multi-image upload fails after the automatic retries, GitPaste groups every failed item into a single modal so a batch of concurrent failures does not flood you with stacked dialogs. The modal offers:
Retry all: retry every failed image in the batch (up to a bounded number of batch retries).
Skip failed: keep the images that succeeded and continue, leaving the failed ones out.
Stop: stop the batch. GitPaste rolls back the files it created earlier in that operation (with your confirmation), then reports the failure instead of swallowing it silently.
When every image in the batch fails, GitPaste reports a descriptive error rather than treating it as a cancellation, so you are never left with a silently dropped upload. A user-initiated cancellation (canceling the progress notification or choosing Stop) remains distinct and triggers cleanup of any files already created.
Cleanup never deletes a file that was overwritten, because GitPaste does not retain the previous file contents. Before deleting a newly created file, GitPaste reads its current SHA again and refuses to delete it if another process has changed it. Explorer and path/URL upload commands also offer cleanup if the remote upload succeeds but the editor edit fails.
Replace an Image
Place the cursor anywhere inside an inline Markdown image such as , then run GitPaste: Replace Image at Cursor from the Command Palette or editor context menu.
On desktop, select one replacement image. In VS Code for the Web, paste one image after running the command.
GitPaste uploads it using the normal filename and conflict settings.
GitPaste replaces the complete Markdown image at the cursor with the new generated output.
If the old URL can be mapped unambiguously to the configured repository, branch, and image directory, GitPaste offers to delete the old remote file.
Reference-style Markdown images such as ![old][image-id] are not replaced. Old-file deletion is not offered for unrelated URLs or custom URL templates that cannot be reversed. If overwrite selects the same remote path, GitPaste keeps that path and does not offer to delete it.
In VS Code for the Web, the pending replacement expires after 60 seconds. It is also canceled if the target document changes, the cursor moves outside the target image before paste, or the target image itself is edited. While waiting to paste, edits elsewhere in the document are tracked and do not cancel replacement.
Deleting a GitHub file creates a deletion commit on the configured branch. It does not erase the file from Git history, and a CDN may continue serving a cached response for some time. Deletion can also break other documents that reference the same URL, so GitPaste requires explicit confirmation.
Delete an Image
In a Markdown or MDX editor, choose GitPaste: Delete GitPaste Image from the editor context menu or Command Palette. Place the cursor inside an inline Markdown image generated by GitPaste. GitPaste only deletes URLs that map to the active repository, branch, public URL template, and image directory, and it also requires a supported image extension. After confirmation it creates a GitHub deletion commit and removes the complete Markdown image from the current document. The command rejects unrelated URLs and reference-style images.
Check Configuration
Run GitPaste: Check Configuration to validate:
repository syntax, repository write permission, and target branch access;
safe repository paths and a non-empty commit message;
the selected filename conflict strategy;
filename, public URL, and output templates.
A custom public URL must be HTTP(S) and include ${path}; the output template must include ${url}. The check is read-only and does not create a test commit. GitHub branch protection or repository rules may still reject a later upload, and GitPaste does not test whether a custom CDN is currently reachable.
This produces <img src="https://example.com/image.png" alt="image"> after the
upload completes. HTML output is useful for HTML documents or when you need image
attributes such as width, height, loading, or class; Markdown remains the
recommended default for Markdown and MDX files.
${random} is an eight-character hexadecimal value. ${timestamp} is milliseconds since the Unix epoch. ${document} is the active document filename after unsafe filename characters are replaced. ${path} is URL-encoded one repository segment at a time.
Downloading arbitrary HTTP URLs is subject to the source server's browser CORS policy. Workspace files and pasted images do not have this limitation.
Relationship to PicGo and vs-picgo
GitPaste is a browser-compatible rewrite derived from the MIT-licensed
PicGo/vs-picgo project. It retains the
original copyright notice required by the MIT license, but it is an independent
project and is not an official PicGo or vs-picgo release.
VS Code Web Extension focused on pasting images into editors
VS Code Web and desktop from the same browser-compatible bundle
GitHub Contents API in the current release
GitPaste does not load PicGo plugins or PicGo/vs-picgo configuration. It uses
gitpaste.* settings, stores credentials in VS Code SecretStorage, and uploads
directly through the GitHub API. Existing PicGo or vs-picgo settings must be
configured again using the corresponding GitPaste settings.
The credential model is an intentional difference. The vs-picgo GitHub uploader
requires a token in its configuration file, which leaves the token as plaintext
configuration. GitPaste keeps tokens out of gitpaste.* settings: built-in GitHub
sign-in delegates authentication to VS Code, while PAT authentication stores the
secret in SecretStorage and only keeps the selected authentication method in
settings.json.
Development
npm install
npm test
npm run package
npm run package emits dist/web/extension.js, a single Web Worker bundle. VS Code desktop can run the same browser entry point.
Release automation
Releases are driven by version tags. Push a tag matching vX.Y.Z (for example,
v0.8.0) to start the release workflow in .github/workflows/ci.yml:
The workflow reads the version from the tag and applies it only in the CI
workspace before installing dependencies and building the VSIX.
The repository's package.json, package-lock.json, and CHANGELOG.md are
not modified or pushed by CI. The tag is the source of truth for the final
VSIX version.
Tests run, the VSIX is built, and a GitHub Release is created with GitHub's
automatically generated release notes.
The workflow requires the repository's GitHub Actions token to have Contents: Write permission so it can create the GitHub Release. The version shown in the
repository files may lag behind the latest release by design.
License
MIT. See the LICENSE file for GitPaste and upstream copyright and license terms.