LoadBase64(js)
Pick local images, get base64 strings out — that's the whole node
- base64
LoadBase64(js) looks like the laziest node in the comfyui-remote-tools pack, and it kind of is - in the best way. The Python side is a pure pass-through: a base64 string in, the same string out, default []. The entire point is the "(js)": a tiny frontend extension that hides the text widget and gives you a "choose images to upload" button. You pick image files, it turns them into base64, and out the other end comes a JSON-encoded list of them. That's the whole job, and it exists for one reason - to feed SendBase64ToRemote, which ships that base64 to another ComfyUI server.
Why would you need a node for this? Because the alternative is typing a JSON array of base64 data URLs by hand, which nobody should do. When you're building a master/worker setup where the heavy rendering happens on another box, the image has to travel as text, and this node is the humane way to get it into that format. You select files, previews pop up on the node, and the base64 quietly rides along in the workflow.
The mechanism, if you want to peek behind the curtain: the extension (in web/js/web.js) waits for the node to be created, hides the base64 widget, appends a hidden <input type="file" accept="image/jpeg,image/png,image/webp" multiple>, and on change reads each file with FileReader.readAsDataURL, pushes the data URLs into an array, and writes JSON.stringify(base64) into the hidden widget. A clear button resets it to []. Because the hidden widget is still a normal widget, its value gets serialized into your saved workflow - which means the images travel with the .json. That's convenient (reload the workflow and your images are still there) and occasionally annoying (saved workflows balloon; a few photos can push one into many megabytes).
The schema is as minimal as it gets:
- base64 (input) - a STRING, default
"[]". You won't usually touch it in the UI because it's hidden; the file picker writes to it. - base64 (output) - a STRING, the same JSON-encoded list, ready to wire into
SendBase64ToRemoteor any node that consumes base64 image strings.
Install is shared with the rest of the pack, and it's about as light as a custom node install gets - no models, no heavy dependencies:
# ComfyUI Manager: search "comfyui-remote-tools" → install → restart
cd ComfyUI/custom_nodes
git clone https://github.com/linshier/comfyui-remote-tools
# restart ComfyUI (the frontend extension needs a reload to show up)
Since the meat of this node is frontend JavaScript, the restart matters more than usual - if you don't reload the browser (or restart ComfyUI), you'll see a bare pass-through node with a text widget and no button. The pack's requirements.txt only lists websocket-client and a typo'd request (the code actually imports requests, already present in every ComfyUI env), so there's nothing to chase down.
Troubleshooting is mostly about expectations. If the button doesn't appear, refresh the page. If you pick a file and nothing seems to happen, look at the output string - it should be a JSON array of data:image/...;base64,.... URLs, and thumbnails should render on the node. If you're feeding this into a remote workflow and the remote complains, the mismatch is usually on the remote side (wrong input name on the receiving node), not here.
One honest caveat: this node is a convenience wrapper around a string, and a slightly fragile one at that - it only accepts JPEG, PNG, and WebP. It's the part of the pack that depends most on the frontend holding up across ComfyUI updates. But for its one job - turning local images into the base64 that SendBase64ToRemote expects - it's exactly the right amount of node.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| base64 | STRING | [] | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| base64 | STRING | — |