I've been using the same core pattern since my first job in 2018, in Python, jQuery, React, Django, and TypeScript, across DevOps platforms, BI applications, API integration layers, and large-scale transaction systems. I didn't learn it from a blog or a conference talk. I arrived at it from a simple, recurring frustration
Writing the same logic in slightly different ways, over and over, felt wrong.
What I found, and kept finding, in every project since, is that declaring intent in structured data and building one engine to execute it is categorically better than writing logic by hand, every time, for every variation. Better to build, faster to extend, safer to change, and easier for everyone around you to understand.
I'm writing this now because AI has made this pattern more powerful than ever. And I think it's worth naming clearly.
🚀 Where It Started: Writing JSONs I Barely Understood.
My first job was at a company building a DevOps automation platform on AWS serverless architecture. I had no frontend experience. My job was to write JSON schemas for each AWS service we supported i.e. VPC, subnet, security group, route table, etc and the platform would render them as forms on the frontend. I was an automation engineer, so naturally I automated that too by building a script that generated these schemas from the raw AWS documentation instead of writing them by hand, but the JSON pattern stuck with me.
🎨 The Canvas That Changed Everything.
The DevOps platform needed a UI, a visual canvas where engineers could drag and drop infrastructure components. Drop a VPC, drop a subnet inside it, connect resources, visualize the whole architecture. The existing implementation used images, fixed positions, and z-indexes to simulate this. It was rigid, slow, and tightly coupled to a specific set of backend assumptions. Adding a new resource type meant frontend changes, backend changes, and a long coordination cycle. A project that should have taken 3 months had taken 9.
I rebuilt the frontend from scratch in jQuery. Every element on the canvas, every resource block, every button, every nested component, was driven by JSON sent from the backend. The backend would send a config for a VPC that included its properties, its allowed children (subnets, internet gateways), its available actions (view logs, open form, collapse section), and its visual state. The frontend code had one job: interpret that config and render accordingly.
The result was a fluid, data-driven canvas where adding a new infrastructure resource type required no frontend changes at all. The backend team could introduce a new service, define its JSON config, and it would appear in the canvas fully functional with forms, actions, nesting rules, and all. We added live status tracking where resource colors updated in real time based on execution state, and a pipeline page that showed exactly what was happening inside a server being deployed, step by step, all driven by data.
That project went from 9 months to 3 months. Not because we worked faster. Because the system was designed to extend without rewriting.
📊 The BI Application: Design Once, Use Everywhere
A few years later I was leading both frontend and backend on a BI application with a very short deadline and a client who changed requirements constantly. The frontend had dozens of tables, each with different column and row configurations such as search, filters, dropdown filters, color-coded badges, status indicators, collapsible rows, icons, prefixes, suffixes etc. In a traditional approach each table would have been a custom component. With a tight deadline and a moving target of requirements, that would have been a disaster.
Instead I built one table component and described every table in JSON. Each column definition had keys like filter, badge, statusLight, prefixes, suffixes, colorCode, collapsible. The backend didn't just send data, it sent the skeleton for how that data should be rendered. A JSON config mapped specific keys to specific rendering functions. The key came from Django, the frontend looked it up, invoked the corresponding function. No if/else chains. No switch statements.
When the client changed requirements, the change was a JSON key. Not a component rewrite, not a PR with 200 changed lines. A JSON key. My teammates were genuinely confused about how I was shipping features faster than the requirements were changing. The ones who looked at the code understood immediately.
🔌 APIs as Data: The Library That Handled Everything
Later I built a Python-based API integration library for a serverless application that needed to talk to multiple third-party APIs, switching between providers dynamically due to throttling and data inconsistency. The library ingested JSON and each config declared the provider, endpoint path, parameters, and feature flags like s3: true, db: true, retry: true, sqs: true. Auth, throttling checks, retries, logging, and storage routing were all handled invisibly. A developer called one method and specified which features to enable. Everything else was abstracted.
I later rebuilt this in TypeScript for a large-scale application processing tens of thousands of transactions per day. With interfaces, the library became fully type safe. Every parameter, every path, every allowed operation typed from a central JSON definition. Developers wrote almost no integration code. They just called the method.
🧠 When JSON Becomes the Code
Everything so far has been about JSON driving UI or describing API calls. But the pattern goes deeper. There are two situations where JSON wasn't just configuring behavior, it was replacing logic entirely.
1️⃣ The Control Flow
Take a webhook receiver handling multiple ride states in an Uber-like application: ride_confirmed, driver_arrived, ride_started, ride_completed. The instinctive approach is an if/else chain, one branch per state, logic buried underneath. Every new state is a code change. Every change is a potential breaking point.
The JSON alternative is a dispatch table:
Adding a new state is adding a new key. The handler never changes. Pre-processing, post-processing, feature flags etc, all attachable without touching a single condition.
2️⃣ Execution Itself
What started as storing boto3 functions in a database eventually evolved into something more principled. A generic execution engine that ingested JSON
The handler instantiated the right boto3 client, called the right operation, passed the right params with no knowledge of S3 specifically. It worked identically for EC2, Lambda, SNS, RDS, anything. Adding a new AWS service meant writing a JSON definition, not code.
But the consequence I didn't fully anticipate was what this did to testing. Because every operation was fully described in data, you could validate it without touching real AWS infrastructure. No mocking, no staging environment dependency, no waiting for a deployment to find out if the config was correct. You validated the JSON against the schema, verified the service, operation, and params were right, and that was your test. It ran in milliseconds, with zero external dependencies. That testing capability, born directly from the execution engine pattern is a significant part of what made the 9-to-3-month result possible. The system was trustworthy because it was testable. And it was testable because the logic lived in data, not code.
The dispatch table and the execution engine look like different patterns. But they're the same idea at different levels. One uses JSON to decide which function to call. The other uses JSON to describe how to call it. In both cases, the imperative logic disappears and is replaced by data that a single, stable handler interprets. The code stops growing with every new case. The JSON does instead.
🏷️ The Pattern Has a Name (Several, Actually)
It took me years to learn that what I'd been building had formal names. The form generation pattern is called schema-driven UI. The canvas approach is a variant of data-driven rendering. The function dispatch via JSON is called a dispatch table or command pattern. It's a well-established concept in computer science.
I arrived at all of these independently, not because I'm exceptional, but because the problems kept pointing in the same direction. Every time I felt the friction of writing variations of the same logic, the answer was the same: declare it, don't write it.
I didn't have a CS degree to tell me whether this was "proper" engineering. I have a degree in electrical and electronics engineering. What I had was pattern recognition and a low tolerance for repetition. It turned out that was enough.
🤖 Why AI Makes This Pattern More Powerful
AI-assisted development is changing how software gets built. But there's a crucial distinction most conversations miss. There are two fundamentally different things you can ask an AI to do:
- Write a React component with state, hooks, event handlers, prop types, and rendering logic.
- Generate a JSON config for a table with five columns, where the status column is a filterable dropdown and the date column has a date range filter.
These are not equivalent tasks, and the numbers prove it.
StructEval (University of Waterloo, arXiv May 2025) is the most rigorous academic benchmark that directly compares LLM performance across structured formats including both JSON and React. Their findings, available at tiger-ai-lab.github.io/StructEval, are unambiguous: JSON generation is classified as a saturated task, scoring above 90% across models. React falls under their visual rendering category (StructEval-V), which they explicitly identify as "harder than text-only structures", pulling the overall GPT-4o score down to 76.02% and o1-mini to 75.58%. That benchmark was run on mid-2025 models. The gap has only widened since.
This changes the economics of the pattern entirely. The rendering engine which is the hard part, the part that requires real engineering, you build once. The config generation, the part that scales with every new feature, every new table, every new form, can now be delegated to AI with near-certainty. A product manager describes a table in plain English. AI generates the JSON config. The engine does the rest.
The pattern that took me 8 years to prove across different domains now has an accelerant that didn't exist before. The gap between intent and implementation just got smaller. And it got smaller precisely because the artifact in the middle is structured data, not imperative code.
What's Coming in This Series
This blog is the beginning of a series that goes deep on everything described above.
The data case first. Before the architecture, the numbers. Research on why AI generates JSON more reliably than code, the real cost of scattered handwritten API routes, and the hidden maintenance burden of one-off UI components. If you're making the case for this pattern to your team, you need evidence, not just intuition. And more importantly, where to draw the line.
Frontend and backend in depth. How to build a single table component and form renderer driven entirely by JSON config. How to declare your entire API surface in one place with full type safety, consistent auth enforcement, and auto-generated documentation. Design once, use everywhere.
The review argument and non-technical control. Why JSON configs are faster and safer to review than imperative code. And why a config-driven system lets the people closest to the product - PMs, ops teams, analysts make changes without raising a ticket or waiting on a developer.
What I'd Tell My 2018 Self
Everything I've built across these 8 years - the DevOps canvas, the BI tables, the API libraries, the dispatch tables, the escape hatches traces back to one instinct that I didn't fully trust for a long time.
Finding patterns is what you are good at. Use it and automate patterns. Every other thing is a facade on top of it.
The industry is catching up. The tooling finally matches the idea. And if you've been frustrated by repetition, by rigid systems, by the gap between what a product needs and how long it takes to build, this series is for you.
This is Part 1 of a series on JSON-driven programming. Next up: the data case - why AI generates configs more reliably than code, and what that means for how we build.


Top comments (1)