{"id":142953,"date":"2025-12-24T04:22:20","date_gmt":"2025-12-24T04:22:20","guid":{"rendered":"https:\/\/darkopavic.xyz\/?p=142953"},"modified":"2025-12-24T04:22:21","modified_gmt":"2025-12-24T04:22:21","slug":"vibe-coding-as-a-weekend-experiment","status":"publish","type":"post","link":"https:\/\/darkopavic.xyz\/index.php\/2025\/12\/24\/vibe-coding-as-a-weekend-experiment\/","title":{"rendered":"Vibe Coding as a Weekend Experiment"},"content":{"rendered":"\n<p>How I built a working retail\u2011news app without coding skills\u2014and what it taught me about APIs, PWAs, and shipping speed<\/p>\n\n\n\n<p>On a Saturday morning I set myself a small, slightly unfair challenge: could I build a useful iPhone \u201capp\u201d without knowing how to program? Not a demo that looks good in screenshots, a real, working product that fetches live data, remembers user settings, and can be installed on a phone.<\/p>\n\n\n\n<p>At the same time, I wanted to pressure\u2011test something we\u2019ve been building for years: the Fiscal Requirements Portal API. If our news and alerts are truly easy to integrate, the fastest way to prove it is to let a non\u2011developer try.<\/p>\n\n\n\n<p>The rule was simple: one day.<\/p>\n\n\n\n<p>If I still had an unfinished project by dinner, the experiment would be a failure.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">The bet: \u201cno code,\u201d real output<\/h1>\n\n\n\n<p>I started with a clear target. The app would display the latest news and alerts from our portal, and let users filter by country and by type. It would also remember preferences locally so that the next time you open it, you don\u2019t have to set everything up again.<\/p>\n\n\n\n<p>This is exactly the kind of workflow retail and POS teams live in: a steady stream of regulatory changes, the need to slice information by market, and the constant demand for faster decisions.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">The first breakthrough: the prompt is the product<\/h1>\n\n\n\n<p>The first step wasn\u2019t opening an IDE. It was writing a prompt. I fed ChatGPT three ingredients: the goal, the banner image that should appear on top of the screen, and the portal API description. Within seconds I had a structured build spec that could be pasted into Lovable.dev.<\/p>\n\n\n\n<p>That moment matters. When documentation is strong, and the request is precise, AI can do what used to take a developer a full day: translate intent into an implementation plan.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"745\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1024x745.png\" alt=\"\" class=\"wp-image-142954\" style=\"aspect-ratio:1.3744954088308285;width:619px;height:auto\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1024x745.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-300x218.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-768x559.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image.png 1146w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 1. Lovable forces an early strategic decision: ship fast as a PWA, or wrap it as a native app later.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"964\" height=\"1024\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-2-964x1024.png\" alt=\"\" class=\"wp-image-142956\" style=\"aspect-ratio:0.9414050182055479;width:591px;height:auto\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-2-964x1024.png 964w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-2-282x300.png 282w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-2-768x816.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-2.png 1156w\" sizes=\"(max-width: 964px) 100vw, 964px\" \/><\/figure>\n\n\n\n<p><em>Figure 2. Another key question: are you building for yourself, a team, or external users?<\/em><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Why I chose a PWA<\/h1>\n\n\n\n<p>In theory, I wanted a native iPhone app. In practice, I wanted speed. A Progressive Web App (PWA) is a website that behaves like an app: it runs in the browser, but can be installed on the Home Screen, launches full\u2011screen, and can cache content for faster load times.<\/p>\n\n\n\n<p>For a weekend experiment, a PWA is the shortest runway. There\u2019s no App Store submission, no review cycle, and no dependency on Xcode. You ship by deploying static files, the same way you publish a normal website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"668\" height=\"1024\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3-668x1024.png\" alt=\"\" class=\"wp-image-142957\" style=\"width:442px;height:auto\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3-668x1024.png 668w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3-196x300.png 196w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3-768x1178.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3-1001x1536.png 1001w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-3.png 1038w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/figure>\n\n\n\n<p><em>Figure 3. From one prompt to a concrete v1 blueprint\u2014design direction and feature set generated automatically.<\/em><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">The surprising part: shipping is addictive<\/h1>\n\n\n\n<p>Once the first version worked, something unexpected happened. I stopped thinking like a project manager and started thinking like a gamer. Lovable suggested improvements. I clicked. Then it suggested another. I clicked again. In minutes, I had filters, a detail view, local persistence, and a more polished UI than I would ever have designed myself.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"566\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-5-1024x566.png\" alt=\"\" class=\"wp-image-142959\" style=\"aspect-ratio:1.8091751498700357;width:818px;height:auto\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-5-1024x566.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-5-300x166.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-5-768x424.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-5.png 1386w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 4. A live preview with real portal data\u2014banner, tabs, cards, and filters working within minutes.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1-1024x598.png\" alt=\"\" class=\"wp-image-142955\" style=\"aspect-ratio:1.7123637160388898;width:565px;height:auto\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1-1024x598.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1-300x175.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1-768x448.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-1.png 1120w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 5. Feature creep, the fun version: AI keeps proposing upgrades\u2014and you keep saying yes.<\/em><\/p>\n\n\n\n<p>This is where the \u2018vibe\u2019 in vibe coding becomes real. You stay in the flow, you describe what you want, and the tool implements it. It feels less like coding and more like directing.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Deployment: where reality still wins<\/h1>\n\n\n\n<p>Building the app took minutes. Deploying it took longer, and that\u2019s the honest part of the story. Software still has to live somewhere, and \u201csomewhere\u201d has opinions: folder paths, permissions, caching, routing rules.<\/p>\n\n\n\n<p>I wanted the app to run under a subfolder on my own site, not on a managed platform. That\u2019s a common enterprise constraint, and it\u2019s also where many quick demos break.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"571\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-7-1024x571.png\" alt=\"\" class=\"wp-image-142961\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-7-1024x571.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-7-300x167.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-7-768x428.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-7.png 1387w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 6. Connecting the project to GitHub makes deployment repeatable and versioned.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"529\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-4-1024x529.png\" alt=\"\" class=\"wp-image-142958\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-4-1024x529.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-4-300x155.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-4-768x396.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-4.png 1046w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 7. The build step produces the deployable \u2018dist\u2019 bundle: static HTML, JS, CSS, and the service worker.<\/em><\/p>\n\n\n\n<p>The biggest issue was routing. A single\u2011page app can show a clean URL like \u201c\/by\u2011country\u201d, but your server must still return index.html for that path. If you deploy into a subfolder, you also need to teach the app its base path, or it will look for assets in the wrong place and throw 404s.<\/p>\n\n\n\n<p>AI helped here too. I shared screenshots of the errors, explained my hosting setup, and asked for a minimal fix. That\u2019s an underrated skill: learning how to ask for the right next step when you don\u2019t have the full mental model.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"586\" src=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-6-1024x586.png\" alt=\"\" class=\"wp-image-142960\" srcset=\"https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-6-1024x586.png 1024w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-6-300x172.png 300w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-6-768x440.png 768w, https:\/\/darkopavic.xyz\/wp-content\/uploads\/2025\/12\/image-6.png 1387w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Figure 8. The finished result running from a subfolder\u2014exactly the kind of deployment reality enterprise teams face.<\/em><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to repeat the experiment<\/h1>\n\n\n\n<p>If you want to run the same test, whether for a portal, a data product, or an internal API, here\u2019s the playbook in plain language.<\/p>\n\n\n\n<p>Start by choosing a small, high\u2011value surface area. News feeds, alerts, status dashboards, and knowledge bases work well because they are read\u2011heavy and workflow\u2011light. Then collect the three inputs the AI needs: the API documentation, a clear list of filters or views, and a deployment target (a domain or subfolder).<\/p>\n\n\n\n<p>When you write your prompt for Lovable (or any similar builder), aim for specificity without noise. Say what the app must do, what it must remember locally, and how it should authenticate. If your API uses tokens, treat them like passwords: don\u2019t hardcode them in public code, and don\u2019t paste them into screenshots that will be shared.<\/p>\n\n\n\n<p>A simple, reusable prompt pattern looks like this:<\/p>\n\n\n\n<p>Build a Progressive Web App called \u201c&lt;APP NAME&gt;\u201d.<br>It fetches items from &lt;API ENDPOINT(S)&gt; using Bearer token auth.<br>Users can filter by &lt;COUNTRY&gt; and &lt;TYPE&gt;, and the app remembers settings locally.<br>Deploy it under &lt;BASE PATH&gt;, so all routes and assets work in a subfolder.<\/p>\n\n\n\n<p>Once you have a working version, connect it to GitHub. That turns the project from a one\u2011off experiment into something you can iterate safely. Build the production bundle, upload the output folder to your web server, and confirm it runs over HTTPS.<\/p>\n\n\n\n<p>Finally, install it on iPhone the way Apple intended PWAs to be installed: open the link in Safari, tap the Share icon, choose \u201cAdd to Home Screen,\u201d and confirm. In ten seconds, it behaves like any other app on your phone.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">What this taught me about APIs and product growth<\/h1>\n\n\n\n<p>The most important lesson wasn\u2019t about PWAs or routing. It was about distribution. A good API is no longer just a technical feature, it\u2019s a growth channel.<\/p>\n\n\n\n<p>If an API is consistent, predictable, and documented with real examples, the barrier to integration collapses. Suddenly the person building a working prototype might be a founder, a consultant, a product manager, or a retailer\u2019s compliance lead, not a developer.<\/p>\n\n\n\n<p>That has a strategic implication for every company that publishes data: treat your API like a product. The easier it is to consume, the faster your ecosystem grows.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">A small invitation<\/h1>\n\n\n\n<p>If you want to see the result of my weekend experiment, the demo runs as a PWA at: <a href=\"https:\/\/www.darkopavic.xyz\/test-news-app\/\">https:\/\/www.darkopavic.xyz\/test-news-app\/<\/a><\/p>\n\n\n\n<p>Open it on an iPhone, add it to your Home Screen, and you\u2019ll understand why this workflow feels like a turning point.<\/p>\n\n\n\n<p>(I will keep it working for 30 days with full access to all news from our fiscal portal https:\/\/www.fiscal-requirements.com)<\/p>\n\n\n\n<p>And if you\u2019re building your own data product, try the same challenge: pick one weekend, set a clear goal, and let the tools surprise you. The point isn\u2019t to replace engineering. The point is to compress the distance between idea and proof.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How I built a working retail\u2011news app without coding skills\u2014and what it taught me about APIs, PWAs, and shipping speed On a Saturday morning I set myself a small, slightly unfair challenge: could I build a useful iPhone \u201capp\u201d without knowing how to program? Not a demo that looks good in screenshots, a real, working&#8230;<\/p>\n","protected":false},"author":1,"featured_media":142962,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"episode_type":"","audio_file":"","cover_image":"","cover_image_id":"","duration":"","filesize":"","date_recorded":"","explicit":"","block":"","itunes_episode_number":"","itunes_title":"","itunes_season_number":"","itunes_episode_type":"","filesize_raw":"","footnotes":""},"categories":[56],"tags":[],"class_list":["post-142953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/posts\/142953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=142953"}],"version-history":[{"count":1,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/posts\/142953\/revisions"}],"predecessor-version":[{"id":142963,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/posts\/142953\/revisions\/142963"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/media\/142962"}],"wp:attachment":[{"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=142953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=142953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/darkopavic.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=142953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}