The proposal in the dependency review was one sentence: the package is ninety lines, and the model can write it. The security lead asked who writes the patch when the advisory drops. Someone gave a name. It was a developer who had been on the team for eleven months. The item was approved with a note.

This is how the enterprise software supply chain is changing. Not with a grand architectural shift, but with a developer bypassing a manifest entry to avoid a procurement delay.

Importing a package is a maintenance contract with a URL. You get the code, and you get an arrangement. Someone else watches for the CVE, ships the patch, answers the issue, and keeps the build green against a new runtime. You pay for that with adoption, not dollars. It is the cheapest on-call arrangement in the industry.

When a team replaces a dependency with generated code, they convert a shared obligation into a private one. The code might be identical in its happy path. The arrangement is gone.

An architect pulls the software bill of materials for a quarterly audit and notices it is shorter than last quarter. The auditors are pleased. It is shorter because six packages were replaced by files committed directly to an internal utilities folder. The dependency count went down. The maintenance burden just moved off the manifest and into the source tree.

Enterprise IT spent a decade building supply chain guardrails. Tools block unapproved open-source code. Scanners flag known vulnerabilities in specific package versions. Generative AI bypasses this entirely. A generated function checked directly into the repository is invisible to software composition analysis.

The threat model inverts. Today, the risk is that an upstream package gets compromised and you inherit the poison. Tomorrow, the risk is that nobody upstream exists to notice anything. When a known library has a vulnerability, the scanner catches it. When a model generates a custom implementation of that library’s logic, it often reproduces the exact same structural flaws that caused the original CVE. But the scanner cannot recognize it because the package signature is missing. No one files a CVE against a private helper copied into twelve repositories. The failure mode is no longer a poisoned dependency. It is silence.

The argument for regeneration relies on the premise that the library is small. The package was forty lines. The decision to import it was about four thousand.

For commodity glue—a retry helper, a thin CLI wrapper, a CSV shim for a specific vendor export format—regeneration is a reasonable call. You can specify the inputs, outputs, and failure modes.

For correctness-critical code, the forty lines are an API surface over years of accumulated edge-case handling. Timezone data, XML canonicalization, charset conversion, semantic version comparison. You cannot evaluate generated output you cannot specify. If the specification is four hundred edge cases you do not know, the model does not know which ones it missed either. Generated code you cannot specify is not a library. It is a liability with a plausible name.

The ecosystem argument for a language was never really about the code. It was about who gets woken up.

An incident bridge convenes at two in the morning. The failing component is a generated module in a language only two of the six people on the call can read fluently. The model’s output is on the screen, and nobody can tell whether the concurrency pattern is fundamentally wrong or just unusual. There is no upstream issue tracker to check. There is no release note explaining a breaking change. There is only the blame line in the version control system, pointing to a developer who prompted the file and moved to a different team six months ago. You can regenerate the code. You cannot regenerate the maintainer.

The pitch from the tooling vendors is that AI frees enterprises from ecosystem lock-in, making language choice irrelevant. The mechanism runs in the opposite direction.

Model competence tracks public code volume, which tracks adoption. Models generate excellent Python, TypeScript, Java, C#, and Go because the public corpus is massive. They hallucinate confidently in languages with smaller corpora. This creates a feedback loop. Better assistance raises the value of the languages you already have. The tail gets relatively worse with every model generation. Choosing a shrinking language means choosing to freeze at a permanent snapshot, because the corpus stops moving and so does the model.

Typed languages win for an unglamorous reason. A compiler is a free verification loop the model can fail against. In an untyped dynamic language, verifying generated output means writing tests. If the model writes the tests, you have built a mirror that reflects its own misunderstanding. Static types do not make a language better. They make generated code cheaper to reject.

The language still matters, though the criteria for choosing it have shifted. It matters less for the availability of one small package, and more for whether the generated code can be reviewed, operated, and changed by people who will not have the original prompt. You can drop a package you did not write, but the code you generated belongs to you now.