A few weeks ago, I caught myself spending 40 minutes writing a form validation schema I had written a dozen times before. I wasn’t learning anything. I was just typing.
That was the moment I decided to run an experiment: for 30 days, I would use AI coding assistants on every project I touched, and I would log what saved me time and what quietly wasted it.
I expected a magic productivity boost. What I got was more nuanced. Some habits made me noticeably faster. Others made me slower while feeling productive, which is the worst combination.
This is the honest breakdown, including the mistakes.
I mostly build web apps with React and Node.js, with the occasional Python script for automation. During the experiment, I worked on three things:
I used ChatGPT, Claude, and GitHub Copilot alongside VS Code. To keep myself honest, I kept a plain notes file with three columns: the task, my estimate without help, and the actual time taken. It isn’t scientific, but it was enough to spot patterns.

The biggest win was boilerplate: config files, validation, CRUD endpoints, regex, date formatting. I know exactly what I want in these tasks, but typing them out is tedious.
Here is a real example. I needed to validate a signup request. Writing it by hand meant checking the docs for the right syntax, handling each field and then writing error messages. About 15 minutes.
My prompt:
“Express 4, Node 20. Write a validation middleware for a signup route using Joi. Fields: name (2-50 chars), email, password (min 8, at least one number). Return 400 with a clear message for each failure.”
I got a working first draft in under a minute, reviewed it, tweaked two messages and moved on. Total: about 3 minutes.
const Joi = require('joi');
const signupSchema = Joi.object({
name: Joi.string().min(2).max(50).required(),
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/\d/).required()
});
function validateSignup(req, res, next) {
const { error } = signupSchema.validate(req.body, { abortEarly: false });
if (error) {
return res.status(400).json({
errors: error.details.map(d => d.message)
});
}
next();
}
The rule I settled on: if I can explain the task in two sentences and I’d be bored writing it, hand it off.

My early prompts were lazy: “fix this error.” The answers were generic and often wrong.
Then I started including four things every time:
Compare these two prompts:
“My API is not working.”
“I’m using Express 4 with Node 20. This POST route returns a 500 when the body is empty. Here’s the handler and the error log. I expect a 400 with a validation message.”
The second one gets a useful answer on the first try almost every time. Good prompting turned out to be the same skill as writing a good bug report, and that skill makes you a better teammate even without any tools.
This surprised me the most. When I joined the older codebase, I pasted unfamiliar functions and asked, “Explain what this does, what its inputs are and what could break it.”
I still read the code myself afterwards, but having a first explanation to check against cut my onboarding time from what I estimated would be a week to about three days. It also helped me find a function that silently swallowed errors, which nobody on the team knew about.
I’m not great at imagining how my own code will fail. Asking for “10 edge cases for this function that might break it” gave me inputs I wouldn’t have tried: empty arrays, null values, unicode characters, extremely large numbers, duplicate entries.
Three of those edge cases exposed real bugs in a date-range function I thought was finished.
Explaining a bug to someone often solves it. These tools work like a duck that talks back. Half the time, I found the answer while typing out the question. The other half, the reply pointed me in the right direction.
In week two, I accepted a generated function without a careful review. It looked clean and passed my quick test. It also had an off-by-one error that affected pagination, and it took me almost an hour to track down two days later.
Generated code sounds confident even when it’s wrong. Now I treat it like a pull request from a junior developer: useful, but it always needs review.
When I asked for an entire module in one prompt, the result was messy, inconsistent and hard to modify. Naming didn’t match my project, error handling was different in every file and some parts duplicated logic that already existed.
Smaller pieces worked far better: one function, one component, one query at a time.
This was the hidden cost. When I jumped straight to prompting, I skipped the design thinking. I ended up with code that worked but didn’t fit the rest of the system, and I paid for it later during refactoring.
Now I spend five minutes writing the approach in plain text before opening any tool: what the inputs are, what the output is, where the code will live. It saves far more time than it costs.
When I was learning a new concept (database indexing, in my case), copying answers meant I didn’t actually learn anything. A week later, I couldn’t reproduce it without help.
For learning, I now ask for hints and explanations, then try to write the solution myself first.
A few times, I got suggestions that used library methods which don’t exist or were removed in newer versions. The code looked perfectly reasonable. It simply failed at runtime.
Anything version-sensitive now gets checked against the official documentation.

Here is the rough summary from my log:
|
Area |
Time saved |
Time lost |
|---|---|---|
|
Boilerplate and config |
~7 hours |
- |
|
Debugging |
~5 hours |
~2 hours |
|
Writing tests |
~4 hours |
- |
|
Understanding old code |
~2 hours |
- |
|
Trusting bad output |
- |
~2 hours |
|
Total |
~18 hours |
~4 hours |
A net gain of roughly 14 hours over a month. That is real, but it’s much smaller than the hype suggests, and it only came from using the tools deliberately, not constantly. The weeks where I used them for everything were not my most productive weeks.
After 30 days, this is the routine that stuck:

If you’re just starting out, be careful. These tools can make you feel like you understand something when you don’t. Use them to explain, to give hints and to review your code, not to skip the struggle that builds skill.
If you’re experienced, the value is in removing friction: the repetitive work, the first draft, the edge-case checklist. Your judgment is still the part that matters, and no tool replaces it.
These tools don’t replace understanding. They reward developers who already know what they want and can judge the result.
The people getting the most out of them aren’t the ones who use them the most. They’re the ones who know exactly when to use them, and when to close the tab and think.
If you try your own 30-day experiment, I’d love to hear what you find. What worked for you, and what quietly wasted your time?