Over the last few months, a new trend has emerged alongside the (over)-hype of AI's code generation capabilities. A development approach called "Vibe coding" has gained popularity among junior and mid-level developers. This essentially means letting AI write all the code while the "developer" focuses on writing prompts, testing, and iterating over the AI-generated code.
I decided to spend an entire day "Vibe coding" to see how far I could actually get with AI alone.
The Experiment Setup
I allocated one full day to build a complete solution with front-end, back-end, persistent storage, and Docker integration. For the headless CMS, I chose Prismic, and for deployment, I selected Hostinger as my service provider.

Project Criteria
I established clear criteria for the project:
- Build a complete front-end and back-end application
- Implement persistent storage
- Dockerize the application
- Integrate a headless CMS (Prismic)
- Make it deployable
Additionally, I wanted to approach this as a "blind" developer, giving AI a reasonable chance to solve problems before intervening. I would only manually solve problems after being stuck for 45 minutes or more.
Initial Setup
I started by creating a project with front-end and back-end folders. In the front-end, I ran $ npx create-nextapp
, and in the back-end, I used $ npx express-generator
to establish the foundation.
These commands are readily available on the Vercel and Express homepages, so I don't consider this as "development" work. However, I could have also tested if AI could generate these commands independently.
Next, I asked Claude to handle the dockerization and Redis persistent storage setup: I have a #backend and #frontend folder that I need dockerized and I want to implement persistent storage for my backend
This command yielded a largely-working solution from the start. While it encountered some environment variable errors initially, prompting it with the errors led to resolution within 1-2 iterations.
This generated a redis-service
, frontend-service
, backend-service
, and redis-storage
, providing a solid foundation for the project.
Within 15 minutes, we had established a robust application foundation.
Implementing Prismic
Prismic serves as an excellent headless CMS for simple yet customizable projects, offering flexibility that enables rapid development. It operates using customTypes
and slices
, which function as its versions of "pages" and "sections". You can easily define these by creating JSON configurations and relating page and component files.

Setup and Initial Challenges
I created a Prismic project based on a NextJS template, incorporating it into my front-end folder. This provided a basic page, default slices, and some demo content.
I aimed to create more dynamic and complex pages with nested data and dynamic entities, allowing users to add new entries and nested elements. Specifically, I created a page for calendar events, featuring listings with date, name, location, and requirement fields.
I prompted Claude: please implement a new customType called "Events" which allows me in Prismic to add event entries, it must have a Name, Location and Date fields, additionally a requirements textarea field
This revealed the first challenge: Prismic requires a specific structure for implementing dynamic and nested data, with certain limits and restrictions.
Claude generated an incorrect definition and couldn't solve the problem directly. It became stuck in a loop, alternately adding and removing "main", then cycling through UIDs and other random fields in the definition after I asked it to study the default page for a solution.
Even after showing it a working example from the Prismic documentation, Claude couldn't resolve the problem through prompts alone.
45 minutes into addressing this single problem, I manually intervened and wrote the definition by hand, simplifying the nested structure.
Custom Slice Implementation
At this stage, we had no custom slices as a foundation for AI to work from. However, I knew we needed some to enable dynamic content display in a reusable way.
I prompted Claude: I need a custom slice called: "Event Details" which needs an image on the left, title, description and CTA on the right, please make it responsive, implement using scss module files
Since I hadn't finalized the design, I let it work with the existing template project.
Issue number 2) The slice was created in an older format and placed in the wrong directory. While the code was usable, I expected to see my new slice when restarting Prismic's slicemachine.
Nothing appeared, so I prompted Claude: I'm using Prismic version x, we created this slice but I'm not seeing it in my slice machine
. It apologized for the misunderstanding and began adjusting the structure to ensure proper slice definition and schema usage.
It still didn't show - After several more prompts to investigate why the slice wasn't appearing, it apologized again and completely rewrote the slice. This time, it appeared in my slicemachine after implementing the final missing piece: exporting the slice component.
Issue number 3) - My page couldn't see the slice. When I asked Claude why: I'm seeing my new slice in the slicemachine, but my page cannot see and use the slice
, it proceeded to update my customTypes to use the slices while simultaneously making additional changes to my page.
If I were new to Prismic, I might have assumed these additional changes, like Adding a UUID
to the page, were necessary for slice display.
This highlights a critical problem with "Vibe coding": you need to understand the underlying solutions and code being written to identify these over-reaches and hallucinations from Claude and similar AIs.
I rejected the suggested change and prompted Claude: please only focus on implementing our custom slice and no other change
.
Content Migration Challenges
I wanted to populate the system with about 24 event items to create a new event list page and event detail page.
Prismic offers a convenient solution called content migrations, which typically takes 10-15 minutes to set up for simple data transformations and imports. (More complex data migrations naturally require more time.)
I asked Claude to handle two tasks:
please generate for me 24 event mock items based on the slice and customTypes of #sliceName and #customTypeName
please generate for me a Prismic content migration for version x.y.z so we can take our 24 event mock items in #mocks so get us 24 event entities for #customType
Generating the mock content went smoothly the first time, even incorporating a local image from the public folder.
Creating the migration proved to be a challenging process.
Prismic requires this basic structure:
import * as prismic from "@prismicio/client";
const repositoryName = "PROJECT_NAME"
const token = "API_KEY";
// Create the Prismic client
const writeClient = prismic.createWriteClient(repositoryName, {
writeToken: token,
});
// Create a migration
const migration = prismic.createMigration();
// Create the entity
migration.createDocument(
{
// The document
}, 'Document_Name'
);
await writeClient.migrate(migration, {
reporter: (event) => console.info(event),
});
Claude couldn't fulfill this request Prismic attempted to use the client SDK and API to make the migration work, but couldn't complete it without errors.
With no existing migration script in the project as a foundation, and working with slightly outdated documentation, it missed important criteria, preventing successful implementation.
After 45 minutes, I stepped in, wrote the foundation, and used Claude's generated mock data to create the migration. Within 10 minutes, I had my content pushed to Prismic and visible in my project.
Design System Implementation
With a working Prismic-driven web app in place, but lacking visual appeal and usability, it was time to implement a design system to build out the initial design properly.

Initial Design Attempts
I shared several Prismic designs with Claude/Cursor, prompting: I want my website to look and feel like these example images, please use MUI components and create a MUI theme that matches the style in the attached images
This led to rewriting all pages, creating initial components, and updating the layout with a theme and theme creation method.
Since the generated design still deviated from my presented examples, I made the prompts more specific: in the attached images we see the "card" has a white background, a rough border-radius of 30px, the colors are actually # # # and # for primary, secondary and complimentary colors, the buttons need x,y,z
About 70% of the prompt was correctly applied, with some areas overlooked. I prompted again for the missing elements: we're missing the styling for textareas, radio buttons etc
.
Issues I encountered:
- Claude applied Tailwind classes despite not using Tailwind in the project
- Claude used style/CSS variables that didn't exist
- Claude repeatedly used the same colors instead of creating variables
Time for the custom back-end
While Prismic excelled at managing our page content, I needed custom functionality, validation, and additional storage separate from Prismic.
API Implementation and Challenges
I entered the back-end folder and prompted Claude: create me a few express APIs that will take advantage of our Redis persistent storage, we're building a "team manager" for our football team, we need to be able to add, edit and remove players, here is the field structure I want to use {....}, please also consider authentication and validation of the APIs and implement API routes in nextJS #frontend folder as a secure pass-through for the calls to not expose our tokens
It began creating and writing these files, suggesting NPM packages to install and offering good auth options and implementations.
The first issue - It incorrectly mapped URLs across various systems and endpoints, mixing backend:8000 and localhost:8000 in different places.
I asked Claude to solve this with a utility, which it created, but I felt it wasn't the optimal solution. Instead of using .env variables, it hardcoded values. However, going in blind, I didn't correct this as it technically worked.
Second issue - Docker stopped mounting and building. During this process, Claude broke the express process, requiring several prompts to address the issues it created: references utilities it never actually created or mismatch syntax and imports
.
The final issue - While it implemented the scaffolding for all API layers, it required registration with external oAuth services instead of providing an in-house implementation.
Several additional prompts were needed to make the implementation workable. The end result appeared relatively secure and usable.
The trap I fell into - Having detailed knowledge of what was needed, what to catch, and what was acceptable, I could identify issues. Someone new to oAuth might not have this awareness, potentially exposing security vulnerabilities in their projects.
I don't trust Claude to provide a solution for something as sensitive as authentication at this level. Its initial reliance on external providers might be its way of protecting developers going into this blindly.
I spent additional time updating the front-end with new screens to consume these endpoints and build the team-manager. The design system updates applied well, though it occasionally introduced design/layout variations requiring correction.
After 6 hours: As more components fell into place, progress accelerated. However, I encountered recurring issues creating new complex customTypes and Slices in Prismic for other pages. New criteria and slightly increased complexity often led to loops with Claude.
Cleanup for delivery
With 8 hours allocated for this project, I had created several custom pages, a back-end, front-end, and implemented good standard practices.

Final Challenges
I dedicated the last 2 hours to cleanup, refining the visual aspects of existing features to create a presentable final product.
I prompted Claude with several commands:
please make all pages mobile friendly
please fix bugs x,y,z etc
please create for me a not-found and error.js app files in our style
please document the project both inline and in readme files
This is where things became increasingly frustrating. Mobile style adjustments broke desktop layouts. Bug fixes sometimes created visual issues or couldn't resolve problems without manual intervention (particularly with Prismic). The not-found and error.js files had styling issues. It occasionally created new phantom files instead of fixing or rewriting existing ones.
Approximately 40% of my time was spent in loops, rejecting changes, and re-iterating prompts.
The extensive context required for "vibe coding" seemed to overwhelm Claude, resulting in significant time loss.
Vibe coding - Did I actually vibe code this project?
The answer is simple: no. I frequently needed to intervene manually throughout the project. Despite my intention to approach this "blind/without experience," I sometimes provided prompt solutions for specific areas. The final result was barely prototype-worthy.
Without a fixed scope, implementing 1-2 additional features would likely have been impossible within the time constraints.
Vibe coding is not a professional practice
While it was an overall fun and occasionally frustrating experience, it proved to be a valuable experiment.
My key takeaway is that Vibe coding has no place in a professional working environment. Claude can serve as an excellent "foundation" tool and "sparring partner," but it's not a reliable source of truth and standards. If you're using AI to solve problems without in-depth knowledge, you can easily become stuck in loops and unable to progress.
What I learned
If you're genuinely passionate about solving a problem, AI can present situations that deepen your knowledge when used appropriately. Claude regularly introduced new problems requiring fixes. By addressing these manually, you gain valuable insights into bad versus good practices and potentially learn some best practices.
Recommendations
Balanced Approach to AI in Development
Based on this experiment, I recommend a balanced approach to using AI in development:
- Use AI for Foundation: Leverage AI for initial setup and boilerplate code
- Maintain Control: Keep critical infrastructure and sensitive components under manual control
- Verify Everything: Always review and verify AI-generated code
- Set Realistic Expectations: Understand AI's limitations and plan accordingly
Remember: AI is a tool, not a replacement for skilled developers. The best results come from combining AI's capabilities with human expertise and oversight.
Want to reach out?
Did you find the article interesting, want to discuss it or ways that Goldmund might be able to help you? Please feel free to reach out using one of the methods below.