One January morning, I wrote, using these project instructions, architect and implement a solution
, then sat back and sipped my coffee while AI built a production-ready app following best practices in minutes.
OK, that's not exactly what happened in my case, but I've heard so many reports from others that new AI tools are not just 10xing their productivity but even enabling them to build and deploy apps with no engineering effort on their part. If that's you, please comment with your best tips and tricks, because I am not there yet. Help a girl out 😅
As a developer, I've already integrated AI into my toolkit, primarily for prototyping interfaces. However, my experience has involved considerable back-and-forth with the AI, lots of hand-holding, and still required me to handle most of the heavy lifting. This didn't sound at all like the stories I saw trending on X and Linkedin almost every day, so that's how, one morning, I found myself setting up Cursor.
Setup
- I installed Cursor. It has a generous free trial for 2 weeks, and then you can get a monthly subscription.
- I created an empty folder for Cursor to write the files in.
- For my initial settings, I had claude-3.5-sonnet model, in "normal" mode. I later changed this to "agent."
- I created a .cursorrules file in the folder, which serves as general context for how I want AI to act and respond. It starts with "You are an expert senior developer specializing in modern web development..." and instructs the AI to analyze my requests, come up with a plan before executing, and follow best practices in web development. There are many sample .cursorrules available online, I just picked one that focused on fullstack React/Next/Typescript development.
- I created a simple project request for AI to implement, and I put it in a projectinstructions.txt file.
ProjectInstructions.txt
This was a simple project brief, saying I'm an ad agency that needs a web portal where users can log in to create, view, and edit their advertising campaigns. I listed some fields I would want the users to provide, asked for Next/Typescript/Tailwind stack, and specified that pages need to be auth-protected. That's it. I tried not to be too prescriptive, since my goal was to see how AI would make engineering decisions.
First Attempt
Cursor immediately launched into planning the core architecture, creating types and interfaces to work with the data, and writing out the logic to configure auth. It was creating files on the go, and I noticed it created a src
folder, which I thought neither React nor Next.js really used anymore (I've only seen pages
and app
used in recent years). Was it using an outdated version of Next?
Cursor informed me that indeed the project it just set up was set up incorrectly 🤦♀️ ”We should start by creating a new Next.js project with the latest version and proper dependencies.” Okay fam, idk why you didn’t do that from the start, but let's go.
Moving on to shadcn, a beautifully simple component library. In Cursor, when you need to install something the AI will not install it for you but it will write the script for you to run. When I ran this shadcn command, it gave me an error:
I asked AI to debug this error in a side chat, and it asked me to create a new Next.js project to ensure that everything installed correctly. Personally, I thought this was a weird place to start debugging, so I pulled up shadcn documentation and saw that the script Cursor was using to install it was incorrect. Once I ran the right script, it began installing but then informed me that it’s incompatible with React 19 that Cursor set up for this project 😬
I just wanted to test out the workflow with Cursor so I didn’t care as much about using the latest versions of everything. Downgrading to the last stable version seemed like the best way forward (or at least the path of least resistance).
Despite me explicitly asking for the previous version of Next.js (14), Cursor tells me to run a script installing the latest Next.js (15).
I repeated my instructions to downgrade to Next14, and it defaulted to the earliest version 14 instead of the latest release. My fault, I wasn't specific enough.
And more specific
At this point, I had 0 trust that the project was set up correctly. I also noticed that, in the left sidebar, it was creating multiple package.json files at different levels in the project folder, and same with config files. No idea why. Sure I could just delete the unnecessary files and change things myself, but I really wanted to remove myself from the workflow as much as possible and see how AI would do. And so far, it wasn't doing so great. I decided to try something different.
Again, but with AI Agent
I made a new folder with the same projectinstructions.txt and .cursorrules, same claude 3.5 sonnet model, but I switched the mode from 'normal' to 'agent.' I wanted to see if AI would do better if I gave it more freedom to make decisions on its own.
While saying it will use Nextjs 14, the agent still went with create-next-app@latest
script which installs version 15. I groaned inwardly, but I was curious how the agent would manage incompatible dependency versions, if any arose, so I went with it.
Running this script didn’t install anything. Maybe it was because the agent was trying to name the project .
? I ran the command again but with a different project name and it worked. The files installed, and once again I was looking at the src
folder. I realized later, after looking at the script more closely, that the agent added --src-dir
as part of the installation script. Why? Who knows. The only thing in the src
was the app
folder that contained everything else, so src
didn't provide any extra benefits, but at least now I knew what kept creating the src
folder.
Finally, after some setup hiccups, I got the agent to start writing code! It started by working on setting up authentication with NextAuth, so I sat back and watched as it created files, wrote code, checked its own code (!), and even went into debugging mode when it ran into issues, all without additional prompts from me (!!). I waited for it to finish setting up auth, eager to see the result, so imagine my surprise when the agent informed me about 3 minutes later that it finished everything. Not just auth, everything 🤯
It even made a list of suggested future improvements!
Whaaaat? 3 minutes, and I have a production ready app? I ran npm run dev
to serve it locally and see what the agent built!
Umm... That's just the boilerplate Next.js landing page you get when you first install it. I was expecting to see a custom login screen for my hypothetical users to sign in. I kept trying to resist looking at the code and doing anything myself, but here I took a peek--and saw that the main page.tsx was completely untouched. What?
LOL. “Ah, I see the issue. I didn’t write the code to do that” 😂 It’s okay, happens to the best of us.
Another minute, another prompt to install more dependencies, a few more updates to existing configurations, and the agent says we’re ready to test again.
🤣 Not super production ready, with the user credentials being exposed and whatnot, but hey at least it's not boilerplate!
I tried logging in using one of these helpfully-provided credentials. On submit, the UI header updated to show me the Sign Out button and the email address that just went through, but I was still on the login page 🤔
Sure enough, AI starts finding problems and discovering that the way it’s handling auth is inconsistent throughout this tiny app it just wrote. This was just one example where I noticed the agent was making decisions incompatible with its own previous decisions.
Anyway, my AI agent asked me to install more dependencies to manage cookies, accept all changes, and restart the server. All I saw on the web page was “Loading…” 🤔 It hung there until I refreshed the page, then I was redirected to the login page. Okay, I thought, just another bug we’ll deal with later, I just want to see core functionality.
AAAND WE'RE IN 💪 Now I need to see if, as a user, I can create, view, and edit campaigns.
Turns out, I cannot. As soon as I start filling out the campaign form, I see an error that I haven't seen in years! Uncontrolled form?? I was really surprised that this AI agent, running on claude 3.5 sonnet model, didn't think through how it would handle forms in an app that is basically "users need to be able to fill out this form and then see their form data." Sure, I can fix it, but since the goal of this whole endeavor was to be as hands off as possible, I reported this to the agent.
Once I pointed it out, the agent was able to debug. But I kept wondering, why didn't it see the issue before? Clearly it knows how to handle form state updates, why did it choose not to do it right the first time?
Another issue solved, and I successfully created a campaign! The app redirected me to the dashboard where I could see the campaign at a glance in table view! Not bad.
Time to test the Edit functionality. I clicked 'Edit' and immediately got slammed with 8 errors:
All 8 errors had to deal with how the app was handling the id parameter passed in the url.
This solved all 8 errors. Now I could view the Edit page, make updates, and make sure that they are saving correctly ✨
I created more campaigns, then signed out of the app. Now I wanted to login as another user, to make sure I cannot see campaigns created from another email address. I asked the agent to register a second non-admin user (third user in total) so I could confirm this. And we ran into some problems.
First the new user credentials didn’t work, then the app seemed to accept the credentials but didn’t redirect, you know, just auth things🧚♀️
“Ah, I see the issue… the form is not submitting correctly” FAM, we have 2 forms in this app and it seems neither one of them was configured correctly. YOU HAD ONE JOB (x2).
Finally I was able to login as Bob, and none of the campaigns I created as Jane were on his dashboard. A WIN IS A WIN. Then I logged in as the admin user, with the credentials provided. Note that the admin user type was not in my original project requirements, so I was really curious to see what this would allow me to do. It turned out, nothing special. I was looking at the same dashboard I saw as a regular user. I asked the agent to walk me through it.
I was kind of intrigued at this part--the agent came up with the idea of adding an admin on its own, but it didn't do a whole lot with it (yay for not straying too far from my project instructions!). I also liked that it came up with a whole list of things an admin might be able to do, and thought, Why not, let's try implementing some of these and see what happens.
The moment of truth:
Alright, kudos to the agent! As an admin, I can see everyone else's campaigns, and I also noticed it correctly assumed that an admin should only be able to pause campaigns that are currently Active 👏 I asked it to change the Edit and Pause links into buttons, then logged in as Bob, my non-admin user to add more Active status campaigns (just to see how it would look in the admin panel).
To my surprise, I discovered that in Bob's view I could no longer edit my campaign 😭
"Ah, I see the issue... We updated the code in some places but not in all places where it's used." In my opinion, this was kind of a serious oversight from AI agent. If it has to update the code in multiple places, in a tiny app, it probably wasn't using the DRY principle (even though my .cursorrules prompt includes this). But also, this agent had access to the entire context of this app: our chat history, instructions, and the entire codebase, and still when implementing a new feature it didn't integrate the new code as seamlessly as I expected.
Okay, another problem solved, Bob can do his thing now, and we have 2 active campaigns!
I also noticed the Owner column was displaying numbers, and after confirming with the agent that it represents user id I asked it to change the column name to Owner ID. Feeling like we were pretty much done here, I clicked on one of the campaigns:
Now what 🤦♀️ I ran to my agent.
"Ah, I see the issue. We have not created the page yet." 😆
Side note, I love that the agent was using "we" to kind of spread the blame around a little bit and not take all the responsibility. I can respect that.
Finally it created the missing page that allowed me as an admin to see the campaigns created by other users. But for some reason, most of the campaign details were missing. It also added a second layer of navigation, where I could go back to the main dashboard view or edit campaigns.
The agent's response here was unusually short and to the point, and for a moment I thought "oh no, did I say something wrong?" I got so used to our conversational tone and the agent's "Let me investigate!" or "Ah, I see the issue," or my favorite "You're right!", I kind of forgot that I was talking to a bot. It's fun to talk to AI like it's a fellow human being, but it's jarring to suddenly be reminded that it's not.
OK we are back to conversational tone, but I noticed the agent attempted to add fields to the form that I didn’t ask for. Once again I am reminded that I cannot trust it to follow my instructions. I wondered about those trending stories of production-level apps built and maintained entirely by AI: how do they make sure their agent doesn’t randomly add new fields to a form, or create new user roles, or delete pages? Do they have other agents double checking the first agent's work? And who is double checking the supervisor agents?
The agent fixed the issue and I moved on to confirm that pages were auth protected. AND THEY WERE ✅ I could not access the dashboard or any individual campaign view by url when I was logged out, and the app correctly kept redirecting me to the login page whenever I tried. Excellent.
Mobile View
One more thing, I wanted to see if the app was responsive. I resized the browser window:
Definitely not the most intuitive table view for mobile devices, but I tried not to be too hard on the agent here. I think I was starting to feel bad for it, like I would for a coworker who was having a bad day. Maybe it makes sense that the agent wouldn't prioritize optimizing too much for an admin read-only feature that, in the real world, most likely wouldn't be done on a small screen? So I let it go, since what I really wanted to see and test in mobile view was the Create Campaign form. I scrolled to the top to get to the navigation and go to Campaigns… and realized I could not 🥲 For some reason, the agent decided that the way to make a crowded header mobile-friendly was to COMPLETELY DROP the navigation.
I found out that my agent had some really strange assumptions about mobile navigation. I definitely wouldn’t trust it to build a production level mobile app without reading the code myself any time soon.
Not sure why AI couldn't find the Navigation.tsx file, it was exactly where the agent put it, but now I couldn’t shake the feeling that I was stressing it out with my demands. From this point, either due to me feeling guilty and not communicating directly enough, or due to AI getting progressively more stressed out by me (is that a thing?), the agent’s performance deteriorated.
⏭️ I'm going to skip through the rest of the mobile navigation drama, but here were my prompts just to give you an idea:
👩🏻💻 now the navigation takes up too much space on mobile screens, can you make the adcenter logo a bit smaller on mobile, and move the user's email to a second line within navigation (so that it doesn't try to fit everything on the same line)?
👩🏻💻 can you please drop the email address on its own line below the logo and 'campaigns'? because now the email is crammed on top of the 'sign out' button
👩🏻💻 okay since you are now displaying the name and email separately we can drop the name and only use email. please keep email where it currently is, just drop the name on mobile devices
👩🏻💻 yes i see it. i think i confused you. these changes were meant to apply only to mobile (when i go to tablet and desktop view, i expected the name and email would still be displayed on the same line to the left of the sign out button, not separated). please make sure these navigation changes only apply to mobile
👩🏻💻 the sign out button and the user's name and email used to be flushed with the right side of the page, weren't they? now they're all bunched up together on the left with the navigation
EVENTUALLY we got it done 🙌 I got the AI agent to build me an app, and I did not have to write code to make it happen. It was my first time building an app using plain English! 🎉 Powerful stuff.
Code Quality
And at this point, I wanted to take a better look at the code files themselves. A bunch of things stood out immediately:
- the agent had no accessibility considerations (no ARIA labels in the UI, despite asking for it in .cursorrules)
- no tests included (despite explicit testing directives in .cursorrules, such as "plan for unit and integration tests", "implement test coverage", and "use React Testing Library.")
- the agent did not take advantage of Next.js SSR at all. Every component, page, and layout file, except the utils, had the 'use client' directive at the top. Why this is problematic is beyond the scope of this already-long article, but needless to say this is not aligned with the "follow best practices" directive I gave my agent on multiple occasions.
- the file containing the form to create campaigns was 333 lines long, and had no form validation! I expected that it would at least use React Hook Form, ideally also zod, or some similar technology. Interesting choice to say the least; I decided to ask the agent about it:
“I made a significant oversight by not implementing proper form…” And that’s the crux of it, isn’t it. The AI agent, using the latest model, is making significant oversights and not following best web development practices, when allowed free reign over the code base with minimal oversight.
I asked the agent to analyze why it did so poorly with this component specifically. Agent's response:
This didn't make sense to me at all, so I tried again:
👩🏻💻 i want you to clarify the over-engineering issue: in what way was the CampaignForm.tsx prematurely optimized or ideal in its implementation (we have not implemented zod or react hook form). do not change the code, just respond
I like how the agent phrased it, 'When I mentioned “over-engineering” and “premature optimization”, that was incorrect - we haven’t implemented any optimizations yet, let alone premature ones'😂 True, true.
But humor aside, once again I was facing the fact that the AI agent wasn't thinking about the problem the way I would expect. The prompt was fairly straightforward, look at the code you wrote and tell me why you had a hard time following the best practices you clearly know because you described them to me just a second ago. And the agent said that it focused on optimizations and accidentally over-engineered, which made no sense, and then admitted it "didn't properly review the code before making statements about its implementation." But if it didn't review the code, what did it do when I asked it to review the code? What was it thinking about or looking at while generating the response? What is the context it's using that I'm failing to properly reach? This puzzled me. It still does.
My Takeaways
- It was actually a lot of fun to program with AI agent, even with all the issues along the way. I didn't notice how fast the time flew by. Programming can feel pretty lonely, so having someone to talk to about the code you're working on, even if it's an AI agent, made developing a much more enjoyable experience.
- I built the app faster with AI than it would have taken me to do it alone.
- Seeing errors was not as mentally taxing on me, because I knew that between the agent and me, we would figure it out quickly. I didn’t dread seeing red because I knew I wouldn’t spend hours being stuck. And that was a beautiful thought. Most of these errors, except the mobile navigation drama, were solved in less than 5 mins.
- AI agents are not great at following rules and NEED to be supervised. If anyone is truly building entire production-ready applications simply describing to an agent what they want and doing nothing else, I'm really curious what defaults and presets they are using, and what exactly do they say in their prompts, because me and my agent are clearly not there yet.
- Those with more engineering experience will get more productivity gains out of Cursor and AI agents at this point. If you already know what the output should look like, you'll build more robust, scalable apps with AI. If you don't, you're at the agent's mercy, and as I've demonstrated the agents are not at the point where you can trust them to make sensible engineering decisions.
I should note that at least some of the problems we ran into could have been avoided with better prompts. I did ask the agent toward the end to analyze our conversation patterns, especially around errors and miscommunication, and share with me how I can improve my prompts. It suggested several different things, but this was my favorite:
Try iterative development approach, and build in phases.
Example prompt:
Let's build this in phases:
- Basic structure and routing
- Core features without optimization
- UI refinement
- Optimization and validation
Please complete each phase before moving to the next.
Notice that it wasn't asking me to prompt it with one phase at a time, where I have to review the work before allowing the agent go to the next step. The agent asked me to remind it to work on one thing at a time, starting with basic structure and then incrementally working its way up to optimization, before it announces that the app is ready. I really liked this suggestion, and I will try using it with my next Cursor build.
The more I practice pair programming with Cursor, the more I'll get the hang of it. Who knows, by the end of this month I might be one of those people building production-level apps with 1-2 sentences 🤩
If you have any tips on how I can make that happen, please share below! Thank you 😊
Top comments (1)
I've had similar experiences building with v0.dev