In this note
define what local meansBase64 is bytes, not secret textdisplay text without executing ita countdown should measure timeleave room for plain HTMLdefine what local means
The Random scratchpad reads a textarea and updates an output element. It uses no network request, cookies, localStorage or saved input history. Reloading clears its contents. This is a property of the tool’s code, not a claim about browser extensions, operating-system clipboard history or the computer around it.
Keeping a tool local also keeps it small. Native inputs give keyboard handling and text selection without a framework. A visible label and a polite result announcement are more useful than elaborate animations.
Base64 is bytes, not secret text
Base64 is a reversible representation of bytes, not encryption. JavaScript’s btoa() does not directly accept arbitrary Unicode text. Polish letters and emoji are a good test: convert text to UTF-8 bytes first.
const bytes = new TextEncoder().encode(text);
let binary = ;
for (const byte of bytes) {
binary += String.fromCharCode(byte);
}
const encoded = btoa(binary);Decode in the other direction: atob() to bytes, then new TextDecoder("utf-8", {fatal: true}). Fatal decoding rejects malformed UTF-8 instead of silently inserting replacement characters. The tool accepts standard padded Base64 and whitespace, not every URL-safe variant. An input limit keeps accidental huge pastes manageable.
display text without executing it
A decoded string can contain HTML. Showing it with innerHTML would turn a text tool into an HTML interpreter. Use textContent for every result:
output.textContent = decodedText;
Try encoding and decoding <img src=x onerror=alert(1)>. It should remain visible text, never an image or executable event handler. Then round-trip Zażółć gęślą jaźń 🐸, test empty input, and test invalid Base64. These cases check real failure modes, rather than only the happy path.
a countdown should measure time
Browsers throttle timers in background tabs. Subtracting one second whenever setInterval() fires can drift. Store an absolute deadline and calculate the difference on every update:
const deadline = Date.now() + 25 * 60 * 1000; const secondsLeft = Math.max(0, Math.ceil((deadline - Date.now()) / 1000));
The interval only repaints; it does not define time. Returning to the tab produces the correct remaining duration. Changing the system clock can still affect a wall-clock timer; this is fine for a casual focus tool, not a precise benchmark. Do not put a once-per-second countdown in an assertive live region.
leave room for plain HTML
JavaScript is necessary for these tools, but not for reading articles or following links. Include a short no-script note, visible controls and clear invalid-input feedback. Avoid collecting usage data just because it is easy.