The Illusion of Competence in the Age of LLMs

Bartek Witczak
Bartek Witczak

I know the Elm architecture. I've built production apps with Redux. Unidirectional data flow, reducers, actions, state - I get it.

So when I decided to learn TCA (The Composable Architecture) for my small iOS side project, I thought: how hard can it be? Same principles, different syntax. I'll watch a few videos, take some notes, and start building.

The videos were fine. Everything made sense. I was nodding along, recognizing patterns from Redux and Elm. "Oh, that's just a reducer." "Right, that's like an action creator." I felt ready.

Then I opened Xcode.

I wanted to start with the simplest feature in my app - checking off a task in a list. Almost like a checkbox. That's it. Nothing else.

I had no idea where to start.

The Fluency Trap

There's a concept in cognitive science called the fluency illusion. When information flows smoothly into your brain - a well-produced video, a clear explanation, a polished tutorial - you mistake that smoothness for learning.

Your brain confuses "I can follow this" with "I can do this."

These are completely different things. Following along activates recognition. Building from scratch requires recall. Recognition feels effortless. Recall is where you discover what you actually know.

And I discovered I knew almost nothing.

What made it worse: my background in Redux and Elm gave me just enough recognition to feel confident. Patterns are more or less the same. I understood the concepts. I could explain them to someone.

What Changed When I Started Doing

I went back to the videos. But this time, I coded everything myself. Every step. Every feature. I paused, wrote the code, ran it, broke it, fixed it.

The difference wasn't that I was seeing the material for the second time. It was fundamentally different:

  • I hit problems the tutorials never mentioned. My app isn't the tutorial app. My data model is different. My navigation is different. The tutorial's clean example didn't map to my reality. Tutorial is simple by design.
  • I had to make decisions the instructor made invisibly. Where to put this dependency. How to scope this reducer. When to use a child store vs. inline logic.
  • I discovered connections between concepts that felt separate when watching. Reducers, effects, and the store aren't three independent topics. They interact in ways you only feel when you wire them together yourself.
  • I asked questions I didn't know to ask the first time. You don't know what you don't know until you're stuck in a compiler error with no tutorial to reference.

My understanding didn't just deepen. It changed shape entirely. I wasn't reinforcing what I'd watched - I was building something new.

And along the way, I wasn't just learning TCA. I was digging deeper into SwiftUI itself. Things I'd glossed over before suddenly mattered because I needed them to work.

The New Illusion

Here's where this gets uncomfortable.

I work with LLMs daily. In my React and Node projects, where I have years of deep hands-on experience, it works beautifully. I describe what I need with precision. I get code back. I immediately spot when something's off - a missing edge case, a security gap, a wrong assumption. I can guide the conversation because I know what good looks like.

In iOS? Different story.

Same me. Same LLM. But I describe things vaguely because I don't know the right terms. I get code back that looks reasonable - but I can't evaluate it properly. I find problems only through trial and error, by running the app and watching it break. And here's the unsettling part: I'm probably missing issues I haven't caught yet. I just don't know enough to see them.

This is the fluency illusion on a new level.

With tutorials, you eventually hit a wall. You open Xcode, stare at an empty file, and reality hits. The illusion breaks.

I did it intentionally "by hand". No LLMs. Just pure coding. I wanted to learn and deepen my knowledge.

With LLMs, you might never hit that wall. The code compiles. The feature works. You move on. And you never discover that you don't understand what just happened. The illusion doesn't just persist - it gets reinforced. Every working feature feels like evidence of your competence, when it's actually evidence of the tool's.

Watching a tutorial and thinking you learned something. Seeing LLM-generated code and thinking you understand it.

Same trap. New medium. Harder to escape.

What I'm Doing About It

I'm not here to moralize. I'm not going to tell you to delete your AI tools or grind through everything the hard way. LLMs are great tools.

The point is simpler: I need to keep doing.

Not because discipline is a virtue. Because passive consumption - whether it's videos, blog posts, or LLM-generated code - creates a feeling of progress that isn't real. The hard work isn't actually harder. It's just honest about what's happening in my brain.

So I'm building my app. Line by line. I use tutorials, docs, example apps, and yes, LLMs - but as references, not replacements. Every feature I implement myself. Every bug I debug myself. Not because I enjoy suffering, but because that's the only way the knowledge sticks.

I use LLMs in different way. I'm using it to explain concepts, to give me more references, to provide samples in my domain.

Five hours of videos taught me nothing I could use. Five hours of building taught me everything I needed.

The difference was never about time spent. It was about what I was doing with it.


If you're wondering why I keep jumping into new languages and ecosystems in the first place - it's intentional. The knowledge transfers. Redux patterns helped me recognize TCA. Elm's architecture gave me vocabulary for SwiftUI. Every language I learn makes the next one easier to pick up. I wrote more about this in Why I Learn a New Programming Language Each Year.