Vibe Coding with ChatGPT
Tuesday, 10th June 2025
After re-joining the local gym from having some time-out following surgery towards the end of last year, I decided to build a small application to track my workouts.
Yes, there are plenty of apps that do that, but many of them are over-complicated, trying to be a personal trainer in an app, cramming ads, in-app purchases, profiling and needless data sharing. The top one on Play Store's list at the time of writing this article is "Fitbod: Workout & Gym Planner", which lists in the data safety section that it wants to share financial info with third parties! What the actual F... !?
What I wanted was just a simple list of the exercises, weights and reps that I could tick off as I completed each set. No accounts, no cloud storage, no need to upload anything to the internet or any kind of profiling or tracking.
Technology: JavaFX
So I had a pretty clear idea of "what" I wanted to build. I just needed to decide "how" to build it.
PHP - the language I have the most experience with, was out of the question. Even though there is some interesting stuff going on over in the PHP Laravel ecosystem with NativePHP, I just feel it's trying to smash a square peg into a round hole - and under the hood, it's making use of Kotlin. So you might as well just use Kotlin Multiplatform.
I have been dabbling with JavaFX on and off for a few years, and knew I could make the layouts fairly easily. What I didn't have was any experience linking the various screen elements and form fields with data objects, or how I might persist that data.
So it was time for some AI assistance.
Asking ChatGPT for help
I'm not going to list all the code snippets here - in fact, I'm not going to include any code at all. This is a work in progress, so the code changes everytime I sit down for an hour or two to develop the app. Instead, what I want to focus on here is the quality and benefits I got from the AI responses.
To kick things off, I started with a fairly long prompt:-
Lets make a JavaFX app.
I want to make a simple app for tracking gym workouts. The main page will be a list (initially, empty) with an "Add new workout" button.
Clicking the button will take you to a form to collect a workout name, weight, number of reps, number of sets and a rest time in seconds. For example: "Bicep curls", 35KG, 15 reps, 3 sets, 90 seconds.
Once saved, we should go back to the main list screen with the newly added item on the list.
Clicking the item on the list should take to a simple page with the workout details displayed and a button "Set Completed". Clicking the button should start a countdown for the specified rest period, then return to the detail view ready for the next set. Once the number of sets have been completed, return to the main list with the completed workout marked as done.
Finally, there should be a "Session complete" button on the main list, which will reset all the completed workouts so they are ready for the next gym visit.
The AI then spat out the basic code to make the app work. I spend about an hour transferring it to a clean project - I never just blindly copy and paste the code from AI. This initial code was fairly basic though, and mostly ended up in the app just as ChatGPT had generated it.
It was just plain-text and unstyled buttons, but it did exactly what I had asked.
Things started getting interesting as I asked it to develop some persistence options. At first it spat out a list of the possible ways to persist data in a Java app, along with some Pro's and Con's. Which is great from a learning point of view for a language you're not familiar with. It also recommended to use JSON serialisation, so that's what we went with.
On the first attempt, it just spat out an updated version of the main "Workout" class which had an empty constructor and public getters and setters for every field along with basic load()
and save()
methods using the Jackson library.
This was not completely unexpected. If you've read enough online tutorials, or skimmed over ORM's, etc. It's a common pattern you will see - just make all the properties public (or achieve the same with getters and setters). This undermines the main concept of Object-Oriented Programming though. So the AI needed a little more prodding in the right direction:-
I don't want public getters and setters, that breaks encapsulation.
The response was good:-
Excellent — you're absolutely right. Relying on public getters/setters everywhere exposes internal state unnecessarily, which undermines encapsulation. Fortunately, Jackson can work with private fields and no setters if we configure it correctly.
It then continued to tech me more about the options with the Jackson library, using annotations to identify serialised private properties instead of relying on a no-arg constructor and getters and setters.
And this is how it continued across multiple sessions. I would sometimes ask it to explain the options we didn't choose (like native Java Object serialization - which the AI confirmed is a minefield, and requires a lot of attention to detail and in-depth Java knowledge to get right), thus filling in gaps in my knowledge.
Often, it will spit out "an updated version of the class" which actually makes references to variables with slightly different names, which will trip you up if you're not paying attention.
Sometimes it would need an extra prompt:-
Great. However, in Exercise replace setCompletedSets() with completeSet() which takes no arguments and just increments the private counter - this preserves encapsulation of the class.
And the subsequent corrections to the code were usually the right thing:-
Excellent decision — encapsulating that logic inside Exercise avoids exposing internals and keeps the model clean.
Breaking encapsulation seems to be a repeating theme, so in future I've asked it to make strong encapsulation a priority when generating code.
There are also times when the AI has come up trumps. For example, as I mentioned earlier I've only dabbled in the basics of JavaFX and I had switched out the generated code for FXML and dedicated controllers, but this let to a bit of a stumbling block, which I just explained in simple terms to ChatGPT:-
I've switched my views to using FXML and FXMLLoader. However, I now find myself with an issue of how do I inject dependencies? Assuming my app had a maybe a dozen "views" in total, would it be an issue to load all views at startup so I can inject various dependencies into the controllers?
It's response was to tell me all about custom controller factories that you can add to the FXMLLoader, which enables setting dependencies on the controllers when they are created. It's the kind of "just below the surface" feature that you'll likely only come across after using the language for a while, or after a few hours of searching StackOverflow until you just happened to craft the corect search query.
Conclusion
AI is not taking over anyone's developer jobs - not yet anyway.
They are most useful as companions or assistants where you can play around with ideas and see what it gives you back. With the understanding that what it gives you is not going to be production ready code - you as the developer still need to review it and give it the sign off.
I've found it most useful for getting up-to-speed with relatively new technology. Instead of asking it to spit out entire programs, just ask for help with snippets of code which you can then take inspiration from to incorporate into your application.