tl;dr
LLMs will follow the same hype cycle as cloud, crypto, and blockchain — useful for those who truly need them, but not the revolution everyone claimed. They're energy-hungry, expensive to run at scale, and pose serious security risks when running locally with broad system access.
As a developer, your LLM effectiveness is just a reflection of your existing engineering skills — not some new "prompting profession." To prove the point, the author rebuilt a multiplayer Minesweeper project the old-fashioned way: vanilla CSS over Tailwind, Symfony/Twig on the backend, and clean code over AI-generated shortcuts.
On the technical side, the old class-based React code was modernized with hooks, and libraries like Material UI and react-hook-form were brought in to keep things clean and maintainable. Most notably, the deprecated WebSocket layer was replaced with Mercure — a modern, HTTP-native approach to real-time communication that fits naturally into the Symfony ecosystem. Sometimes boring and proven beats shiny and new — but that doesn't mean you can't quietly upgrade the parts that actually deserved better.
I don't think I'm saying anything new about what has been happening in the IT world over the last year or two since LLMs became part of our everyday lives. In my opinion, LLMs will follow the same path as everything else that has appeared in IT over the last 30 years — from NFTs and crypto to blockchain and the cloud.
When cloud technologies became widely available, everybody put their four-page portfolio on the cloud because it seemed like "the future." And obviously, because it was cheap. After the real costs emerged, the cloud hype died down to a more normal level, and now those people and companies that genuinely need it are the ones using it. More or less.
Near future
Back in 2022, there was a widespread belief that software development would become a hobby, and that anyone could do a software developer's job — the so-called "vibe-coder" era. And it would all be cheap, of course. Meanwhile, anyone who has ever tried Ollama or LM Studio knows the reality: running LLMs consumes an enormous amount of energy. The first time you watch your GPU struggle for a minute or two while your OS lags just from asking a simple question, you start to wonder how much energy will be burned when 100k users do the same thing simultaneously w/ complex queries. Will $20/month per user really be enough to sustain that? Everybody already knows the answer. But I always wondered, anybody thought about how much will be the prices incresased.
Security questions
When we will reach the real prices? Meanwhile the Copilot increases its prices by hunderds of percents and this is only the start. Another issue is the security aspect of LLMs. Five or six years ago, when cloud services took off, companies voluntarily uploaded their data — but only when they were actually using it. If you are a software developer using LLMs as an agent, I just want to point out: those LLMs are running on your machine. Have you ever stopped to think about that? Just ten years ago, the conventional wisdom was that we needed to be very careful about the applications we installed and how much data we shared w/ them. And now? We install an application that can, by default, see everything on our machine. Even in open-source tools like OpenCode, you have to explicitly restrict what the LLM can access. And I still did not mention the OpenClaw and similar applications...
We know how FAANG companies and other tech giants have misled us about our data time and again — selling it, using it w/o consent, and facing little to no real punishment. What is going to stop them from taking data straight from our computers, especially when we install the software ourselves? From an IT security perspective, this is a nightmare.

The Mineseeker Game

Last year I started using LLMs more seriously as programming agents — partly to learn what they were capable of, and partly because I had a bit of FOMO from all the hype surrounding them. At first it felt like black magic, but after a while I realized it was far more straightforward than I had initially thought. Now I can confidently say I haven't missed much. A lot of people claim that prompting is a new profession, but I don't think it is. Your effectiveness w/ LLMs depends almost entirely on your existing software development skills. If you are an architect who knows how to design and write both backend and frontend code, you have a serious advantage over someone w/ no software engineering background.
Even w/o writing any dedicated documentation, AGENTS.md files, or SKILLS files, if you maintain good code quality, LLMs will follow your style confidently. And w/ a bit of practice in prompting and documentation — which LLMs can help w/ too — your efficiency only increases.
I developed a multiplayer Minesweeper game back in mid-2018. Since then, I never had the time or motivation to finish it properly. I was never satisfied w/ its infrastructure or codebase, which is why I left it unmaintained until very recently. The core game logic was written in class-based React — simply because hooks didn't exist when I started. So I decided to revisit it, but entirely w/o LLMs. I wrote the documentation using LLMs, and I added some AGENTS.md instructions for times when I might not have enough bandwidth for maintenance. My goal is to maintain the project at least once per quarter — w/ or w/o AI assistance.
The design approach
Another decision I made: no CSS libraries. No Tailwind, nothing like that. I sometimes miss the era when we wrote everything by hand and thought carefully about what should happen at every step. I wanted to use HTML and CSS the way they were designed to be used, putting code exactly where it belongs.
1<html>
2 <head>
3 <link rel="stylesheet" href="stlye.css" />
4 <title>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</title>
5 </head>
6 <body>
7 <header>
8 Lorem ipsum dolor sit amet
9 </header>
10 <article>
11 <h1>Lorem ipsum dolor sit amet</h1>
12 <div class="content">
13 Lorem ipsum dolor sit amet, nostrud sed sed ullamco consectetur
14 aliquip cupidatat non cupidatat do dolore irure quis deserunt
15 voluptate ad sed elit excepteur lorem voluptate do est non
16 laborum nulla irure qui incididunt aute voluptate qui dolore
17 dolor dolor nulla eiusmod culpa minim nostrud officia voluptate
18 </div>
19 </article>
20 <footer>
21 <img src="image.png" alt="Lorem ipsum dolor sit amet" />
22 </footer>
23 </body>
24</html>1* {
2 margin: 0;
3 padding: 0;
4 box-sizing: border-box;
5}
6
7html {
8 font-size: 16px;
9}
10
11body {
12 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
13 line-height: 1.6;
14 color: #1a1a2e;
15 background: #f0f2f5;
16 min-height: 100vh;
17 display: flex;
18 flex-direction: column;
19}
20
21header {
22 background: linear-gradient(135deg, #667eea, #764ba2);
23 color: white;
24 padding: 1.5rem 2rem;
25 text-align: center;
26 font-size: 1.25rem;
27 font-weight: 600;
28 letter-spacing: 0.02em;
29 box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
30}
31
32article {
33 flex: 1;
34 max-width: 800px;
35 margin: 3rem auto;
36 padding: 0 1.5rem;
37}
38
39h1 {
40 font-size: 2rem;
41 color: #16213e;
42 margin-bottom: 1.5rem;
43 border-left: 5px solid #667eea;
44 padding-left: 1rem;
45}
46
47.content {
48 background: white;
49 padding: 2rem;
50 border-radius: 12px;
51 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
52 color: #333;
53 text-align: justify;
54}
55
56footer {
57 background: #16213e;
58 padding: 2rem;
59 text-align: center;
60}
61
62footer img {
63 max-width: 100%;
64 height: auto;
65 border-radius: 8px;
66 box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
67 transition: transform 0.3s ease;
68}
69
70footer img:hover {
71 transform: scale(1.03);
72}Everyone can judge for themselves which approach is more readable.
1<html>
2 <head>
3 <script src="https://cdn.tailwindcss.com"></script>
4 <title>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</title>
5 </head>
6 <body class="font-sans leading-relaxed text-[#1a1a2e] bg-gray-100 min-h-screen flex flex-col">
7 <header class="bg-gradient-to-r from-[#667eea] to-[#764ba2] text-white text-center py-6 px-8 text-xl font-semibold tracking-wide shadow-lg">
8 Lorem ipsum dolor sit amet
9 </header>
10 <article class="flex-1 max-w-4xl mx-auto my-12 px-6">
11 <h1 class="text-4xl font-bold text-[#16213e] mb-6 border-l-4 border-[#667eea] pl-4">Lorem ipsum dolor sit amet</h1>
12 <div class="bg-white p-8 rounded-xl shadow-md text-gray-700 text-justify">
13 Lorem ipsum dolor sit amet, nostrud sed sed ullamco consectetur
14 aliquip cupidatat non cupidatat do dolore irure quis deserunt
15 voluptate ad sed elit excepteur lorem voluptate do est non
16 laborum nulla irure qui incididunt aute voluptate qui dolore
17 dolor dolor nulla eiusmod culpa minim nostrud officia voluptate
18 </div>
19 </article>
20 <footer class="bg-[#16213e] py-8 text-center">
21 <img src="image.png" alt="Lorem ipsum dolor sit amet" class="max-w-full h-auto rounded-lg shadow-2xl transition-transform duration-300 hover:scale-105" />
22 </footer>
23 </body>
24</html>In my case, looking at too much Tailwind code makes my eyes roll — and that's before even getting to debugging. This is just one small example of a much bigger picture.
The pure Symfony approach
I also decided I wanted a Twig-based website wrapped around the React game. Over the last few years, I haven't had the opportunity to write a classic Symfony application in any of my projects, and I've genuinely missed it. Over the past decade, PHP has matured enough to make coding in it a genuinely enjoyable experience.
Engineers who worked w/ PHP 5 and Symfony 1 or 2 know exactly what I mean — especially if you remember what PHP was like before the framework era. In today's PHP frameworks, you can find a solution for almost anything you need. Almost every problem has a mature, battle-tested answer. For more complex challenges, you can easily combine those smaller solutions like LEGO bricks. If you know how to design an application well, PHP's building blocks — i.e. Symfony bundles — make it straightforward to build.
For example, in Symfony 8, creating a single REST API endpoint takes just a few lines of code.
1<?php
2
3declare(strict_types=1);
4
5namespace SplendidBear\Controller;
6
7use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
8use Symfony\Component\HttpFoundation\JsonResponse;
9use Symfony\Component\HttpKernel\Attribute\AsController;
10use Symfony\Component\Routing\Attribute\Route;
11
12#[AsController]
13class ExampleController extends AbstractController
14{
15 private const string WORLD = 'world!';
16
17 #[Route('/api/hello-world methods: ['GET'])]
18 public function helloWorld(): JsonResponse
19 {
20 return new JsonResponse([
21 'hello' => self::WORLD,
22 ]);
23 }
24}Nothing more than that. No extra markup, no XML, no YAML, no annotation files, no PHP config files. W/ Attributes, I think PHP is genuinely beautiful. Naturally, PHP isn't perfect — it lacks some things that feel mandatory in more established languages — but it is evolving rapidly.
If you strive for K.I.S.S. in your Symfony projects and stick close to Symfony's native conventions, upgrades become trivial even in long-running projects. If you follow S.O.L.I.D. principles, you/somebody else will still understand your own code two years later too.
In Symfony, forms work almost exactly the same way they did ten years ago — no surprises. Twig has gained many new features since then. The one thing I chose not to use is Symfony UX. It looks decent and interesting, but in my opinion it's designed for a different use case than what I needed.
Refactoring the frontend
Of course, deciding to revisit the project meant confronting the old codebase head-on. The first order of business was modernizing the React side of things. The original class-based components are now fully rewritten using React hooks — cleaner, more readable, and far easier to reason about. Along the way, I also swapped in some modern, well-maintained libraries: Material UI for the component layer, and react-hook-form for handling forms without the usual boilerplate headache. Nothing exotic, nothing over-engineered — just solid, proven tools that make the day-to-day development experience more enjoyable.
The bigger and more satisfying change, however, was rethinking the real-time communication layer. The original implementation relied on WebSockets, which — while functional at the time — has since become a deprecated approach in this context. I replaced it entirely with Mercure.
For those unfamiliar, Mercure is a high-level, HTTP-native protocol for real-time communication — and the differences compared to WebSockets are significant. WebSockets is a low-level protocol that was never designed to take advantage of HTTP/2, is notoriously difficult to secure, and requires you to implement features like authorization, automatic reconnection, and state reconciliation entirely by yourself. Mercure, on the other hand, provides all of these out of the box. Because it is built on top of Server-Sent Events (SSE) and plain HTTP connections, it also inherits all the security benefits of the HTTP stack — including CORS protections that WebSocket connections typically bypass. On top of that, it plays nicely with existing infrastructure: proxies, load balancers, and firewalls require no special configuration, unlike WebSocket upgrades. And for mobile clients, it is notably more battery-efficient too.

The one architectural trade-off worth mentioning is that Mercure is server-to-client only. Sending data back to the server happens via regular HTTP POST requests — which, if anything, feels more natural and RESTful. For a multiplayer game like Mineseeker, this is actually a perfect fit: the server broadcasts the game state to all connected clients, while player actions travel back through standard HTTP calls. It feels like the right tool for the job: modern, standards-based, and a natural fit within the Symfony ecosystem.
The end result is a project that I'm actually happy to put my name on — something I couldn't quite say about the 2018 version. Sometimes the best thing you can do for an old project isn't to rewrite it from scratch, but to give it the patience and care it deserved the first time around.

