Skip to content

imgflash

imgflash is a universal disk imaging tool that enables browser-based writing to SD cards, USB drives, HDDs, and optical media. It runs as a local service and exposes an HTTP/WebSocket API for real-time progress.

Multi-Platform

Linux, macOS, Windows support with platform-native tooling

Browser Integration

HTTP API enables one-click writing from any web page

All Media Types

SD cards, USB drives, HDDs, CD/DVD/Blu-ray, floppy

Verified Writes

SHA256 read-back verification catches bad sectors and failed writes

Terminal window
# Download for your platform
curl -LO https://github.com/supported-systems/imgflash/releases/latest/download/imgflash-linux-x86_64
chmod +x imgflash-linux-x86_64
# Run (requires root for disk access)
sudo ./imgflash-linux-x86_64

Once running, you’ll see:

┌─────────────────────────────────────────────────────────────┐
│ imgflash v2025.2.12 │
│ Universal Disk Imaging Tool │
├─────────────────────────────────────────────────────────────┤
│ Service URL: http://127.0.0.1:8765 │
│ │
│ Endpoints: │
│ GET / - Service info │
│ GET /drives - List available drives │
│ POST /write - Start write job │
│ GET /ws/:id - WebSocket progress │
└─────────────────────────────────────────────────────────────┘
FlagDescriptionDefault
-p, --portHTTP server port8765
--allowed-domainsComma-separated URL allowlist(all)
--allow-hddEnable HDD writing (dangerous!)false
--allow-any-pathAllow any local file pathfalse
--no-root-checkSkip privilege checkfalse
Terminal window
# Basic usage
sudo imgflash
# Custom port
sudo imgflash --port 9000
# Restrict to specific image sources
sudo imgflash --allowed-domains "downloads.raspberrypi.org,8-dsi-touch.build.supported.systems"
# Enable HDD writing (use with caution!)
sudo imgflash --allow-hdd
GET /

Returns service capabilities:

{
"service": "imgflash",
"version": "2025.2.12",
"status": "ready",
"platform": "linux",
"capabilities": ["sd-card", "usb-drive", "hdd", "cd-burn", "dvd-burn", "floppy"]
}
GET /drives?optical=true&hdd=false

Returns available drives:

[
{
"device": "/dev/sdb",
"label": "SDCARD",
"size_bytes": 32000000000,
"size_human": "29.8 GB",
"mountpoint": "/media/user/SDCARD",
"is_removable": true,
"media_type": "removable",
"media_type_name": "Removable Drive",
"model": "SD Card Reader",
"is_writable": true
}
]
POST /write
Content-Type: application/json
{
"image_source": "https://example.com/image.img.xz",
"device": "/dev/sdb",
"verify": true
}

For optical media, include burn options:

{
"image_source": "/path/to/image.iso",
"device": "/dev/sr0",
"burn_options": {
"speed": "8",
"blank": false,
"simulate": false,
"eject": true
}
}

Returns job info:

{
"job_id": "a1b2c3d4",
"websocket_url": "/ws/a1b2c3d4"
}
GET /ws/{job_id}

Streams progress updates:

{
"status": "writing",
"progress": 45,
"bytes_written": 1500000000,
"total_bytes": 3300000000,
"speed_mbps": 25.4
}

Status values:

  • pending - Job queued
  • downloading - Fetching image from URL
  • writing - Writing to device
  • burning - Burning optical disc
  • verifying - SHA256 read-back verification
  • complete - Success
  • error - Failed (check error field)

imgflash performs SHA256 read-back verification:

  1. During write: Computes SHA256 hash as data is written
  2. After write: Reads back all bytes from the device
  3. Compares: Ensures hashes match
  4. Reports: On mismatch, shows both hashes for debugging

This catches:

  • Failing SD cards with bad sectors
  • USB cable disconnects mid-write
  • Power glitches
  • Filesystem cache not flushing

Verification roughly doubles total time but guarantees data integrity.

imgflash auto-decompresses images based on file extension:

ExtensionFormatNotes
.xzXZ/LZMA2Best compression, common for Pi images
.gzGzipFast decompression
.bz2Bzip2Good compression
.zstZstandardFast + good compression
(none)RawDirect write
Media TypeLinuxmacOSWindows
SD Card / USBddddWin32 API
HDDddddWin32 API
CD/DVD Burnwodim/cdrecordhdiutilisoburn.exe
FloppyddddN/A
  • Root privileges (sudo)
  • For optical: wodim or cdrecord
Terminal window
# Debian/Ubuntu
sudo apt install wodim
# Arch
sudo pacman -S cdrtools
# Fedora
sudo dnf install wodim

imgflash is designed with safety in mind:

  • Localhost only: Binds to 127.0.0.1 — not accessible from network
  • URL allowlist: Restrict image sources with --allowed-domains
  • HDD protection: HDDs excluded by default, require explicit --allow-hdd
  • System drive protection: Never lists drives mounted at /, /boot, /home, or C:\
  • Root required: Proper privilege escalation for raw disk access

Add to any web page:

<script>
const IMGFLASH_URL = 'http://localhost:8765';
async function checkService() {
try {
const res = await fetch(`${IMGFLASH_URL}/`);
return res.ok;
} catch {
return false;
}
}
async function writeImage(imageUrl, device) {
const res = await fetch(`${IMGFLASH_URL}/write`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
image_source: imageUrl,
device: device,
verify: true
})
});
const { job_id, websocket_url } = await res.json();
const ws = new WebSocket(`ws://localhost:8765${websocket_url}`);
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
console.log(`Progress: ${data.progress}% (${data.status})`);
if (data.status === 'complete') {
console.log('Write successful!');
} else if (data.status === 'error') {
console.error('Write failed:', data.error);
}
};
}
</script>

imgflash is open source under the MIT license.