Skip to content

JSON Minify — C++ source

Remove all whitespace from JSON for the most compact serialization. Validates as it minifies, runs entirely in your browser, with a shareable link to your exact input.

This is the C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.

// json-minify — compact JSON to its smallest valid form. C++17 port
// (canonical TS: src/lib/json-minify.ts; Go twin: cli/json-minify). No
// stdlib JSON codec: a hand-rolled RFC 8259 scanner that validates, copies
// tokens verbatim and drops only whitespace; invalid JSON -> nullopt.
#include <iostream>
#include <optional>
#include <string>
#include <string_view>
struct JsonMinify {
    std::string_view in; std::string out; std::size_t i = 0; // input / compact output / read cursor
    char peek() const { return i < in.size() ? in[i] : '\0'; }
    char take() { char c = peek(); ++i; return c; } // '\0' at end-of-input
    void skipWs() { while (peek() == ' ' || peek() == '\t' || peek() == '\n' || peek() == '\r') ++i; }
    bool digits() { bool any = false; while (peek() >= '0' && peek() <= '9') { ++i; any = true; } return any; }
    static bool hex(char c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }
    bool str_() {
        out.push_back('"'); ++i; // opening quote
        for (;;) {
            char c = take();
            if (c == '"') { out.push_back(c); return true; }
            if (c == '\\') {
                char e = take();
                out.push_back(e);
                if (e == 'u') { for (int k = 0; k < 4; ++k) { char h = take(); if (!hex(h)) return false; out.push_back(h); } }
                else if (e == '\0' || std::string_view("\"\\/bfnrt").find(e) == std::string_view::npos) return false;
            } else if (static_cast<unsigned char>(c) < 0x20) return false; // control char / EOF
            else out.push_back(c);
        }
    }
    bool number() {
        std::size_t start = i;
        if (peek() == '-') ++i;
        if (peek() == '0') ++i; // "01" is rejected by the caller
        else if (peek() >= '1' && peek() <= '9') { ++i; digits(); }
        else return false; // bare '-'
        if (peek() == '.') { ++i; if (!digits()) return false; }
        if (peek() == 'e' || peek() == 'E') { ++i; if (peek() == '+' || peek() == '-') ++i; if (!digits()) return false; }
        out.append(in.substr(start, i - start));
        return true;
    }
    bool literal(std::string_view w) {
        if (in.substr(i, w.size()) != w) return false;
        out.append(w); i += w.size();
        return true;
    }
    bool value() {
        skipWs();
        char c = peek();
        if (c == '{' || c == '[') {
            char close = c == '{' ? '}' : ']';
            out.push_back(c); ++i; skipWs();
            if (peek() == close) { out.push_back(close); ++i; return true; } // {} / []
            for (;;) {
                if (close == '}') { skipWs(); if (peek() != '"' || !str_()) return false; skipWs(); if (take() != ':') return false; out.push_back(':'); }
                if (!value()) return false;
                skipWs();
                char d = take();
                if (d == ',') { out.push_back(d); continue; }
                if (d == close) { out.push_back(close); return true; }
                return false;
            }
        }
        if (c == '"') return str_();
        if (c == 't' || c == 'f' || c == 'n') return literal(c == 't' ? "true" : c == 'f' ? "false" : "null");
        return (c == '-' || (c >= '0' && c <= '9')) && number();
    }
    static std::optional<std::string> minify(std::string_view input) {
        JsonMinify p{input};
        if (!p.value()) return std::nullopt;
        p.skipWs();
        if (p.i != p.in.size()) return std::nullopt; // trailing garbage
        return p.out;
    }
};
int main() {
    std::cout << JsonMinify::minify("{\n  \"a\": 1,\n  \"b\": [\n    1,\n    2\n  ]\n}").value_or("(invalid)") << '\n'; // {"a":1,"b":[1,2]}
    std::cout << JsonMinify::minify("{invalid}").value_or("(invalid)") << '\n'; // (invalid) — invalid JSON
    return 0;
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →