JSON Formatter

Format, beautify, or minify JSON with configurable indentation. Highlights syntax errors.

Developer
100% Free
Runs in Browser

Preview

Source Code

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

json-formatter.tsx
import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Copy, Check, Minimize2, Maximize2 } from "lucide-react";

export default function JsonFormatter() {
    const [input, setInput] = useState("");
    const [output, setOutput] = useState("");
    const [error, setError] = useState("");
    const [copied, setCopied] = useState(false);
    const [indent, setIndent] = useState(2);

    const format = () => {
        try {
            const parsed = JSON.parse(input);
            setOutput(JSON.stringify(parsed, null, indent));
            setError("");
        } catch (e: any) {
            setError(e.message);
            setOutput("");
        }
    };

    const minify = () => {
        try {
            const parsed = JSON.parse(input);
            setOutput(JSON.stringify(parsed));
            setError("");
        } catch (e: any) {
            setError(e.message);
            setOutput("");
        }
    };

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

    return (
        <div className="space-y-4">
            <Textarea
                placeholder='Paste your JSON here... e.g. {"name": "John", "age": 30}'
                value={input}
                onChange={(e) => setInput(e.target.value)}
                className="min-h-[160px] resize-y font-mono text-sm"
            />
            <div className="flex flex-wrap items-center gap-3">
                <Button onClick={format}>
                    <Maximize2 className="mr-2 h-4 w-4" />
                    Format
                </Button>
                <Button variant="outline" onClick={minify}>
                    <Minimize2 className="mr-2 h-4 w-4" />
                    Minify
                </Button>
                <div className="flex items-center gap-2">
                    <span className="text-sm text-muted-foreground">Indent:</span>
                    {[2, 4].map((n) => (
                        <Button
                            key={n}
                            variant={indent === n ? "default" : "outline"}
                            size="sm"
                            onClick={() => setIndent(n)}
                        >
                            {n}
                        </Button>
                    ))}
                </div>
            </div>
            {error && (
                <div className="rounded-lg border border-destructive/50 bg-destructive/10 p-3">
                    <p className="text-sm text-destructive font-mono">{error}</p>
                </div>
            )}
            {output && (
                <div className="relative rounded-lg border bg-muted/50 p-4">
                    <pre className="overflow-x-auto whitespace-pre 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
2

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 badge button textarea

Shadcn UI Components

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

Component Import Path
badge @/components/ui/badge
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
@/components/ui/badge Badge
lucide-react Copy, Check, Minimize2, Maximize2

State Management

React state variables managed within this tool.

Variable Initial Value
input ""
output ""
error ""
copied false
indent 2

Variables & Constants

Constants and computed values defined in this tool.

Name Value
parsed JSON.parse(input)
parsed JSON.parse(input)

Functional Logic

Internal functions that handle the tool's core logic.

Function Parameters Async
format() None No
minify() None No
copyOutput() None
Yes

External Resources

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