{"id":4783,"date":"2026-01-31T14:51:59","date_gmt":"2026-01-31T14:51:59","guid":{"rendered":"https:\/\/nikola-breznjak.com\/blog\/?p=4783"},"modified":"2026-01-31T14:51:59","modified_gmt":"2026-01-31T14:51:59","slug":"vibe-coding-a-pokemon-search-app-with-cursor","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/vibecoding\/vibe-coding-a-pokemon-search-app-with-cursor\/","title":{"rendered":"Vibe Coding a Pok\u00e9mon Search App with Cursor"},"content":{"rendered":"<h2>TL;DR<\/h2>\n<p>We&#8217;re going to build a <strong>Pok\u00e9mon search app<\/strong>. But we&#8217;re not going to write even one line of code.<\/p>\n<p>\ud83e\udd28<\/p>\n<p>I know, coming from a developer (<em>who used to take pride in what\u2026 we&#8217;ll call &quot;handcrafted artisanal code&quot;<\/em>), this sounds like heresy.<\/p>\n<p>But stay with me here and see how far these kind of tools have come in only the last year.<\/p>\n<p>We&#8217;ll be building the app using the so-called <strong>vibe coding<\/strong>. Basically: <strong>you &quot;talk&quot; to the editor<\/strong>, the editor writes the code, and <strong>you navigate aka prompt<\/strong> it toward the final product (that you&#8217;ll be happy with \ud83e\udd1e).<\/p>\n<blockquote>\n<p>Programmers\/Coders\/Engineers &#8211; we&#8217;ve always liked to tell\/instruct computers what to do. That&#8217;s still true, only the syntax got\u2026 conversational \ud83d\ude42<\/p>\n<p>Who would&#8217;ve thought \ud83e\udd37\u200d\u2642\ufe0f<\/p>\n<p>~ Nikola Bre\u017enjak <a href=\"https:\/\/x.com\/HitmanHR\/status\/2016450596107083908\">on X<\/a><\/p>\n<\/blockquote>\n<p>In my previous post, I did this with Replit: <a href=\"https:\/\/nikola-breznjak.com\/blog\/vibecoding\/vibe-coding-a-pokemon-search-app-with-replit\/\">Vibe Coding a Pok\u00e9mon Search App with Replit<\/a>.<\/p>\n<p>This time we&#8217;ll do the same thing, step-by-step, <strong>but with Cursor<\/strong>.<\/p>\n<p>Same app. Same flow. Different tool. More &quot;local dev&quot; vibes (<em>yup, puns still need some work<\/em>).<\/p>\n<h2>The Tools<\/h2>\n<p>In this post, we&#8217;ll be using <strong>Cursor<\/strong>: <a href=\"https:\/\/www.cursor.com\/\">https:\/\/www.cursor.com\/<\/a>.<\/p>\n<p>Cursor is a code editor (much like <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code &#8211; VSC<\/a> &#8211; actually, its fork, in Github terms), but with an AI Agent that can plan and implement changes across your codebase. It&#8217;s like pair-programming\u2026 except your pair doesn&#8217;t need bathroom breaks.<\/p>\n<p>For bonus points, we won&#8217;t even type anything. Instead, <strong>we&#8217;ll use our voice to code<\/strong> (\ud83e\udd2f, <em>I know<\/em>) with *<a href=\"https:\/\/wisprflow.ai\/r?NIKOLA1\"><strong>WisprFlow<\/strong><\/a> (or alternatives like SuperWhisper \/ VoiceTypr).<\/p>\n<h2>The Old Ways\u2122<\/h2>\n<p>Previously, I wrote the &quot;classic&quot; (<em>may I say, &quot;old&quot; at this point?<\/em>) tutorials building the same app with two different tech stacks:<\/p>\n<ul>\n<li><a href=\"https:\/\/nikola-breznjak.com\/blog\/javascript\/getting-started-with-vue-js-3-by-building-a-pokemon-search-application\/\">Getting started with Vue.js 3 by building a Pokemon search application<\/a><\/li>\n<li><a href=\"https:\/\/nikola-breznjak.com\/blog\/javascript\/react\/getting-started-with-react-by-building-a-pokemon-search-application\/\">Getting started with React by building a Pokemon search application<\/a><\/li>\n<\/ul>\n<p>This one is different.<\/p>\n<p>Same Pok\u00e9mon search app.<\/p>\n<p>Less typing.<\/p>\n<p>More vibes (\ud83d\ude02 <em>I know, I know<\/em>).<\/p>\n<h2>Let&#8217;s Start Prompting<\/h2>\n<p>If you want to follow along:<\/p>\n<ol>\n<li>(Download, Install) Open Cursor<\/li>\n<li>Create a new empty folder (e.g. <code>pokemon-cursor<\/code>)<\/li>\n<li>Open that folder in Cursor<\/li>\n<li>Open the &quot;AI chat&quot; pane (<code>Command + i<\/code>) and make sure you select the <strong>Plan<\/strong> mode<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/YNco74W.png\" alt=\"\" \/><\/p>\n<blockquote>\n<p>Pro tip: copy\/paste these and adapt in case you&#8217;re feeling adventurous.<\/p>\n<\/blockquote>\n<h3>Prompt 1: Spec first, code later<\/h3>\n<p>First of all, <strong>always start with a plan<\/strong> before writing any code.<\/p>\n<p>In the Replit post, I started with a simple prompt and then clicked Replit&#8217;s <strong>Improve prompt<\/strong> button.<\/p>\n<p>I like that &quot;improved&quot; prompt better as:<\/p>\n<ul>\n<li>it&#8217;s more specific about <em>what the app should do<\/em> (less back-and-forth)<\/li>\n<li>it includes <em>UI style guidance<\/em> (so you don&#8217;t get &quot;default HTML 2003 vibes&quot;)<\/li>\n<li>it forces a <em>PRD + checklist<\/em> (so you can hold the AI accountable)<\/li>\n<\/ul>\n<p>So\u2026 let&#8217;s use that improved prompt here too \ud83d\udc47<\/p>\n<p>Paste this into Cursor (Plan mode):<\/p>\n<blockquote>\n<p>A comprehensive web-based Pok\u00e9mon search application that allows users to discover and view detailed information about Pok\u00e9mon using the Pok\u00e9API.<\/p>\n<p>Core Features:<\/p>\n<ul>\n<li>Search Pok\u00e9mon by name or ID (bonus: autocomplete suggestions if it&#8217;s simple)<\/li>\n<li>Display detailed Pok\u00e9mon information (stats, types, abilities, sprites)<\/li>\n<li>Browse Pok\u00e9mon list with pagination (if it makes sense; keep it simple)<\/li>\n<li>Responsive design that works on mobile and desktop devices<\/li>\n<\/ul>\n<p>Visual References:<\/p>\n<p>Inspired by the official Pok\u00e9mon website and Pok\u00e9dex interfaces, using vibrant, game-accurate designs and intuitive card-based layouts.<\/p>\n<p>Style Guide:<\/p>\n<ul>\n<li>Colors: Primary #FFCB05 (Pok\u00e9mon yellow), Secondary #3D7DCA (Pok\u00e9mon blue), Accent #CC0000 (Pok\u00e9mon red), Text #2A2A2A (dark grey), Card Background #FFFFFF (white)<\/li>\n<li>Design: Flexo\/Poppins\/Roboto fonts, card-based grid layout, mobile-first approach, clean search interface with prominent search bar<\/li>\n<\/ul>\n<p>Special Requirements:<\/p>\n<ul>\n<li>Must include a detailed PRD (Product Requirement Document) covering user stories, UI layout, components, state management, API endpoints, error\/loading states, accessibility considerations, folder structure, and a deployment plan for GitHub Pages<\/li>\n<li>Provide a numbered implementation checklist after the PRD<\/li>\n<li>DO NOT include actual code implementation \u2014 documentation and planning only<\/li>\n<\/ul>\n<\/blockquote>\n<p>You can leave the <code>Auto<\/code> for Model, but lately I&#8217;ve been defaulting to Opus 4.5. Then, just hit ENTER or click the button with the arrow pointing up (\u2191).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/chBiS7U.png\" alt=\"\" \/><\/p>\n<h3>Answer the questions<\/h3>\n<p>Since we didn&#8217;t define the actual tech stack, Cursor will ask us which stack we want (language + CSS framework):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/4nTDaTU.png\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/Dws58lf.png\" alt=\"\" \/><\/p>\n<p>I chose Vue.js and Tailwind CSS.<\/p>\n<h3>Build the plan<\/h3>\n<p>Select <code>Build<\/code> to start creating the PRD and the implementation checklist.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/AUaTY7G.png\" alt=\"\" \/><\/p>\n<h3>Review the prompt<\/h3>\n<p>Cursor will create a seriously detailed PRD. I won&#8217;t paste it here fully, but will mention that mine included sections like:<\/p>\n<pre><code># Pok\u00e9Search - Product Requirements Document\n\n1. Project Overview\n2. User Stories\n3. UI Layout and Wireframes\n4. Component Architecture\n5. State Management\n6. API Endpoints\n7. Loading and Error States\n8. Accessibility Considerations\n9. Style Guide Implementation\n10. Folder Structure\n11. GitHub Pages Deployment Plan\n12. Implementation Checklist<\/code><\/pre>\n<p>Also, Cursor created a detailed implementation checklist (sharing just sections that it covered below):<\/p>\n<pre><code>Phase 1: Project Setup\nPhase 2: API Layer\nPhase 3: Core Components\nPhase 4: Detail View\nPhase 5: Search Integration\nPhase 6: Polish and Accessibility\nPhase 7: Testing and Quality\nPhase 8: Deployment\nFinal Checklist\nBonus Features (Optional)<\/code><\/pre>\n<h3>Start cooking<\/h3>\n<p>Before you do &#8216;start cooking&#8217;, I really encourage you to <strong>read through the PRD<\/strong> and see if:<\/p>\n<ul>\n<li>it describes a simple UI<\/li>\n<li>it mentions loading + error states<\/li>\n<li>it keeps state management simple<\/li>\n<li>the folder structure looks reasonable<\/li>\n<li>it mentions GitHub Pages deployment<\/li>\n<\/ul>\n<p>If something looks off, just tell Cursor what you want. And, once you&#8217;re happy, move on.<\/p>\n<h3>OK, now we start cooking \ud83e\uddd1\u200d\ud83c\udf73<\/h3>\n<p>Let&#8217;s now tell Cursor to implement the project by following the PRD and the Checklist it created:<\/p>\n<pre><code>Implement the product described in @PRD.md by executing @IMPLEMENTATION_CHECKLIST.md end-to-end.\n\nRules:\n- Treat @PRD.md as source of truth. If checklist conflicts, call it out and follow PRD.\n- Work in small, reviewable commits (or clearly separated change blocks) per checklist section.\n- After each section, run\/tests\/build locally and paste results. Fix issues before moving on.\n- Keep the solution minimal and maintainable. No over-engineering.\n- Update docs and TODOs as you go; leave the repo in a \u201cship-ready\u201d state.\n\nDeliverables:\n- All checklist items completed (explicitly mark each as done with a short note).\n- A final summary: what was implemented, how to run, how to test, and any known gaps (should be none).\nStart now.<\/code><\/pre>\n<p>Finally, send that prompt to Cursor (make sure you have <code>Agent<\/code> mode selected).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/0b4hCyn.png\" alt=\"\" \/><\/p>\n<blockquote>\n<p>\u26a0\ufe0f You would most likely get a good final output if you wouldn&#8217;t use such a detailed prompt. Something like &quot;Implement the @PRD&quot; would most likely suffice. But, as with anything, treat this like a craft and go an extra mile (test multiple prompts and see what works best for you).<\/p>\n<p><strong>TL;DR<\/strong>: a bit more structure and detail in the prompt goes a long way.<\/p>\n<\/blockquote>\n<h3>Now we wait&#8230; \u23f3<\/h3>\n<p>Here&#8217;s where Cursor does the &#8216;actual work&#8217; of:<\/p>\n<ul>\n<li>creating files<\/li>\n<li>installing dependencies<\/li>\n<li>wiring up the UI<\/li>\n<li>calling Pok\u00e9API<\/li>\n<li>and fixing the inevitable &quot;oops, that didn&#8217;t run&quot; moments<\/li>\n<\/ul>\n<p>Yes, it can do all of that. No, it doesn&#8217;t always do it perfectly, and that&#8217;s why you&#8217;re here \ud83d\ude05<\/p>\n<p>Meaning, it will ask you for permission to run certain commands (<code>npm install<\/code>, <code>npm run dev<\/code>, &#8230;). You can choose to whitelist the commands so it won&#8217;t ask your permission about running them again (do thread lightly here though, and actually read which commands it wants to run).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/3hbxXJq.png\" alt=\"\" \/><\/p>\n<p>As it&#8217;ll be doing its thing, you&#8217;ll be able to follow along and read what it is all that it&#8217;s doing. <em>I know, looking at someone else doing your job, gives you a weird feeling.<\/em> \ud83d\ude05<\/p>\n<h3>Done<\/h3>\n<p>When Cursor is done, you&#8217;ll see a detailed message of what it did, including the section on running it and deploying to Github:<\/p>\n<pre><code>### How to Run\n\n```bash\n# Install dependencies\nnpm install\n\n# Development server\nnpm run dev\n\n# Production build\nnpm run build\n\n# Preview production build\nnpm run preview<\/code><\/pre>\n<h3>Preview<\/h3>\n<p>In the Replit version, preview was built into the web UI.<\/p>\n<p>With Cursor, we&#8217;re running locally on our machine \u2014 so the &quot;Preview&quot; step is simply:<\/p>\n<ul>\n<li>run the commands it told you, or just tell Cursor to run the app (yes, literally, write &quot;run the app&quot;)<\/li>\n<\/ul>\n<p>In my case, the URL was <a href=\"http:\/\/localhost:4173\/PokemonSearch\/\">http:\/\/localhost:4173\/PokemonSearch\/<\/a> and it looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/2sZg0bK.png\" alt=\"\" \/><\/p>\n<p>I&#8217;ll be frank and say that I liked the Replit output better (see here: <a href=\"https:\/\/pokedex-nikolabreznjak.replit.app\/\">https:\/\/pokedex-nikolabreznjak.replit.app\/<\/a>), but you can get to that as well by additional prompting.<\/p>\n<p>I asked Cursor to <code>let&#039;s now add a nice landing page to it.<\/code>, and it came up with this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/0HBnDQw.png\" alt=\"\" \/><\/p>\n<p>Not bad for a terrible prompt \ud83d\ude48<\/p>\n<h3>Publish and share<\/h3>\n<p>Replit had a &quot;Publish now&quot; button.<\/p>\n<p>Here, we&#8217;ll just ask Cursor to tell us how to deploy to Github Pages.<\/p>\n<p>It said:<\/p>\n<pre><code># Initialize git (if not already)\ngit init\n\n# Add all files\ngit add .\n\n# Commit\ngit commit -m &quot;Initial commit: Pok\u00e9Search app&quot;\n\n# Create repo on GitHub, then add remote\ngit remote add origin https:\/\/github.com\/YOUR_USERNAME\/YOUR_PROJECT_NAME.git\n\n# Push to master\ngit push -u origin master<\/code><\/pre>\n<p>Only thing you have to change in the commands above is the Github username, and the project&#8217;s name.<\/p>\n<p>As a step 2, you have to:<\/p>\n<pre><code>Go to your repository on GitHub\nClick Settings \u2192 Pages (left sidebar)\nUnder &quot;Build and deployment&quot;:\nSource: Select GitHub Actions\nThat&#039;s it! The workflow will trigger automatically<\/code><\/pre>\n<p>You can now run the workflow manually in the <code>Actions<\/code> tab on Github, or push some code changes and it will trigger automatically.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/QMHJXA3.png\" alt=\"\" \/><\/p>\n<p>Once deployed, your app is going to be available at: <a href=\"https:\/\/YOUR_USERNAME.github.io\/YOUR_PROJECT_NAME\/\">https:\/\/YOUR_USERNAME.github.io\/YOUR_PROJECT_NAME\/<\/a><\/p>\n<p>In my case, you can check it out here: <a href=\"https:\/\/NikolaBreznjak.github.io\/PokemonSearchCursor\/\">https:\/\/NikolaBreznjak.github.io\/PokemonSearchCursor\/<\/a><\/p>\n<h2>Conclusion: the future is now!?<\/h2>\n<p>Here&#8217;s the uncomfortable truth: those who still treat AI coding tools as &quot;cheating&quot; or &quot;not there yet&quot; are losing out. If not on shipping MVPs faster, then on <strong>getting up to speed on unfamiliar codebases<\/strong>, and learning faster in general.<\/p>\n<p>\u26a0\ufe0f <strong>And this last part is something I want to emphasise: if you &quot;just&quot; vibe code and have absolutelly no idea how the thing <em>YOU<\/em> built works (and have no desire to learn), then you&#8217;re missing the point<\/strong>.<\/p>\n<p>Instead, you&#8217;ve got an amazing oportunity that the devs in the past didn&#8217;t have: you can ask the tool to tell you &quot;how does this code work&quot;. And, you can ask all the questions without the fear of showing your lack of knowledge.<\/p>\n<p>And, if you&#8217;re worried about quality (valid!), you don&#8217;t have to YOLO it. Do this instead:<\/p>\n<ol>\n<li>Tell the model: <strong>Explain what you intend to do without writing any code<\/strong><\/li>\n<li>Make it produce a <strong>long spec document<\/strong> (architecture, edge cases, test plan).<\/li>\n<li>Iterate on that doc until it&#8217;s legit<\/li>\n<li>Then say something along the lines of: <strong>Now, iplement this spec perfectly<\/strong><\/li>\n<\/ol>\n<p>I would have never dreamed that the hottest new programming language will be <code>[insertLanguageHere]<\/code>. I say it like that because, technically, you could write in your language and some (most?) of the tools would understand you. If not, you can throw it in a ChatGPT (or any similar tool) for translation and then feed it translated into the AI tool.<\/p>\n<p>No, the world won&#8217;t make the devs extinct, but it surely will enable a lot of non-devs to create things that make actual money. It&#8217;s your choice if you want to watch from the sidelines or get in on the action and see how it can help you &#8211; maybe now&#8217;s the time to do that project you &#8216;never had the time for&#8217;.<\/p>\n<p>I&#8217;m cheering for you, good luck!<\/p>\n<h2>Disclaimer<\/h2>\n<p>Links prepended with a <code>*<\/code> are referral links.<\/p>\n<p>If you enjoy the content and decide to sign up through those links, you&#8217;ll be helping me feed my caffeine addiction \u2615\ufe0f<\/p>\n<p>Thanks a bunch, you glorious human! \ud83d\ude4c<\/p>\n<h2>New achievement<\/h2>\n<p>You made it to the end, here&#8217;s a \ud83c\udf96\ufe0f<\/p>\n<p>P.S. In case you were wondering, the style has been recently influenced by a book series called *<a href=\"https:\/\/amzn.to\/4bKTmsO\">Dungeon Crawler Carl<\/a>.<\/p>\n<p>Enjoy! \ud83d\udc4b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR We&#8217;re going to build a Pok\u00e9mon search app. But we&#8217;re not going to write even one line of code. \ud83e\udd28 I know, coming from a developer (who&hellip;<\/p>\n","protected":false},"author":1,"featured_media":4785,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64],"tags":[],"class_list":["post-4783","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vibecoding"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/4783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=4783"}],"version-history":[{"count":0,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/4783\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/4785"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=4783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=4783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=4783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}