Upload images to Cloudflare Images with drag & drop, paste, or command palette - automatically inserts the right syntax for your file type.
- 🖱️ Drag & Drop: Drag image files from your file explorer directly into any supported file
- 📋 Paste from Clipboard: Copy images from anywhere (screenshots, browsers, image editors) and paste into your document
- ⌨️ Command Palette: Use the command palette to select and upload images
- 🎨 Smart Syntax: Automatically inserts the correct syntax based on file type:
- Markdown:
 - HTML/PHP/Vue/Svelte:
<img src="url" alt="filename" /> - CSS/SCSS/Sass/Less:
url('url') - JavaScript/TypeScript/React:
"url" - Python/Ruby/Go/Rust/Java/C/C++/C#:
"url" - JSON:
"url" - Plain Text: Raw URL
- Markdown:
- ⚡ Progress Notifications: Real-time upload progress feedback
- 🔍 Smart Duplicate Detection: Automatically detects and reuses previously uploaded images (no redundant uploads!)
- 📦 Automatic Compression: Compress oversized images before upload with configurable quality and size limits
- 🔄 AVIF Auto-Conversion: Automatically converts AVIF images to a compatible format (WebP, JPEG, or PNG) before upload
- 🏷️ Automatic Metadata Tagging: Tags uploaded images with extension info for easy tracking and management
- 🗑️ Optional Delete on Removal: Ask to delete from Cloudflare when removing image URLs (with optional auto-delete)
- 🔐 Signed URLs: Generate signed URLs to restrict access to specific variants, preventing unauthorized access to other image sizes
- 🌐 Multi-Format Support: Works in 25+ file types including Markdown, HTML, CSS, JavaScript, TypeScript, Python, and more
All uploaded images are automatically tagged with customizable metadata for easy tracking:
The default metadata includes:
- uploadedBy: Identifies images from this extension
- version: Extension version used
- uploadedAt: Timestamp of upload
- fileName: Original filename
You can fully customize the metadata template with your own fields and dynamic variables — see Metadata Settings for details.
VSCode Marketplace (for VSCode):
- Open VSCode
- Go to Extensions (
Ctrl+Shift+XorCmd+Shift+X) - Search for "Cloudflare Images Upload"
- Click Install
Open VSX Registry (for Windsurf, VSCodium, and other VSCode alternatives):
- Open your editor (Windsurf, VSCodium, etc.)
- Go to Extensions
- Search for "Cloudflare Images Upload"
- Click Install
Or install directly from:
- Download the
.vsixfile from Releases - Open your editor
- Go to Extensions →
...menu → Install from VSIX - Select the downloaded file
Before using the extension, you need to configure your Cloudflare credentials:
- Open VSCode Settings (
Ctrl+,orCmd+,) - Search for "Cloudflare Images Upload"
- Configure the following:
| Setting | Description | How to Get It |
|---|---|---|
| Account ID | Your Cloudflare Account ID | Dashboard → Any domain → Overview (right sidebar) |
| API Token | API token with Images:Edit permission | Dashboard → My Profile → API Tokens → Create Token |
| Account Hash | Your Cloudflare Images account hash | Dashboard → Images → Copy from URL: /images/[HASH] |
| Default Variant | Image variant for URLs (optional) | Default: /public |
The extension automatically compresses images that exceed the configured file size limit before uploading.
| Setting | Default | Description |
|---|---|---|
| Enable Compression | true |
Automatically compress oversized images |
| Max File Size MB | 10 |
Compression triggers when file exceeds this size |
| Compression Quality | 80 |
Quality level (1-100) for compressed output |
| Preserve PNG Format | false |
When compressing PNG images, keep PNG format instead of converting to JPEG |
Supported formats and output:
| Input Format | Compressed Output | Notes |
|---|---|---|
| JPEG | JPEG | Quality reduced per settings |
| PNG | JPEG or PNG | Converts to JPEG by default; enable "Preserve PNG Format" to keep PNG |
| WebP | WebP | Quality reduced, format preserved |
| AVIF | WebP, JPEG, or PNG | Auto-converted (configurable via AVIFConversionFormat setting) |
| HEIC/HEIF | JPEG | iPhone photos converted |
| BMP | JPEG | Converted for better compression |
| GIF | (skipped) | Animated format - not compressed |
| SVG | (skipped) | Vector format - not compressed |
Note: Cloudflare's official upload limit is 10MB, though uploads up to 20MB may work but are not guaranteed. See Cloudflare Images documentation.
| Setting | Default | Description |
|---|---|---|
| Use Signed URLs | false |
Enable signed URLs for variant protection |
| Signed URL Expiration | 0 |
Expiration time in seconds (0 = never) |
| Signing Key | (auto-fetched) | Optional manual override |
The extension can tag each upload with custom metadata. Enable with Add Metadata and customize the template.
| Setting | Default | Description |
|---|---|---|
| Add Metadata | true |
Tag uploaded images with metadata |
| Metadata Template | (see below) | Custom key-value pairs with dynamic variable support |
Default template:
{
"uploadedBy": "vscode-cloudflare-images-extension",
"version": "${extensionVersion}",
"uploadedAt": "${timestamp}",
"fileName": "${fileName}"
}Available dynamic variables:
| Variable | Description | Example |
|---|---|---|
${fileName} |
Original file name | photo.avif |
${timestamp} |
ISO 8601 datetime | 2026-02-10T10:45:00.000Z |
${date} |
Date only | 2026-02-10 |
${time} |
Time only | 10:45:00 |
${extensionVersion} |
Extension version | 0.7.0 |
${fileSize} |
File size in bytes | 1048576 |
${fileExtension} |
File extension | .png |
${workspaceName} |
Workspace name | my-project |
Note: Cloudflare limits metadata to 1024 bytes total. A warning is shown if your resolved metadata exceeds this limit.
| Setting | Default | Description |
|---|---|---|
| Delete On Removal | false |
Ask to delete image from Cloudflare when URL is removed from document |
| Delete Without Confirmation | false |
Skip confirmation dialog when deleting (auto-delete) |
- Go to Cloudflare Dashboard
- Click on your profile → API Tokens
- Click "Create Token"
- Use the "Edit Cloudflare Images" template
- Or create a custom token with
Account.Cloudflare Images:Editpermission - Copy the token and paste it in the extension settings
- Open a markdown file (
.md) - Drag an image file from your file explorer
- Drop it where you want the image
- ✨ Done! The image uploads and a markdown link is inserted
- Copy an image to your clipboard:
- Take a screenshot (
Cmd+Shift+4on Mac,Win+Shift+Son Windows) - Copy an image from a browser (right-click → Copy Image)
- Copy from an image editor
- Take a screenshot (
- Open a markdown file
- Paste (
Ctrl+VorCmd+V) - ✨ Done! The image uploads and a markdown link is inserted
- Open a markdown file
- Open Command Palette (
Ctrl+Shift+PorCmd+Shift+P) - Type "Upload Image to Cloudflare"
- Select an image file
- ✨ Done! The image uploads and a markdown link is inserted
I use it heavily when writing blog posts. Going from screenshot to published image in seconds.
- PNG (
.png) - JPEG (
.jpg,.jpeg) - GIF (
.gif) - WebP (
.webp) - BMP (
.bmp) - SVG (
.svg)
- VSCode: Version 1.80.0 or higher
- Cloudflare Account: With Cloudflare Images enabled
- API Token: With
Images:Editpermission
The extension automatically inserts the correct syntax based on your file type. Here are some examples:
Markdown (.md):
HTML (.html):
<img src="https://imagedelivery.net/YOUR_HASH/IMAGE_ID/public" alt="image-name.png" />CSS (.css):
url('https://imagedelivery.net/YOUR_HASH/IMAGE_ID/public')JavaScript/TypeScript:
"https://imagedelivery.net/YOUR_HASH/IMAGE_ID/public"The image is immediately accessible via Cloudflare's global CDN!
- Documentation: Quickly add screenshots to your README files
- Blog Posts: Upload images while writing markdown blog posts
- Notes: Add images to your markdown notes
- Technical Writing: Include diagrams and screenshots in technical docs
- GitHub Issues: Upload images for bug reports
# Clone the repository
git clone https://github.com/mcdays94/cloudflare-images-upload-extension.git
cd cloudflare-images-upload-extension
# Install dependencies
npm install
# Compile TypeScript
npm run compile
# Package the extension
npm run packagecloudflare-images-upload/
├── src/
│ └── extension.ts # Main extension code
├── out/ # Compiled JavaScript
├── extension_icon.png # Extension icon
├── package.json # Extension manifest
├── tsconfig.json # TypeScript config
└── README.md # This file
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
If you find this extension helpful and it saves you time, consider buying me a coffee! Your support helps keep this project maintained and improved.
- AVIF Auto-Conversion: AVIF images are automatically converted to a Cloudflare-compatible format before upload
- Configurable AVIF Output: New setting to choose conversion format (WebP, JPEG, or PNG — defaults to WebP) with per-format pros/cons descriptions
- Custom Metadata Templates: Define your own metadata key-value pairs with dynamic variables (
${fileName},${timestamp},${date},${workspaceName}, etc.)
- Fix: HEIC/HEIF paste support now works correctly (was only working for drag & drop)
- Image Compression: Automatically compress images exceeding configurable size limit before upload
- Preserve PNG Format: Option to keep PNG format instead of converting to JPEG during compression
- Delete Without Confirmation: Option to auto-delete images without confirmation dialog
- HEIC/HEIF Registration: Explicit mime type registration for better drag/drop and paste support
- Settings Organization: Settings now grouped logically in the UI
- Signed URLs: Generate signed URLs to prevent unauthorized access to other image variants
- Auto-fetch Signing Key: Signing key is automatically retrieved from Cloudflare API
- Configurable Expiration: Set URL expiration time or use non-expiring signed URLs
- ✅ Automatic Metadata Tagging: Uploaded images are tagged with extension info (version, filename, timestamp) for easy tracking
- ✅ Optional Delete on Removal: Ask to delete images from Cloudflare when removing URLs (disabled by default)
- ✅ Smart Tracking: Tracks recently inserted images for 5 minutes to detect removals
- ✅ Configurable: Both features can be enabled/disabled in settings
- ✅ Smart Duplicate Detection: Automatically detects previously uploaded images using SHA-256 hashing
- ✅ Persistent Cache: Stores image hashes locally (30-day retention) to avoid redundant uploads
- ✅ User Notifications: Shows friendly messages when duplicates are detected
- ✅ Performance: Instant duplicate detection with no API calls required
- ✅ Enhanced multi-language support
- ✅ Improved syntax formatting for different file types
- ✅ Drag & drop image upload
- ✅ Paste image from clipboard
- ✅ Command palette upload
- ✅ Automatic markdown link insertion
- ✅ Progress notifications
- ✅ Support for PNG, JPG, GIF, WebP, BMP, SVG
While I work at Cloudflare, this is a personal side project I built independently. It's not an official Cloudflare product and isn't affiliated with, endorsed by, or supported by Cloudflare, Inc.




