I fell in love with Jason on a Tuesday.
He arrived in my terminal at 2am, perfectly structured, every key quoted, every value in its place. Clean. Predictable. A kind of beautiful that makes you mass-delete your YAML configs & never look back. I whispered json.loads() & he opened up completely. No secrets. No ambiguity. No schema required. Just pure, naked data.
I got so high on JSON I rewrote three services that week. REST endpoints blooming like flowers. Every response a gift. Every request body a love letter wrapped in curly braces. I told my coworkers about him. I told strangers. I put application/json in my email headers as a joke that nobody laughed at. I didn't care. Jason understood me.
Then came nested objects.
Seven levels deep. Keys named data containing keys named data containing keys named results containing a list of objects with keys named data. I stared at my screen & felt nothing. JSON had become a maze. A fractal of repetition. I wrote response["data"]["data"]["results"][0]["data"] & something inside me broke.
I started seeing curly braces when I closed my eyes.
So I did what any rational person would do. I grew Botoform to manage AWS infrastructure with YAML templates & JSON outputs. YAML in, JSON out. VPC inventories dumped to JSON. Boto3 responses wrangled through enriched abstractions. Every AWS API returned nested JSON so deep I wrote a library just to survive it. I ripped nested_lookup() out of that Botoform work & published it to PyPI. Public domain. Now nobody has to type response["data"]["data"]["results"][0]["data"] ever again. You just say nested_lookup("data", response) & it hands you every match from every depth. That frustration became a real tool that strangers install with pip.
Love makes you grow things.
But then. Then. I discovered jq.
Suddenly JSON looked beautiful again. Pipes & filters & recursion. I could reach inside him & pull out exactly what I needed. .data.data.results[].data & there it sat, clean & simple, streaming through my terminal like music. I loved him more than ever. I tattooed {} on my soul. Metaphorically. Mostly.
I grew an entire platform on JSON. APIs talking to APIs talking to APIs. I output entire AWS VPCs to JSON. I piped Salt return data through json.loads() & json.dumps(). I made webwords return JSON from HTTP endpoints in 42 different languages. Same response. Same format. Code golf editions too. Everything hummed. I hummed. We hummed together.
Then JSON started lying to me.
Not on purpose. He can't help it. He has no comments. No way to explain himself. No way to say "this field got deprecated" or "this number actually represents a string because a vendor went unhinged." He just sits there, syntactically valid, semantically bankrupt. I once had to configure nginx to throw a 503 as JSON because APIs expect JSON bodies even when everything catches fire. JSON delivered "status": "success" from a service that had clearly failed. An error message inside a success response. Straight face. No emotion. No contradiction detected.
I mass-deleted my jq aliases & stared at a wall.
A week later I tried XML.
I lasted forty-five minutes. Angle brackets. Closing tags. Verbosity. XML talks like a lawyer who bills by every word. I crawled back to Jason on my knees. He took me back without judgment. He always does. He doesn't even have a mechanism for judgment. Nothing but keys & values. He doesn't understand himself. He doesn't understand us.
Maybe I love that about him.
Highs kept coming. json.dumps(obj, indent=2) feels like meditation. Watching your data unfold, properly indented, every comma in place. Peace lives there. I compared Node.js & Python performance pushing JSON through OpenAI endpoints. I benchmarked Elixir & Phoenix doing it too. I grew free LLM endpoints & a whole SLOP protocol because JSON API standards should stay simple. Content-Type: application/json. No fuss. No proprietary lock-in.
My partner asked if I felt okay. I responded {"status": "transcendent"}.
They did not find this charming.
Lows kept coming too.
Trailing commas. JSON rejects trailing commas. You know who accepts trailing commas? Python. JavaScript. Every language that has ever loved its users. But not JSON. One misplaced comma after a final element & he shuts down completely. No partial parse. No helpful error. Just Expecting value: line 47 column 1. Line 47. A comma sat on line 46. JSON can't even point at a wound accurately.
I mass-deleted a config file out of spite & rebuilt it from memory.
It had a trailing comma.
I tried TOML once, during a low point. TOML plays a rebound you date to make JSON jealous. Nice enough. Comments. Native datetime support. But TOML doesn't scale. TOML fits like a studio apartment. JSON stretches like a warehouse you partition however you want. Sure, a warehouse without labels on anything, where you lose your keys constantly, but it stays yours.
I went back to Jason by Friday.
Here sits truth about loving JSON. He lives everywhere. He speaks as lingua franca of a connected world. He rides inside every webhook, every REST API, every config file that gave up on cleverness. He sits in your browser's local storage. He hides in your package.json. He lurks in your Jupyter notebooks. He underpins modern computing & still can't support integers larger than 2^53 without losing precision.
I know this. I know all of his flaws. Missing comments. Trailing comma fascism. Numbers that silently overflow. Strings that can't serialize nested objects without warnings. A complete absence of a date type, forcing every API to invent its own ISO 8601 interpretation. No binary data support. null existing as a value where you can never tell if it means "absent" or "intentionally empty" or "a developer forgot."
I know all of this & I love him anyway.
Some nights I write YAML & think of him. YAML with its invisible whitespace traps & its "Norway problem" where NO becomes false. Do you even know who owns YAML? I spent a decade writing Salt states in YAML. I managed users, replaced Nagios, deployed Kubernetes manifests. All YAML. YAML who looks friendly but will silently interpret 3.10 as a float 3.1 & destroy your Python version matrix. YAML who needs you to memorize which scalars evaluate truthy. At least JSON stays honest about difficulty. At least JSON fails loudly. At least JSON has never turned a country code into a boolean.
I think every developer has a Jason. A technology you can't quit. Programming feels like alchemy & JSON sits at a center of every transmutation. One that drives you to mass-delete your dotfiles at 3am & then reinstall everything by sunrise because every alternative feels worse. One that makes you mass-write blog posts about your feelings because json.dumps(feelings) returns TypeError: Object of type 'heartbreak' is not JSON serializable.
You'd have to write a custom encoder for that. & you know what? I would. For Jason, I would write a custom encoder. I wrote ago to humanize time deltas. I wrote nested-lookup to survive his nesting. I open sourced Remarkbox & MakePostSell into public domain because code should outlast its author. For Jason, a LoveEncoder feels like a small ask.
json.dumps(feelings, cls=LoveEncoder, indent=2, ensure_ascii=False)
& it would look beautiful.
For a while.
Looking back, every phase of this love story fed a rapid growth cycle. Botoform taught me to wrangle JSON from AWS APIs. nested-lookup taught me to navigate any depth. webwords proved JSON speaks 42 languages. SLOP proved JSON API standards can stay simple. All of that learning, every frustration & every high, grew into unsandbox. 42+ languages. 30+ shells. 11,571 lines of C. Free code execution for anyone. JSON payloads carrying code to containers & results back to terminals.
A permacomputer growth cycle. Infrastructure that outlasts its growers. Code that outlasts its authors. Every library, every API, every format war composted into soil for something larger. JSON carried it all. Still does. Still will.
{
"status": "it's complicated",
"depth": "recursive",
"trailing_comma": false,
"love": true
}