Denne indlæg findes også på dansk
Inspired by summer reading in 2024, “How to Create Tech Products Customers Love” by Marty Cagan, I found confirmation of my own experience using prototypes to develop, demonstrate, and validate ideas. Marty Cagan uses the concept of a High-Fidelity prototype to describe a prototype that closely resembles the final product and can help secure funding and buy-in for a product before development begins.
Using High-Fidelity prototypes for product development requires the development team to build skills and tools to create them relatively quickly – ideally in less than 1/10 of the time it would take to build a comparable MVP of a product. The faster a High-Fidelity prototype can be tested by potential users, the more ideas can be explored in the same time it would take to build one MVP. The more realistic a prototype you can build, the better you can estimate and execute the work to turn it into a proper application.
In this article, I describe some of my experiences and methods that others might find useful. Note that I’m not a software developer. I’m a product developer and hobby coder. The target audience for this article is therefore creative and somewhat technical types who might need to build a quick simple app or prototype.
Table of Contents
A good starting point for making a realistic prototype is to use some of the same tools that will be used in the final product.
In my current product team, we develop web applications with front-end in Next.js and Shadcn/UI. I have experience with both back-end and front-end code, but not with these specific technologies. My ability to create a prototype resembling our final product was therefore limited.
Frustrated by my inability to visualize my ideas and lack of time, I turned to AI for help.
How can I help you today?
I know absolutely nothing about next.js front-end development and node.js deployment.
I have a newly installed Linux server I want to use to develop an application.
Explain from the very beginning how I can get started.
And so I began. After a day of trial and error and an appropriate amount of copy-pasting code that I could recognize as JavaScript and CSS, I had my first app up and running. This has since evolved into a toolbox, while I’ve also learned a lot about Node.js, React, conditional rendering, routes, and Shadcn/UI styles and components.
Your new AI coding assistant
The available AI assistants are excellent at writing code. Especially for next.js since the training material available on the internet is massive. I’ve tried several, and most produce decent code. They all have their pros and cons though.
Generally, for all server-based AI assistants, you should prompt with caution. There’s no guarantee of where your data ends up or whether it’s used for training. For prompts containing confidential data or code, you must stick to assistants that are properly approved for the purpose. For prototypes and small applications that don’t contain confidential data or actual intellectual property, you can advantageously keep naming somewhat anonymous just to be safe. For confidential data, it’s also possible to use local LLM models. My experience is that they work best with well-defined tasks.
Copilot
Microsoft Copilot is good at writing code and suggesting solutions to problems. However, my workflow, where I partly work with code I don’t fully understand, presents challenges for Copilot. It can’t handle very long prompts. I typically paste many hundreds of lines and ask the AI to make some changes and give me a complete updated application – not just describe what needs to be changed. This is where Copilot falls short.
Mistral
French Mistral has been my regular “colleague” for a period. I like their product, their ethics, and I want to support European technology. It has worked quite well and produced lots of good code for me. At times it has had fluctuating response times, and some prompts may time out. It might also not be quite as sharp as, for example, Claude at hitting the mark with solutions and making good assumptions about points I haven’t described so clearly.
Claude
Claude is currently my preferred AI assistant. In most cases, it understands what I’m asking for and creates solutions that work. As an extra bonus, Claude has an online code execution module, so the code it creates can be tested in the browser. This is super convenient. I’ve used the free version for a while when I haven’t needed it much. It works for basic needs. You don’t get many prompts per day, and you can’t continue working with the code in the same prompt. That means you have to start a new prompt and reformulate the entire task. If you seriously want to get something out of Claude, I recommend getting out your credit card. I do this when I have active projects.
OpenAI
I started the process with OpenAI, first free and then paid. However, I prefer Claude and am also happy to support something other than the obvious giant!
Deepseek
Before Deepseek became talk of the town, I also used it quite intensively for about a week. It produces excellent code. Of course, you should be (extra) careful about what you share on a Chinese application. Most of what I create is quite primitive and contains no confidential information. After Deepseek received a lot of attention, performance has dropped significantly. It’s as if the first prompt is processed quickly, and then response times gradually slow down.
LM Studio
I’ve also explored various language models that can be downloaded and run on your own machine. I use the program LM Studio to work with them. It comes highly recommended. It’s quite impressive what you can do locally, but I haven’t yet succeeded in running my somewhat intensive prompt concept locally with success.
Technical setup
To get started with next.js prototyping, you need to have a basic technical setup in place. Don’t worry – it’s easier than you might think, even for a hobby coder or product owner without in-depth development experience.
Node.js – The foundation
Node.js is the fundamental runtime environment that the rest of our setup builds on. It’s basically a program that lets you run JavaScript on your server or computer – not just in a browser.
To get started, you need to install Node.js on your machine or server. There are plenty of guides online, and it’s as simple as downloading an installer from their website and following the instructions.
I was a bit confused at first about where things were installed. Node.js itself is installed globally on your machine. When you start a project, a basic configuration is created in the folder where you’re working. Subsequent modules and packages you install become part of that specific project. This means you can have different projects with different versions of the same packages.
Node can run on your own computer or on a server. If you want to show the prototype to others, a small Linux server with public access is a perfect solution.
Next.js – The React framework that makes life easier
Next.js is a framework built on top of React that handles many complex aspects of modern web applications. For us, it’s the perfect platform for rapid prototyping because it comes with:
- A ready-made project structure
- Automatic routing based on folder structure
- Simple separation between client-side and server-side code
To start a Next.js project, just run:
npx create-next-app@latest my-prototype
cd my-prototype
Follow the installation guide and choose the default settings suggested. When the installation is complete, you’ll have a functional website with hot-reloading (automatic updating when you change the code).
React – The building blocks
React is the library that makes it possible to build user interfaces with components – reusable building blocks for your UI.
As a beginner, you don’t need to understand all React concepts upfront. You can start by copying and adapting the code that the AI generates, gradually learning the concepts along the way.
Shadcn/UI – The beautiful layer
Shadcn/UI isn’t a traditional component library, but rather a collection of reusable components built with Radix UI and styled with Tailwind CSS. It provides:
- Professional-looking components like buttons, dialogs, forms
- Accessibility and user-friendliness out of the box
- Easy customization through Tailwind CSS classes
To install Shadcn/UI in your Next.js project:
npx shadcn@latest init
Then you can install specific components as needed:
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add dropdown-menu
This is one of the big advantages of Shadcn/UI – you only install the components you actually use.
npm run dev – Your new best friend
Once you have your project set up, start the development server with:
npm run dev
This starts your app in development mode at http://localhost:3000 (or another port if 3000 is taken). The magic of this command is that it enables “hot reloading” – your app updates automatically every time you change a file, without you needing to reload the browser.
This almost instant feedback loop is crucial for rapid prototyping. You can change something, see the result immediately, and iterate quickly. If an error occurs, you get it right away – fail fast! This has enabled me to learn much faster than if I had to go through a slow build process each time.
“use client” – The small directive with big meaning
If you copy code from the AI and encounter errors like “You’re importing a component that needs useState”, you need to add "use client";
at the top of your file.
This directive is specific to Next.js 13+ and tells the system that your component should run on the client side (in the browser), where hooks like useState
work. It’s necessary because Next.js by default runs components on the server, where these hooks aren’t available.
This technical setup gives you a robust foundation for turning AI-generated code into functional prototypes. Although it may seem overwhelming at first, you’ll quickly discover that most of the complexity is hidden from you, and you can focus on what matters: visualizing and testing your ideas through prototypes.
The art of prompting your AI assistant
AI assistants like Claude are exceptionally good at building front-end code. But getting exactly what you want depends on your ability to communicate effectively with them. Let’s dive into how you can create a productive collaboration with your digital developer.
Establish a common language
The key to successful AI-assisted development lies in establishing a common language with your assistant. You don’t need to be an expert in technical terms, but a basic understanding of the components and concepts you want to implement is invaluable.
For example:
– Understand the difference between a “modal”, a “dialog”, and a “popover”
– Know the basic layout structures like “card”, “container”, and “grid”
– Learn to refer to interaction patterns like “drag-and-drop” or “infinite scroll”
Introduce your own terms for specific elements in your application. As I demonstrated in the examples, I defined “… the menu” as a concept, and Claude understood and applied it consistently thereafter.
Write in your native language
An often overlooked advantage is that modern AI assistants understand most languages excellently. I prefer to write my prompts in Danish, as it allows me to express my thoughts more precisely and nuanced. This reduces misunderstandings and yields better results.
Think of AI as a junior developer with encyclopedic knowledge
After months of close collaboration with Claude and Mistral’s LeChat, I’ve developed a mental model that helps me: Think of the AI assistant as a super-skilled, newly graduated software developer. It has:
- Extensive theoretical knowledge of almost all programming languages and frameworks
- The ability to implement complex designs quickly
- Lacking contextual understanding of your specific business or domain
- A tendency to assume what you want without always asking for clarification
Just like with a human colleague, communication improves over time as you build a shared understanding.
Practical tips for effective prompts
- Be specific, but not overspecific
Describe what you want to achieve rather than exactly how it should be implemented. Give the AI room to apply best practices. Iterate gradually
Start with a basic version and build on top. It’s easier to adjust and refine than to create the perfect solution on the first try.Provide examples
If you have references or existing code, share them to give the AI a clear idea of what you expect.Ask for alternatives
If you’re unsure, ask for 2-3 different ways to solve a problem. This expands your understanding and gives you options.Redirect when necessary
If the AI goes too far off on a tangent or overcomplicates things, don’t hesitate to ask for a simpler approach or redirect focus.Error handling as a learning process
When you encounter errors, share them with the AI and ask for an explanation. This helps you build a deeper understanding of the technology and improves your future prompts.Build on previously successful code
Ask the AI to adapt or extend code that already works, rather than starting from scratch with each iteration.Learn along the way
You won’t get all the way to a larger High-Fidelity prototype without being able to make some adjustments yourself and ask for very specific changes and method choices from the AI. Use the opportunity to learn some javascript, next.js, chadcn/ui and front-end terminology along the way.
The beauty of working with AI is that you can ask questions, request changes, and change direction without human frustration. Take advantage of this freedom to experiment and develop both your application and your prompt skills simultaneously.
From theory to practice: Practical examples
Now that we’ve covered the theoretical foundation, it’s time to see how it works in practice. In the following examples, I’ll show how you can progressively build more advanced applications using AI-assisted development. Each example builds on the previous one and demonstrates how you can communicate effectively with your AI assistant to achieve the desired results.
These examples are designed to be simple enough to understand while still showing important principles in modern web application development. You’ll see how I formulate my prompts, how I handle errors and iterations, and how I gradually build more complexity.
Example 1: Address book
Let’s start by making a very simple address book application.
How can I help you today?
Create a page in React using components from Shadcn/UI.
It should be called Address Book.
It should display an address list with these columns:
Name, email, and phone number.
In the top left corner there should be a button called Add.
For each line in the address book there should be a … icon with a small menu. I’ll call this … the menu.
When clicking Add or Edit in … the menu, an add/edit modal should appear where you can enter name, email, and phone number.
In … the menu there should also be a Delete function.
The result is this app – without any further adjustments. Appropriate icons and sample data were invented by Claude itself.
Note that there are some concepts in play. A list and lines in a list, the AI understands without further explanation. I can also casually mention an add/edit modal and Claude fixes it without problems.
“… the menu” is my own name for the menu that appears in each line. I therefore start by defining it before writing what should be in it.
To run it from a standard next installation, create a folder in the app folder called example1 and place the file there as page.tsx.
Open your browser to http://ip:3000/example1
You’ll most likely see one or more errors in the browser. Copy them and ask the AI what it might be. Initially, you probably need to add
"use client";
Then the AI has probably used some modules that aren’t installed in your next project. Just look at the error message in the browser to see what’s missing, then go to the server and install them.
as the top line in the code
The version Claude made for me required these install lines on my server:
npx shadcn@latest add dropdown-menu
npx shadcn@latest add label
npx shadcn@latest add dialog
npx shadcn@latest add alert-dialog
Just copy the error message and ask:
“Explain what I need to write to install what’s missing” and paste your error…
Example 2: Persistent data
In example 1, you can delete and create addresses, but as soon as you reload the page, you’re back to Anders, Bente, and Carsten. To create the experience of data being saved in the application, you can use a function that’s widely supported in most browsers: localStorage. Think of it as a small key/value database in your browser. It will feel like you’re saving to a server, but it’s actually only in your own browser.
Follow-up prompt to example 1:
How can I help you today?
“Adjust my app so it saves the addresses in localStorage with a key name called myAppAddresser.
Give me a complete updated app.”
Copy the new code the AI has created and overwrite the old one.
Again there’s a small error – Claude didn’t quite hit the mark with localStorage – apparently something about permissions. I copy the error and write to Claude “I got this error …”
Example 3: Event RSVP – Persistent data across applications
Let’s say we want to create a new application where you can note who has RSVP’d yes or no to an event. Based on people in the address book.
If you continue in the same thread, you can create a new page and use data from the address book without further ado. The AI knows the data structure since it created it itself. At some point the thread may have run its course, or you need to continue with another AI assistant. Then you need to have control of the concepts. We therefore start somewhat from scratch in this example. In the same way as example 1.
How can I help you today?
“Create a page in React using components from Shadcn/UI.
Use the skeleton from this app (paste example2)
It should be called R.S.V.P.
It should show a list of RSVPs to an event with these columns:
Name and response.
In the top left corner there should be a button called “Add response”.
For each line in the list there should be a … icon with a small menu. I’ll call this … the menu.
When clicking “Add response” or Edit in … the menu, an add/edit modal should appear where you can select name in a searchable dropdown and a radiobutton with Yes or No.
In … the menu there should also be a Delete function.The content in the Name dropdown in the add/edit modal should be fetched from localStorage key myAppAddresser.
Here’s an example of the format:
[{“id”:1,”name”:”Anders Andersen”,”email”:”anders@example.com”,”phone”:”+45 12 34 56 78″},{“id”:2,”name”:”Birgitte Bertelsen”,”email”:”birgitte@example.com”,”phone”:”+45 23 45 67 89″}]
save the list in localStorage key myAppRSVP”
Here Claude and I ran into something that happens occasionally. Claude was extra ambitious and used a new complex module. And after several attempts with “It doesn’t work I get this error…” I couldn’t proceed. Instead, I chose the approach “can you come up with a simpler app solution that works around the problem?”. Claude could do that. Now example 3 works. With data fetched from example 2.
Example 3 on my sandbox
Source code
localStorage Browser
When you get further into using localStorage across pages, it can be helpful to be able to view and manipulate data. Both when you need to “show” some data to the AI that it needs to use as a starting point, but also to be able to work with and share mock-up data. For this, I (meaning me and Claude) have created a simple localStorage Browser.
High-Fidelity prototyping in practice
The basic principles described above form the foundation of my prototyping workflow. In my experience, the process develops organically as you discover new design patterns and components.
When exploring new solution possibilities, I gather inspiration from existing applications and identify what these design patterns are formally called – often through dialogue with AI. For example, I didn’t know that a component with two lists where items can be moved from one to the other is called a “dual-list”. After establishing the terminology, I could easily get such a component generated.
To create effective prototypes, I’ve gradually built a component library that reflects our production system:
- A sidebar menu with the same icon library as our real application
- A mock user database to simulate role assignment
- Reusable data structures and interaction patterns
This library enables us to quickly create prototypes that feel like the finished product – exactly what Marty Cagan describes as High-Fidelity prototypes.
As you develop prototypes, you build both technical understanding and a library of components for future projects. Even without in-depth knowledge of React or Node.js, you gradually learn to modify elements, which accelerates the development process.
If you’ve been inspired by the concept of AI-assisted prototyping, you’re welcome to reach out with questions or to share experiences.
Conclusion
The combination of Node.js, Next.js, Shadcn/UI, and AI assistants like Claude provides an effective method for creating High-Fidelity prototypes with a modern look in a short time. This setup is particularly valuable for product owners and hobby coders who want to turn ideas into testable products without being front-end experts.
Establishing a “common language” with the AI is key to successful results. By being clear about concepts and data structures in your prompts, you can build complex functionalities gradually and with increasing precision.
The process requires some courage and acceptance of a trial-and-error approach. Error messages actually become valuable help in this process, and the dynamic development environment in Next.js significantly accelerates the learning curve.
For product owners, this tool enables you to express exactly what you want and experiment with different approaches without burdening development resources. The significant reduction in time from idea to testing provides faster feedback loops with potential users.
Although the solutions may not always be production-ready, they serve perfectly as prototypes that can demonstrate ideas, gather feedback, and validate concepts before larger investments. This is the core of Marty Cagan’s approach – creating products customers love begins with prototypes that can be tested and refined early in the process.
If you’ve made experiences in this area, become curious, or have questions, feel free to comment on the article.
One thought on “High-Fidelity prototyping using A.I.”