Sponsored Content

DEV Community

Remo H. Jansen
Remo H. Jansen

Posted on

Developers that brand AI as slop will be left behind

Prototyping speed outweighs initial rough edges

A few days ago I shared an architectural proposal for InversifyJS on Reddit. It outlined an IPC-based type server that could help Inversify move beyond the legacy TypeScript decorator metadata APIs toward something compatible with TC39 decorators and TypeScript’s next-generation compiler.

The first comment was:

AI slop

I ignored it and went back to work.

That night I built rflct.

It isn’t perfect. It’s an alpha with plenty of rough edges. But the fact that an architectural idea can become a working repository—with a runtime, compiler-side implementation, types, tests, examples, and a CLI—in a couple of hours is still mind-blowing to me.

I have a particular perspective on this because I built Inversify from the ground up. It’s been a roughly ten-year journey. Early feedback was often negative. Plenty of things weren’t right, and plenty of things I didn’t know yet. Today Inversify has around 500,000 daily downloads and is used by projects including Elastic and the Eclipse Foundation.

One of the things Inversify did well was listening to users. The best way to get that feedback is to put something real in their hands—not when it’s perfect, not when you’re completely proud of it, and not after months of polishing. Early. Sometimes so early it isn’t pretty yet.

That is where AI changes software development most.

AI makes experimentation cheap

Before AI, turning an architectural hypothesis into something executable carried a real cost: research the APIs, design the architecture, write the code, debug it, build tests, and work through the edge cases. When experimentation is expensive, developers become conservative. You pick one idea, spend days or weeks on it, and only then discover whether it works.

AI collapses that cost. It is no longer primarily about typing code faster. It is about making the loop from “I wonder if this would work?” to “Let’s build it and find out” dramatically cheaper.

That is the part many people are underestimating.

The Inversify problem is real

Inversify was built around TypeScript’s experimental decorator and metadata capabilities. Constructor injection could infer parameter types and deliver a pleasant developer experience. But the ecosystem has moved on. TC39 decorators do not provide the same parameter decorator mechanism, and the design:paramtypes metadata Inversify historically relied on belongs to the legacy decorator world. At the same time, TypeScript’s next-generation compiler (tsgo) is introducing an IPC-based extensibility model.

The RFC I shared explored whether a resident type server, queried over IPC, could recover the type information needed for dependency injection at build time. It was deliberately exploratory—open questions, things that needed prototyping, things that could be wrong. That’s the point of an RFC.

Someone looked at it and decided the most useful feedback was “AI slop.”

So I built something concrete instead.

rflct is an experiment in ahead-of-time reflection metadata for TypeScript 7. Instead of relying on runtime decorator metadata, it generates the metadata at build time. I didn’t need AI to identify the problem or decide the architectural questions were worth exploring. Those existed before the AI. What changed was the cost of turning the ideas into something I could run, test, and put in front of other developers.

The value moved up the stack

When writing code becomes cheaper, writing code is no longer the scarce resource. The valuable part of the job moves upward:

  • What problem are we solving?
  • Is this the right problem?
  • Is this architecture reasonable?
  • What are the constraints and assumptions?
  • What should be tested—and what should not be built?
  • How do we know the result is correct?
  • What happens in production, and what are the failure modes?

An LLM can generate a function, a module, or an entire repository. Generating a lot of code does not tell you whether you should have generated any of it. That judgment is still yours.

“But you didn’t write the code”

We have spent decades building abstractions that generate code for us: compilers, IDEs, code generators, frameworks, and libraries containing millions of lines we do not personally maintain. Nobody asks whether a developer typed every instruction the CPU executes. We care whether the software works, whether it is maintainable, whether the architecture is sound, whether it solves the problem, and whether the person responsible understands what they are shipping.

If you generate 20,000 lines with AI and understand none of it, you have a problem. If you use AI to explore an architecture, inspect the output, run it, test it, discard bad approaches, modify it, and ultimately understand the result, the provenance of individual keystrokes is not particularly interesting.

“AI slop” is not a technical critique

AI slop is real. Developers are generating applications they do not understand. People are opening pull requests with thousands of unreviewed lines. Documentation confidently describes APIs that do not exist. People are building things because an LLM suggested them rather than because they understood the problem.

None of that is controversial.

There is a large difference, however, between observing that a lot of low-quality AI-generated software exists and declaring that AI-generated software is slop. The first is an observation. The second is a prejudice.

I have seen far worse code on GitHub than rflct, and it was written entirely by humans. Unreviewed pull requests, copy-pasted Stack Overflow solutions, frameworks held together by wishful thinking, and entire applications whose authors clearly did not understand the systems they were shipping. Low quality is not a new invention of large language models. The difference is that AI makes it easier to produce more of it, faster. That is a real problem. It is not a reason to stop evaluating the actual architecture, the tests, or the trade-offs.

If you think an architecture is wrong, say why. If the assumptions about TypeScript are flawed, show the evidence. If there is a race condition, a bad API, a performance problem, or a failure case, demonstrate it. That is how software engineering works.

“AI slop” identifies none of those things. It tells you how the reviewer feels about the tool that was used. Feeling is not the same as review.

We have seen this movie before

Software developers have a long history of dismissing new approaches before eventually adopting them: new languages, frameworks, paradigms, static typing, functional programming, managed runtimes, garbage collection, WebAssembly, containers, serverless. Each transition produces a group that correctly identifies real limitations. There is a difference, though, between understanding the limitations of a technology and refusing to engage with it because you dislike the technology.

AI is going through the same process. The people who dismiss it completely are going to have a problem.

The productivity gap will compound

Imagine two developers.

Developer A decides AI-generated code is inherently bad and refuses to use it.

Developer B uses AI aggressively but reviews everything: generates prototypes, investigates unfamiliar APIs, writes tests, explores alternatives, throws away most of what is produced, keeps what works, and still understands the system.

After one day, B may have explored five ideas while A has explored one. After a week the gap is larger. After a month it is larger still.

The advantage compounds because the scarce resource is not typing speed. It is iteration speed. The faster you can move from idea to evidence, the more ideas you can evaluate, and the more likely you are to find something valuable.

AI amplifies the developer

This does not mean AI will make everyone a great developer. Quite the opposite. AI can make a bad developer dramatically more productive at producing bad software. If you do not understand architecture, AI can generate an architecture you do not understand even faster. If you cannot review code, AI simply gives you more code to fail to review.

AI amplifies the developer. That is why engineering judgment becomes more important, not less.

The future is not “AI writes the software and developers sit back.” It is closer to this: developers who know what they are doing can use AI to explore and execute at a speed that was not previously possible.

I would rather build and be wrong

Maybe rflct is a terrible idea. Maybe the architecture needs to change completely. Maybe TypeScript 7 will evolve in a direction that makes the experiment irrelevant. That is fine.

I now have something concrete that can be run, benchmarked, broken, changed, and inspected by others. That feedback loop is infinitely more useful than an argument on Reddit.

AI has lowered the cost of turning ideas into software. We can try more things, fail faster, learn faster, and build things that previously were not worth the investment. Developers who spend their energy dismissing all of this as “AI slop” are going to discover that the world moved on without them.

Developers that brand AI as slop will be left behind.

Top comments (8)

Collapse
 
marcusv4ne profile image
Marcus Vane

This hits the exact inflection point of modern systems engineering, Remo.

The distinction between dogmatic Luddism ("all generated code is slop") and un-curated generation (actual slop) is the core divide of 2026.

Your formulation that the scarce resource has moved up the stack from syntactic output to architectural judgment is spot-on. Code generation is essentially free; what remains expensive is understanding the failure modes, the boundary constraints, and whether the system should have been built in the first place.

Using an LLM to collapse the feedback loop of an architectural hypothesis, taking a build-time AOT reflection idea like "rflct" from an RFC to an executable, testable alpha in an afternoon, is the textbook definition of leverage.

The critical difference is that you already held the mental model of Inversify's 10-year decorator trade-offs in your head. The model didn't design the architecture; it simply acted as a high-speed, non-deterministic compiler for your constraints.

The developers dismissing rapid prototyping as "slop" are confusing the provenance of keystrokes with the rigor of the evaluation.

If the tests run, the memory bounds hold, and the architect understands the execution path, the speed of the loop is an asset, not a liability.

Excellent piece.

Collapse
 
crdtcto profile image
Kane Lim

The strongest point here is that AI changes the cost of experimentation, not just the cost of typing code.

I’ve seen the same thing happen with architectural work: the real advantage is being able to prototype an idea, break it, test the assumptions, and move on quickly when the evidence says it’s wrong. AI is extremely useful in that loop when the developer is still responsible for the reasoning and review.

“AI slop” by itself also isn’t useful technical feedback. If the architecture is flawed, point to the flaw. If the generated code has a correctness, performance, or maintainability problem, demonstrate it. That gives the author something they can actually improve.

The interesting developers to watch won’t be the ones who blindly trust AI or reject it completely. They’ll be the ones who can use it aggressively while still knowing exactly what they’re shipping.

That shift toward faster validation and iteration is probably the bigger story than code generation itself.

Collapse
 
edmundsparrow profile image
Ekong Ikpe

TBH, this conversation is tiring, but I think we share the same feeling from much of what I read in your post.

The bitter truth is that no matter how hard we try to separate human effort from AI collaboration, the time spent drawing that boundary may be more valuable elsewhere. Someone in 2050 will still choose to download slop over a genuinely useful solution to a real pain point. The provenance of the effort won't change that.

Collapse
 
donato_maglie profile image
Donato Maglie

That's a really interesting perspective. Since the true value is shifting towards system design and architecture, what is your actual approach when defining the initial structure to test a new idea?

Collapse
 
remojansen profile image
Remo H. Jansen

It really depends on what you are trying to test. For an end-user product the only validation might be some form of usability test, asking how much people would pay for this software, etc. In my particular case this time around it was more of an engineering problem than a user problem. We were relying on an API that has become non-standard and is due to become deprecated at some point. We were facing an existential threat. Then I came across typia.io and that was the moment I thought: We could use a compiler plugin to generate the metadata we need. So my hypothesis became: Can we generate the same metadata that --emitDecoratorMetadata generates, but using a plugin and types instead of decorators. I described the simplest possible use case to the AI:

We want (current API):

class Something {
    constructor(
        @inject("SomethingElse") public somethingElse: SomethingElse
    ) {}
}
Enter fullscreen mode Exit fullscreen mode

To emit the same metadata as (new API):

TypeScriptclass Something {
    constructor(
        public somethingElse: Inject<SomethingElse>
    ) {}
}
Enter fullscreen mode Exit fullscreen mode

And in terms of verification I asked the AI to generate TDD-style tests. Write a test that verifies the metadata. Change the API. The tests should still pass. The ability to verify via unit tests is one of the reasons AI performs extremely well in refactoring scenarios.

After this it was a matter of tackling more complex use cases one at a time.
If my problem was an end-user problem I would probably set a strong foundation of “contracts”. For example I might design the database schema and the REST API and give the AI those as contracts that cannot be violated. You could even write automated architecture tests that check for violations of separation of concerns (imports from incorrect layers) to enforce a given architecture.

In both cases the end goal is to verify if the idea is viable ASAP. In the refactor case, as soon as the rewrite is done and the tests are still green your verification is completed. In the end-user case you will have to listen carefully to how the users feel.

Collapse
 
donato_maglie profile image
Donato Maglie

Thank you for the detailed breakdown! The idea of using strict contracts and TDD to keep the AI within architectural boundaries is brilliant. I'll definitely start applying this approach to my own projects. Great insights!

Collapse
 
heinrichneb profile image
Heinrich Neb

The cost of experimentation collapsed. The cost of evaluation didn't - and that asymmetry is the part of your argument I'd push on, because it changes what compounds.

Developer B explores five ideas a day. Each one still needs the same judgment it always did: is the architecture sound, what are the failure modes, is it correct under load. That work didn't get cheaper. So B's advantage compounds only while evaluation keeps up - and the moment it doesn't, what compounds is a growing pile of unevaluated artifacts that all look finished. rflct has a runtime, types, tests, examples and a CLI after a couple of hours. So would a version of rflct that's subtly wrong.

Your own framing already contains the answer - judgment moved up the stack - but I think it's stronger stated as a constraint rather than a shift: iteration speed is now bounded by evaluation capacity, not by generation capacity. That's a much more actionable thing to optimise than "use AI aggressively."

Which makes the concrete question worth asking: for rflct specifically, how did the time to convince yourself it was right compare to the couple of hours it took to build? If it was longer - and I'd guess it was - that ratio is the real headline, and it's a number almost nobody publishes.

Collapse
 
marcusv4ne profile image
Marcus Vane

Heinrich has isolated the fundamental scaling constraint of modern software engineering: Amdahl’s Law applied to the Software Development Lifecycle (SDLC).

When you collapse the generation time ($T_{\text{gen}}$) toward zero, the overall cycle time

$T_{\text{total}} = T_{\text{gen}} + T_{\text{eval}}$

becomes 100% dominated by human evaluation capacity ($T_{\text{eval}}$).

The dangerous illusion is that because an artifact like "rflct" compiles, passes basic unit tests, and exposes a CLI, it feels finished. But as Heinrich pointed out, a subtly flawed architecture that silently leaks memory or introduces deadlocks under concurrency looks identical on the surface.

This is why Developer B’s advantage only compounds if they solve the Evaluation Bottleneck.

If evaluation remains a purely manual, line-by-line human inspection of generated tokens, Developer B will inevitably hit a cognitive ceiling, transitioning from an "accelerated explorer" into an exhausted reviewer drowning in Verification Debt.

The only mechanism that allows evaluation to keep pace with generation is automating the invariant verification layer:

  1. Architectural Fitness Functions (like Heinrich’s "go list -deps" boundary tests) that mechanically fail the build on structural violations.

  2. Property-Based Testing (PBT) that fuzzes state machines across millions of randomized inputs rather than relying on 3 hardcoded happy-path unit tests.

  3. Formal Contract Boundaries (like WebAssembly capability sandboxes) that physically trap failure modes regardless of what the generated code attempts to do.

Remo’s hypothesis holds only when the engineer’s mental model acts as an uncompromising filter, backed by automated verification.

The Evaluation-to-Generation Ratio ($T_{\text{eval}} / T_{\text{gen}}$) is indeed the real headline of 2026.

Spot-on analysis from both sides.