Base64 Encoder / Decoder

Encode text to Base64 or decode Base64 strings back to plain text. Supports UTF-8.

Developer
100% Free
Runs in Browser

Preview

Source Code

Toggle the controls below the code to live-edit the initial state values.

base64-codec.tsx
import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Copy, Check, ArrowDown, ArrowUp } from "lucide-react";

export default function Base64Codec() {
    const [input, setInput] = useState("");
    const [output, setOutput] = useState("");
    const [mode, setMode] = useState<"encode" | "decode">("encode");
    const [error, setError] = useState("");
    const [copied, setCopied] = useState(false);

    const process = () => {
        try {
            if (mode === "encode") {
                setOutput(btoa(unescape(encodeURIComponent(input))));
            } else {
                setOutput(decodeURIComponent(escape(atob(input))));
            }
            setError("");
        } catch (e: any) {
            setError("Invalid input for " + mode + "ing");
            setOutput("");
        }
    };

    const copyOutput = async () => {
        await navigator.clipboard.writeText(output);
        setCopied(true);
        setTimeout(() => setCopied(false), 1500);
    };

    const swap = () => {
        setInput(output);
        setOutput("");
        setMode(mode === "encode" ? "decode" : "encode");
    };

    return (
        <div className="space-y-4">
            <div className="flex gap-2">
                <Button
                    variant={mode === "encode" ? "default" : "outline"}
                    onClick={() => setMode("encode")}
                >
                    Encode
                </Button>
                <Button
                    variant={mode === "decode" ? "default" : "outline"}
                    onClick={() => setMode("decode")}
                >
                    Decode
                </Button>
            </div>
            <Textarea
                placeholder={
                    mode === "encode"
                        ? "Enter text to encode..."
                        : "Enter Base64 string to decode..."
                }
                value={input}
                onChange={(e) => setInput(e.target.value)}
                className="min-h-[120px] resize-y font-mono text-sm"
            />
            <div className="flex items-center gap-2">
                <Button onClick={process}>
                    {mode === "encode" ? (
                        <ArrowDown className="mr-2 h-4 w-4" />
                    ) : (
                        <ArrowUp className="mr-2 h-4 w-4" />
                    )}
                    {mode === "encode" ? "Encode" : "Decode"}
                </Button>
                {output && (
                    <Button variant="outline" onClick={swap}>
                        Swap ↕
                    </Button>
                )}
            </div>
            {error && (
                <div className="rounded-lg border border-destructive/50 bg-destructive/10 p-3">
                    <p className="text-sm text-destructive">{error}</p>
                </div>
            )}
            {output && (
                <div className="relative rounded-lg border bg-muted/50 p-4">
                    <pre className="overflow-x-auto whitespace-pre-wrap break-all text-sm font-mono">
                        {output}
                    </pre>
                    <Button
                        variant="ghost"
                        size="icon"
                        className="absolute top-2 right-2"
                        onClick={copyOutput}
                    >
                        {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
                    </Button>
                </div>
            )}
        </div>
    );
}
Props Playground
2 props

Required Libraries

Install the external dependencies used by this tool.

bun add lucide-react react

Shadcn UI Setup

Add the required Shadcn UI primitives to your project.

bun x --bun shadcn@latest add button textarea

Shadcn UI Components

The following primitives are required in your @/components/ui directory.

Component Import Path
button @/components/ui/button
textarea @/components/ui/textarea

Imports

All import statements used in this tool.

Source Exports
react useState
@/components/ui/textarea Textarea
@/components/ui/button Button
lucide-react Copy, Check, ArrowDown, ArrowUp

State Management

React state variables managed within this tool.

Variable Initial Value
input ""
output ""
mode "encode"
error ""
copied false

Functional Logic

Internal functions that handle the tool's core logic.

Function Parameters Async
process() None No
copyOutput() None
Yes
swap() None No

External Resources

Documentation, tutorials, and package details for libraries used in this tool.