Building Software Is No Longer a Nightmare

Will Large Language Models make us better coders or worse? While this questions will take time to settle, one thing it clear: LLMs have finally broken down the barriers to creating and publishing open source. How many projects took off quickly with the implementation of the core logic only to run into a wall once it came to “all the other stuff”, such as:

  1. Version control & hosting
  2. Packaging
  3. Publication
  4. Testing
  5. Documentation
  6. UI/UX

Your experience might differ, maybe you’re a git-whiz who is cranking out command-line-foo like there’s no tomorrow. Or maybe you honed the perfect setup to scaffold and automate tasks like packaging or testing over the years. Lucky you! But the majority of developers are grinding every day through an ungodly mess of confusing git commands, dependency issues, and contradictory testing practices. And I won’t even go into the hell that is frontend development for the sake of our collective sanity 1.

Most programmers probably spend more time on peripheral issues than they are prepared to admit. It’s not too unusual to burn an entire afternoon on resolving version conflicts, or desperately trying out random configuration options. Of course, none of this ever felt like it had anything to do with solving the actual task at hand. No new feature, no performance improvement came out of these excursions, just unadulterated frustration and a sense of being an imposter. Was anyone really living up to their CS degrees when they were blindly mashing keys like a monkey on a typewriter?

Fortunately, if nothing else, LLMs have undoubtedly broken down the penumbra of semi-professional software development2. What used to take days of trudging through Reddit posts, GitHub discussions, and trying to read pay-walled Medium posts is now just a prompt away. In the olden days, building applications and publishing them online required solving a whole range of unrelated problems from which our multi-headed overlords have finally freed us.

Why was it so hard to begin with?

There are probably three major sources of frustration for any hobbyist or semi-professional developer.

Too many languages (and frameworks)

The sheer amount of programming and scripting languages would turn any normal person’s brain to mush. Ever heard of an interpreter speaking more than 10 languages? But that is what programmers are faced with. Think back to all the programming, scripting, configuration, automation, markup, style and query languages you’ve come across3!

Hobbyist developers can’t afford to develop all the necessary code from scratch and are thus reliant on pre-existing libraries and frameworks. Modifying, configuring, or integrating with 3rd party code thus often requires becoming familiar with the developer’s favorite language and framework.

Poor documentation

Most of us have probably come across cases where we just couldn’t get something to work until we found that one crucial hint in some random tutorial or GitHub issue discussion. It’s rare to come across documentation that is complete and updated regularly. When even Google struggles, what can we really expect from open source projects?

Rapidly evolving ecosystem

Keeping up with new languages, frameworks, and best practices can be overwhelming. Developers constantly have to decide whether to hone the skills they already have or learn a new thing. It feels like a gamble that one should not be required to make. There is a reason why open source developers burn out quickly and abandon projects. The ever changing ecosystem with its fads and breaking changes makes it hard to hold on to what works and is well-understood.

Open source is more fun with LLMs

LLMs allow anyone to focus on implementing their core idea again rather than suffering through learning a new language for a one-off project, figuring out packaging & distribution, setting up testing and so on.

How does LLM-assisted coding deliver us from the nightmare that is modern software development?

  1. LLMs make everything accessible via human language. LLMs can instantly explain any piece of code to you or translate it into a programming language you know. LLMs can implement your human-language specifications into any programming language. Using human language to read and write code greatly reduces “language barriers”.

  2. LLMs filter out the noise. LLMs gather answers across many sources, including documentation, blog posts, and forums and distill it down to your specific circumstances with summaries and example code. With the right prompt they give very straight answers4 making you wonder why you ever read through pages of Stackoverflow answers arguing about the relevancy or duplication status of a question.

  3. LLMs don’t shill. LLMs don’t pressure you into adopting a new framework. They mostly base their recommendations on your requirements or what fits with your existing code base.

  4. LLMs help iterate. Have you ever felt stuck? Sometimes nothing seems to work. Now, if something fails, let the LLM respond to the error message, diagnose the issue and recommend possible solutions. Still can’t get it to work? Pivot! Try a different framework/library. Have the LLM translate the existing code to fit with the new dependency. Or let the LLM build custom code instead of hunting for a library that works with your code.

Caveats

Of course, not all is rosy in LLM land. LLM responses get better the more context is provided. Like humans, LLMs can misinterpret your question, over-complicate solutions, forget, and go off on tangents. Thus you should use git liberally. Commit changes before every prompt and don’t be afraid to revert to previous versions that worked and try again with a better prompt based on what you learned. I found that the following rules achieve overall better results.

  • Provide motivation to your question. What are you trying to achieve overall?
    • "I am building a chat app with a FastAPI backend and a React frontend. What is the best way to ..."
  • Ask broader questions first. Ask for options and review the pros & cons.””
    • "What are the 2 most popular Python build backends."
  • Narrow down the tech stack and emphasize what options you picked.””
    • "I want to use hatch. How can I create a dedicated testing environment."
  • Don’t be afraid to backtrack. LLMs can take you into the wrong direction.
    • "Your suggestion to ... is too complicated/does not work. I reverted all changes."
  • Break up more complex tasks. Ask to make a plan first, which is then in the LLM’s context window to guide further responses.
    • "[Complex question]. Make a plan first, don't implement anything yet."
  • Let the LLM do the busy work.
    • "Create a unit test for [code]. Create a docstring for [code]."

These are just some general rules. Obviously, an editor with an integrated agent that has full access to you source code will behave differently than editor-to-LLM copy-and-pasting. (I might discuss specific tools in a follow-up article.)

Conclusion

It has become a whole lot easier to share self-developed software. Tasks (such as packaging, publication, testing and documentation) which used to distract from the core development have become infinitely more accessible with LLMs.

I’ve added some query-answer pairs below for illustration. (Some content has been removed for brevity.)

  1. Vanilla, React, Angular, Vue, Svelte, Preact, Lit, or Solid? JS or TS? JS and CSS inside HTML? Jinja templates? State management? Light and dark mode? Did I say I wanted a button!? I don’t want that button anymore. I’ll just sit here and stare at the wall for a bit. 

  2. I’ve purposefully left out more “professional” topics like logging, security, and infrastructure. I’m also skipping over type hints and refactoring. 

  3. Most used programming languages among developers worldwide as of 2024 

  4. If at all, LLMs can appear a little too confident.