Platform teams across thousands of organizations are writing nearly identical Kubernetes controllers to wire together objects and copy fields between them, according to a technical report published by The New Stack in conjunction with KubeCon + CloudNativeCon. The report examines kro, the Kube Resource Orchestrator, which moved to Kubernetes SIG Cloud Provider in September 2025 as a shared primitive for resource composition. The central finding is that while Kubernetes provides all the necessary ingredients—CRDs, controllers, server-side apply, and CEL expressions—it doesn't supply a recipe to declare that multiple resources form one thing or that values in one must wait for another's status.

The report details how every tool managing sets of resources builds the same composition machinery independently. Helm handles it at render time, with version 4 adding server-side apply and waiting on resource status. Argo CD introduced sync waves, hooks, and health checks because manifests can't specify the order they need or when they're finished. Crossplane uses compositions and functions, with version 2 composing native Kubernetes resources directly, while operators implement the logic by hand in Go. The tenth controller a team builds carries its own reconcile bugs, upgrade path, and on-call rotation, despite performing the same glue work as the first. Kro version 0.10 separates composition into two parts: ResourceGraphDefinitions, which create reusable APIs with custom resources, and Graphs, which react to existing cluster state without generating new instance types.

The authors write that "an explicitly declared order is a second description of a relationship the manifests already contain, and the two can disagree after any rename or reorder." Kro derives dependency graphs from references in CEL expressions rather than requiring teams to declare order separately, ensuring the two descriptions can't drift. "The cost of an abstraction moved from writing it to owning it: ten codebases gone, ten APIs left," the report states, noting that kro refuses schema changes that would break existing instances unless the author explicitly allows it. The report observes that wherever order is declared apart from the reference that needs it, there are two sources of truth and an opportunity for drift.

The report argues that composition machinery appears throughout Kubernetes platforms in disguised forms—naming conventions to synchronize strings between manifests, sync waves encoding dependency graphs as step order, and scripts copying status fields between objects. These exist because underlying tools can't express dependencies between objects or observe current cluster state, forcing the dependency to live elsewhere as a string, step number, or script. A composition tool returns it to its proper place as a reference between objects, continuously watched and evaluated inside a graph. The pattern mirrors Kubernetes' earlier evolution, when rolling updates moved from a kubectl subcommand into the Deployment controller, simplifying everything built on top.

The report's central question is whether composition should remain something every platform builds independently or become a shared Kubernetes primitive. Teams should count APIs rather than controllers, since application teams point manifests, RBAC, and pipelines at those APIs, making each one a promise that breaks downstream systems when fields are removed. The authors position kro as evidence of what changes when composition machinery becomes reusable and relationships become declarative rather than procedural. If composition is what nearly every platform needs, the machinery to provide it may be what Kubernetes is missing. The shift from bespoke controllers to shared primitives could reshape how platform teams allocate their engineering time, moving effort from reimplementing established patterns to designing APIs that serve their particular organizations. Whether that consolidation happens through kro or another approach, the economics of building the same component thousands of times independently make a compelling case for standardization.