Last night I achieved something with Cursor that I’m genuinely torn about: I successfully used a library while learning almost nothing about it.
Some general preamble, since I haven’t talked about this here, before.
In the past I had been skeptical about the value of AI for coding. Early Copilot capability was “a neat trick” but got in the way more often than not and I turned it off. The latest generation of “agent”-based assistance is another story. There has been amazing progress. This is a clear, genuine productivity enhancement and beyond that, it sometimes feels like magic.
As far as “AI use” goes I’m not a purist or zealot in either direction. There are definitely harmful use cases, and there are definitely issues with how AI is trained on some forms of creative works and can then be turned around to more-directly recapitulate or embody those same or similar works. Society needs to figure this out. But just saying “no” isn’t a credible answer. While there are a lot of stupid, banal use cases (e.g., anything Facebook throws at you), there are also ways that it can be a transformative productivity enhancement, they’re real and valid. It’s not going to lead to some post-work society (in either the utopia or distopian fashion), or any kind of overnight transformation. It’s also not a flash in the pan.
I am starting to believe that it’s inevitable that if you are a computer user in your job, and you want to stay employed in the long term, learning how to use AI tools is a growth skill you’ll need just like office workers in the late 90’s needed to learn how to use the Internet (which was also controversial before it became inevitable). The upshot of all this is that I’ve recently been digging into LLM codegen with Cursor: what models to use, how to prompt it, how to use custom rules, and to learn its strengths and weaknesses and how to get the most out of it.
But back to generating code…
I asked it to build a React component to draw a certain kind of diagram from a dataset, and use ReactFlow. It did it in a minute. The only thing I had read in the docs to that point was the right npm
incantation, since Cursor still isn’t great at running bash commands in my git repo.
The nodes rendered but not the edges. I pasted the error msg from the browser console into Cursor along with a screenshot of situation and told it to fix the problem. The agent succeeded in one shot. I made another request for it to tweak some styling and Cursor updated the css. Also one shot.
Then I actually had to look at the docs for some props to figure out how to disable letting the user drag nodes of the graph around. This is the entirety of where I actually had to learn anything. This took only a couple of minutes.
What does this mean, though?
I’m not gonna lie, this is an unsettling experience for me. On the one hand: I used a third party library, successfully hit the brief, did it in under 20 minutes. Absolute victory.
And I learned practically nothing from the experience, whereas I’m used to basically tearing libraries apart inside out before wiring them into a project by hand. If Cursor disappeared tomorrow, it would be as difficult to debug any new behavior issues in that React component as if I were starting writing from scratch.
I certainly get why people are concerned about kids using LLMs in college essays. This totally defeats the purpose of those exercises. But even now, I am personally unlikely to need to be super proficient with ReactFlow, so this is “fine,” but I wonder about the degree to which we’re setting ourselves up for failure of maintainability (the software engineers I work with, or the tech sector as a whole).
There is a real tradeoff between “this is not core to my capabilities so I need to get it out of the way,” vs “I need to learn this stuff the hard way” vs “it is core to my work but I’m under pressure so I will dispatch the job with AI now and move on / ‘come back later’ (yea right).” I don’t know if anyone has really worked through how to balance these concerns. And I don’t think there’s a “free lunch” answer that gets you both the immediate productivity boost and the knowledge.
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?
— Brian Kernighan
One way or another, we need to each make these tradeoffs, and we need to guide more junior engineers to make the decisions that grow them into senior engineers, without just blindly forcing them to each work with one hand tied behind their back—it’s inevitable in such cases that they’ll be upstaged by other engineers who “cheat” to get ahead.
My teachers in elementary school didn’t let us use calculators on tests. (“You won’t have a calculator in your pocket when you’re just walking around in life”, they confidently mispredicted.) And I think the ubiquitous availability of calculation on demand has actually been a good thing for society. We’re now at the stage where we have to confront much more complicated forms of this problem, and I haven’t seen a lot of good guidance for individuals or for team leads in industry that wrestles with this balance in a nuanced way.