This service tests the validity of an RSS 2.0 feed, checking to see that it follows the rules of the RSS specification. For advice from the RSS Advisory Board on how to implement RSS and handle issues such as enclosures and HTML encoding, read the RSS Best Practices Profile. This checker is also a validator of Atom and RSS 1.0 feeds.
Use this tester regularly to ensure that your RSS feed continues to work well in the wide audience of RSS readers, podcast clients and other software that supports the format.
This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Valticus</title><link>https://valticus.pro/</link><description>Expert insights on programming, technology, and software development. Discover practical code examples, development tools, and in-depth technical tutorials.Valticus</description><generator>Hugo 0.162.1 -- gohugo.io</generator><language>en-us</language><managingEditor>valticus81@gmail.com (Val Paliy)</managingEditor><webMaster>valticus81@gmail.com (Val Paliy)</webMaster><lastBuildDate>Wed, 22 Jul 2026 23:22:13 +0000</lastBuildDate><image><url>https://valticus.pro/images/logo.webp</url><title>Valticus</title><link>https://valticus.pro/</link></image><atom:link href="https://valticus.pro/index.xml" rel="self" type="application/rss+xml"/><item><title>What I'd Learn If Starting Today: A No-Nonsense Dev Career Roadmap</title><link>https://valticus.pro/posts/what-id-learn-if-starting-today-dev-career-advice/</link><pubDate>Thu, 16 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/what-id-learn-if-starting-today-dev-career-advice/</guid><description>A comprehensive guide on how to start a career in web development in 2026, focusing on fundamentals, the right stack, and avoiding the 'framework trap' based on 20+ years of experience.</description><category>Career</category><content:encoded><h2 id="the-hindsight-of-two-decades">The Hindsight of Two Decades</h2><p>Twenty years in web development. Hundreds of projects. Dozens of technologieslearned, mastered, and eventually discarded. If I could step into a time machineand talk to my younger self on day one, my advice wouldn&rsquo;t be about the latest&ldquo;hot&rdquo; framework or a specific library. It would be about <strong>compound interest inknowledge</strong>.</p><p>The industry is noisier than ever. Every week, there&rsquo;s a new &ldquo;game-changing&rdquo;tool that promises to make you 10x more productive. But here’s the cold truth:the most successful developers I know aren&rsquo;t the ones who know the mostframeworks; they are the ones who understand the <strong>fundamentals</strong> so deeply thatthey can pick up any framework in a weekend.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/what-id-learn-if-starting-today-dev-career-advice_hu_119a4b1857525206.webp"alt="What I&#39;d Learn If Starting Today: A No-Nonsense Dev Career Roadmap."width="800"height="436"></div><figcaption><p class="figure__caption">What I&#39;d Learn If Starting Today: A No-Nonsense Dev Career Roadmap.</p></figcaption></figure><p>If I were starting today, this is exactly how I would navigate the path fromabsolute beginner to senior engineer.</p><h2 id="phase-1-learn-the-platform-not-the-abstractions">Phase 1: Learn the Platform, Not the Abstractions</h2><p>The biggest mistake I see juniors make today is the &ldquo;Framework Trap.&rdquo; They learn<strong>React</strong> before they understand <strong>JavaScript</strong>. They learn <strong>Tailwind</strong> beforethey understand <strong>CSS</strong>. They learn <strong>Next.js</strong> before they understand how abasic <strong>HTTP request</strong> works.</p><p>When you learn an abstraction first, you are building your career on sand. Whenthat framework inevitably falls out of favor, your skills go with it.</p><h3 id="the-fundamental-learning-stack">The Fundamental Learning Stack</h3><p>Before you even think about installing a package manager, you must master thesefive pillars:</p><ol><li><strong>Semantic HTML</strong>: Understand the <strong>document object model (DOM)</strong>,<strong>accessibility</strong> (ARIA roles), and why using a <code>&lt;button&gt;</code> is better than a<code>&lt;div&gt;</code> with an <code>onclick</code> handler.</li><li><strong>Modern CSS</strong>: Forget libraries for a moment. Master the <strong>Box Model</strong>,<strong>Flexbox</strong>, <strong>CSS Grid</strong>, and <strong>Custom Properties (CSS Variables)</strong>. If youcan&rsquo;t build a responsive layout with pure CSS, you aren&rsquo;t ready for<strong>Tailwind</strong>.</li><li><strong>Core JavaScript (ES6+)</strong>: You need to understand closures, prototypes,<strong>asynchronous programming</strong> (<code>async/await</code>), and functional programmingconcepts. Learn how the browser actually executes your code.</li><li><strong>Browser APIs</strong>: Spend time with the <strong>Fetch API</strong>, <strong>localStorage</strong>,<strong>Intersection Observer</strong>, and <strong>Web Workers</strong>. These are the tools thebrowser gives you for free.</li><li><strong>HTTP &amp; Networking</strong>: Understand status codes, headers, CORS, and thedifference between <strong>REST</strong> and <strong>GraphQL</strong>. Knowing <em>how</em> data moves acrossthe wire is more important than the library you use to fetch it.</li></ol><blockquote><p><strong>Common Pitfall: Tutorial Hell</strong> Many beginners fall into the trap ofwatching 50-hour courses and following along line-by-line. This gives you afalse sense of competence. You aren&rsquo;t learning to code; you&rsquo;re learning totranscribe. Break the cycle by building something unique every time you finisha module.</p></blockquote><h2 id="phase-2-the-first-project-architecture">Phase 2: The &ldquo;First Project&rdquo; Architecture</h2><p>Once you have the basics, don&rsquo;t build another Todo list. Build something thatsolves a real problem. If I were starting today, my first &ldquo;serious&rdquo; projectwould be a <strong>Personal Knowledge Base</strong> or a <strong>Custom CMS</strong>.</p><p><strong>Why?</strong> Because it forces you to handle:</p><ul><li><strong>Data Persistence</strong>: Connecting to a database (SQL or NoSQL).</li><li><strong>Authentication</strong>: Implementing secure login and sessions.</li><li><strong>CRUD Operations</strong>: Create, Read, Update, Delete.</li><li><strong>State Management</strong>: Managing complex data on the frontend.</li><li><strong>Deployment</strong>: Getting your code into the real world.</li></ul><h2 id="phase-3-version-control--collaboration">Phase 3: Version Control &amp; Collaboration</h2><p>I avoided <strong>Git</strong> for too long in my early years, thinking it was only forteams. That was a massive mistake. <strong>Git</strong> isn&rsquo;t just a backup tool; it&rsquo;s a<strong>time machine</strong> and a <strong>collaboration engine</strong>.</p><p>If you want to be a professional, you must be comfortable with the <strong>terminal</strong>.Learn how to:</p><ul><li>Branch, merge, and handle merge conflicts.</li><li>Write meaningful commit messages (e.g.,<a href="https://www.conventionalcommits.org/">Conventional Commits</a>).</li><li>Perform code reviews on GitHub/GitLab.</li><li>Use <code>git rebase</code> to keep your history clean.</li></ul><h2 id="phase-4-integrating-ai-the-2026-reality">Phase 4: Integrating AI (The 2026 Reality)</h2><p>We cannot talk about starting a dev career today without mentioning <strong>AI</strong>. In2026, <strong>AI</strong> is no longer a luxury; it&rsquo;s a standard part of the workflow.However, it is a double-edged sword.</p><p>As I&rsquo;ve written about previously, the goal is to use <strong>AI</strong> as a <strong>copilot</strong>,not the captain. If you use <strong>AI</strong> to write code you don&rsquo;t understand, youaren&rsquo;t a developer; you&rsquo;re a prompt engineer with a looming technical debtcrisis.</p><blockquote><p><strong>Pro Tip: The 15-Minute Rule</strong> When you hit a bug, spend exactly 15 minutestrying to solve it yourself by reading the docs and debugging. If you&rsquo;re stillstuck, use <strong>AI</strong> to explain the concept, not just give you the fix. Thisensures you&rsquo;re still growing your &ldquo;mental muscle.&rdquo;</p></blockquote><h2 id="the-career-roadmap-from-junior-to-lead">The Career Roadmap: From Junior to Lead</h2><p>Success in this industry isn&rsquo;t just about code. It&rsquo;s about how yourresponsibilities shift as you grow.</p><table><thead><tr><th style="text-align: left">Level</th><th style="text-align: left">Primary Focus</th><th style="text-align: left">Key Skill to Master</th><th style="text-align: left">Output</th></tr></thead><tbody><tr><td style="text-align: left"><strong>Junior</strong></td><td style="text-align: left">Syntax &amp; Implementation</td><td style="text-align: left">Reading Documentation</td><td style="text-align: left">Working code that follows instructions.</td></tr><tr><td style="text-align: left"><strong>Mid-Level</strong></td><td style="text-align: left">Architecture &amp; Patterns</td><td style="text-align: left">Testing &amp; Maintainability</td><td style="text-align: left">Scalable features with minimal bugs.</td></tr><tr><td style="text-align: left"><strong>Senior</strong></td><td style="text-align: left">Problem Solving &amp; Systems</td><td style="text-align: left">Communication &amp; Mentorship</td><td style="text-align: left">Technical direction and team productivity.</td></tr><tr><td style="text-align: left"><strong>Lead</strong></td><td style="text-align: left">Business Value &amp; Strategy</td><td style="text-align: left">Decision Making</td><td style="text-align: left">High-impact architectural and organizational changes.</td></tr></tbody></table><h2 id="the-business-of-code">The Business of Code</h2><p>This is the lesson that took me a decade to truly internalize: <strong>Code is aliability, not an asset.</strong></p><p>Companies don&rsquo;t pay you to write code; they pay you to solve problems. Sometimesthe best solution to a problem is <em>not</em> writing code at all. Understanding thebusiness context of your work—how it makes money, how it saves time, or how itreduces risk—will make you ten times more valuable than the best &ldquo;pure&rdquo; coder.</p><h2 id="soft-skills-the-secret-weapon">Soft Skills: The &ldquo;Secret&rdquo; Weapon</h2><p>Technical skills get you the interview. <strong>Soft Skills</strong> get you the job and thepromotion. In a world where <strong>AI</strong> can write a boilerplate <strong>React</strong> componentin seconds, your ability to <strong>communicate</strong>, <strong>empathize</strong>, and <strong>negotiate</strong> isyour moat.</p><ul><li><strong>Writing</strong>: Can you explain a complex bug in a Jira ticket? Can you write aclear README?</li><li><strong>Public Speaking</strong>: Can you demo your work to stakeholders?</li><li><strong>Empathy</strong>: Can you understand why a designer is frustrated with yourimplementation?</li><li><strong>Reliability</strong>: Do you do what you say you&rsquo;re going to do?</li></ul><h2 id="dont-chase-trends">Don&rsquo;t Chase Trends</h2><p>I&rsquo;ve watched jQuery, Backbone, Angular, and countless others rise and fall. Ifyou chase every trend, you will burn out.</p><p>Instead, adopt the <strong>80/20 Rule for Learning</strong>:</p><ul><li>Spend <strong>80%</strong> of your time mastering established, &ldquo;boring&rdquo; technologies(<strong>SQL</strong>, <strong>Bash</strong>, <strong>vanilla JS</strong>, <strong>CSS</strong>, <strong>Docker</strong>).</li><li>Spend <strong>20%</strong> of your time playing with the new shiny stuff (new frameworks,<strong>AI</strong> agents, etc.).</li></ul><h2 id="the-advice-i-wish-id-followed">The Advice I Wish I&rsquo;d Followed</h2><ol><li><strong>Write about what you learn</strong>: Teaching is the highest form of learning.Start a blog on day one.</li><li><strong>Contribute to Open Source</strong>: Don&rsquo;t start with code. Start withdocumentation or fixing typos. It teaches you how professional repositoriesare managed.</li><li><strong>Take care of your health</strong>: This is a sedentary job. If you don&rsquo;t scheduletime for movement, your back and wrists will remind you in ten years.</li><li><strong>Save your &ldquo;F-you&rdquo; money</strong>: Freelancing and tech jobs can be volatile.Having a financial buffer gives you the freedom to say &ldquo;no&rdquo; to toxicprojects.</li></ol><h2 id="conclusion">Conclusion</h2><p>If you&rsquo;re starting today, the mountain might look insurmountable. The stack istaller, the competition is global, and the tools are more complex. But thereward for those who focus on the <strong>fundamentals</strong> remains higher than ever.</p><p>The specific technologies will change—they always do. But the ability to learn,solve problems, and communicate effectively will serve you for decades. Stoplooking for the perfect tutorial and start building something that breaks.That’s where the real learning happens.</p><p>The best time to start was twenty years ago. The second best time is now. <strong>Getto work.</strong></p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Quora: The Knowledge-Sharing Platform That Still Matters</title><link>https://valticus.pro/posts/quora-the-knowledge-sharing-platform/</link><pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/quora-the-knowledge-sharing-platform/</guid><description>Discover why Quora remains a valuable resource for knowledge sharing, how to leverage it for learning and growth, and why it's still relevant in 2026.</description><category>Technology</category><content:encoded><p>In an era dominated by short-form video and algorithmic feeds, Quora stands as abeacon for those who crave in-depth knowledge and thoughtful discussion. Foundedin 2009 by former Facebook employees Adam D&rsquo;Angelo and Charlie Cheever, Quorahas evolved into one of the internet&rsquo;s most comprehensive Q&amp;A platforms.</p><h2 id="what-makes-quora-special">What Makes Quora Special?</h2><p>Quora&rsquo;s strength lies in its commitment to quality answers. Unlike social mediaplatforms optimized for engagement, Quora prioritizes expertise and depth. Userscan ask questions on virtually any topic—from programming and science tophilosophy and personal development—and receive answers from knowledgeablecontributors, including verified experts and industry professionals.</p><p>The platform&rsquo;s upvote system ensures that the most helpful answers rise to thetop, creating a self-curated knowledge base that grows richer over time. Fordevelopers and tech enthusiasts, Quora offers invaluable insights into careeradvice, coding challenges, and industry trends.</p><h2 id="quora-for-learning-and-growth">Quora for Learning and Growth</h2><p>One of Quora&rsquo;s most underappreciated features is its potential for continuouslearning. By following topics aligned with your interests, you create apersonalized feed of high-quality content. Whether you&rsquo;re exploring newprogramming languages, understanding system design patterns, or diving intobusiness strategy, Quora provides diverse perspectives that textbooks simplycan&rsquo;t match.</p><p>The platform also allows you to build a presence by sharing your expertise. Ifyou have deep knowledge in a particular area, answering questions on Quora canestablish you as a thought leader while helping others.</p><h2 id="my-quora-journey">My Quora Journey</h2><p>I&rsquo;ve found Quora to be an excellent space for sharing thoughts on technology,development practices, and the broader tech landscape. You can follow mycontributions and explore the topics I cover on my<a href="https://valticus.quora.com/">Quora blog</a>.</p><h2 id="why-quora-still-matters-in-2026">Why Quora Still Matters in 2026</h2><p>Despite the rise of AI-generated answers and social media alternatives, Quoraremains relevant because it fosters genuine human expertise. The platform&rsquo;sevolution—including Quora+ and Spaces—has added new dimensions to contentcreation and community building while maintaining its core mission of sharingknowledge.</p><p>For anyone serious about learning, growing their expertise, or connecting withlike-minded professionals, Quora deserves a place in your digital toolkit.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Minimalist Development Workflow: My Experience and Insights</title><link>https://valticus.pro/posts/minimalist-development-workflow-my-experience-and-insights/</link><pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/minimalist-development-workflow-my-experience-and-insights/</guid><description>A personal account of adopting a minimalist approach to development workflows, exploring the benefits, challenges, and practical strategies for reducing complexity without sacrificing productivity.</description><category>Web Development</category><content:encoded><p>After twenty years in web development, I&rsquo;ve realized that the most dangerousthing in our industry isn&rsquo;t a security vulnerability or a system outage—it&rsquo;s<strong>creeping complexity</strong>. We are conditioned to believe that a more sophisticatedsetup equals a more professional output. We stack layers of abstraction until wecan no longer see the foundation of our own applications.</p><p>I spent the first decade of my career as a &ldquo;maximalist.&rdquo; I wanted the flashiestIDE, the most complex build pipelines, and the latest alpha-version frameworks.But eventually, the weight of that tooling became a burden. I was spending 40%of my time fighting my environment rather than shipping code.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/minimalist-development-workflow-my-experience-and-insights_hu_44c6f909c36cf879.webp"alt="Minimalist Development Workflow: My Experience and Insights."width="800"height="436"></div><figcaption><p class="figure__caption">Minimalist Development Workflow: My Experience and Insights.</p></figcaption></figure><p>Now? I pride myself on how little I need to get the job done. This is my journeytoward a <strong>Minimalist Development Workflow</strong>.</p><h2 id="the-breaking-point-complexity-debt">The Breaking Point: Complexity Debt</h2><p>The realization hit me during a routine update. A simple project with a dozenpages required a <code>npm install</code> that downloaded 800MB of dependencies andtriggered three different security warnings in libraries I didn&rsquo;t even know Iwas using.</p><p>My &ldquo;productivity&rdquo; had become a facade. I was paying <strong>Complexity Debt</strong> everysingle day:</p><ul><li><strong>Build Times</strong>: Waiting 60 seconds for a &ldquo;hot reload&rdquo; of a CSS change.</li><li><strong>Onboarding</strong>: Taking two days to explain the environment to a new developer.</li><li><strong>Maintenance</strong>: Spending weekends fixing breaking changes in a framework thatI didn&rsquo;t really need.</li></ul><p>I decided to burn it down and start from the fundamentals.</p><h2 id="the-boring-technology-philosophy">The &ldquo;Boring Technology&rdquo; Philosophy</h2><p>I adopted the &ldquo;<strong>Boring Technology</strong>&rdquo; mindset. Boring technology is reliable.Its edge cases are known. It doesn&rsquo;t change its API every six months. For aminimalist workflow, boring is beautiful.</p><h3 id="what-i-kept-the-essentials">What I Kept (The Essentials)</h3><ol><li><strong>The Editor</strong>: VS Code, but stripped to the bone. No &ldquo;AI Autocomplete&rdquo; thatguesses wrong 40% of the time. No 15-extension &ldquo;Pack for React Developers.&rdquo;Just a good mono font, a fast terminal, and built-in Git support.</li><li><strong>The Stack</strong>: Whenever possible, I return to the &ldquo;Holy Trinity&rdquo;: <strong>SemanticHTML</strong>, <strong>Modern CSS</strong>, and <strong>Vanilla JavaScript</strong>.</li><li><strong>The Static Engine</strong>: I use <strong>Hugo</strong> for almost everything. It&rsquo;s a singlebinary, it&rsquo;s written in <strong>Go</strong>, and it builds 5,000 pages in under a second.No <code>node_modules</code> required for the core engine.</li></ol><h2 id="replacing-complex-tools-with-simple-scripts">Replacing Complex Tools with Simple Scripts</h2><p>The biggest win in my minimalist transition was replacing &ldquo;Task Runners&rdquo; (Gulp,Grunt, and even complex npm scripts) with a tool that has been around since1976: <strong>The Makefile</strong>.</p><p>A <code>Makefile</code> is transparent, fast, and doesn&rsquo;t require a runtime. It serves asthe &ldquo;source of truth&rdquo; for how to build and deploy your project.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" ><span class="line"><span class="cl"><span class="c"># Minimalist Development Workflow Makefile</span></span></span><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">help</span> <span class="n">dev</span> <span class="n">build</span> <span class="n">deploy</span> <span class="n">clean</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nf">help</span><span class="o">:</span> <span class="c">## Show this help message</span></span></span><span class="line"><span class="cl"> @grep -E <span class="s1">&#39;^[a-zA-Z_-]+:.*?## .*$$&#39;</span> <span class="k">$(</span>MAKEFILE_LIST<span class="k">)</span> <span class="p">|</span> sort <span class="p">|</span> awk <span class="s1">&#39;BEGIN {FS = &#34;:.*?## &#34;}; {printf &#34;\033[36m%-15s\033[0m %s\n&#34;, $$1, $$2}&#39;</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nf">dev</span><span class="o">:</span> <span class="c">## Start Hugo development server</span></span></span><span class="line"><span class="cl"> hugo server -D -E -F --minify</span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nf">build</span><span class="o">:</span> <span class="c">## Build the production site</span></span></span><span class="line"><span class="cl"> rm -rf public</span></span><span class="line"><span class="cl"> hugo --gc --minify</span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nf">deploy</span><span class="o">:</span> <span class="n">build</span> <span class="c">## Deploy to production via Netlify</span></span></span><span class="line"><span class="cl"> npx netlify-cli deploy --prod --dir<span class="o">=</span>public</span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span> <span class="c">## Remove build artifacts</span></span></span><span class="line"><span class="cl"> rm -rf public resources</span></span></code></pre></div><p>By using this, I don&rsquo;t need to remember 20 different CLI flags. I just type<code>make dev</code> or <code>make deploy</code>. It&rsquo;s portable, version-controlled, and requireszero configuration on a new machine.</p><h2 id="what-i-dropped-and-why">What I Dropped (And Why)</h2><h3 id="1-the-big-three-frameworks">1. The &ldquo;Big Three&rdquo; Frameworks</h3><p>Unless I&rsquo;m building a highly dynamic, state-heavy dashboard, I don&rsquo;t use React,Vue, or Angular. Most websites are content, and content doesn&rsquo;t need a <strong>virtualDOM</strong>. It needs a fast server and a browser.</p><h3 id="2-utility-first-css-frameworks">2. Utility-First CSS Frameworks</h3><p>While I appreciate the speed of Tailwind, I&rsquo;ve returned to <strong>Vanilla CSS withCustom Properties</strong>. Modern CSS (<strong>Grid</strong>, <strong>Flexbox</strong>, <strong>Containers</strong>) has madeframeworks largely redundant for those who actually know the language.</p><h3 id="3-heavy-ides">3. &ldquo;Heavy&rdquo; IDES</h3><p>I moved away from heavy, RAM-hungry IDEs. If I can&rsquo;t run my developmentenvironment on a 5-year-old laptop without the fans spinning up, my workflow istoo heavy. This ties back to my philosophy on digital minimalism for developers,where I discuss the mental impact of digital clutter.</p><blockquote><h3 id="-common-pitfall-not-invented-here-nih">🚩 Common Pitfall: &ldquo;Not Invented Here&rdquo; (NIH)</h3><p>Minimalists often fall into the trap of wanting to build everything fromscratch. This can lead to its own kind of complexity. The goal isn&rsquo;t to writeyour own database; it&rsquo;s to avoid installing a database when a JSON file willdo.</p></blockquote><h2 id="the-minimalist-project-checklist">The Minimalist Project Checklist</h2><p>Before starting a new project, I run it through this &ldquo;Pruning Filter&rdquo;:</p><ul><li><input disabled="" type="checkbox"> <strong>Can this be static?</strong> If yes, no server-side code.</li><li><input disabled="" type="checkbox"> <strong>Does it need JS?</strong> If the interaction can be done with HTML/CSS (like atoggle menu), skip the JS.</li><li><input disabled="" type="checkbox"> <strong>Single Binary Rule</strong>: Can I build this using only tools that are singlebinaries (like Hugo, Go, or Rust tools)?</li><li><input disabled="" type="checkbox"> <strong>Zero-Config Onboarding</strong>: Can a developer clone this and run it with onecommand (e.g., <code>make dev</code>)?</li><li><input disabled="" type="checkbox"> <strong>No-Build CSS</strong>: Can I use standard CSS files without a pre-processor?</li></ul><h2 id="the-benefits-of-less">The Benefits of Less</h2><h3 id="instant-context-re-entry">Instant Context Re-entry</h3><p>When I return to a project after six months, I don&rsquo;t have to spend an hourupdating dependencies or remembering how the &ldquo;Magic Build Tool&rdquo; works. The codeis just code.</p><h3 id="faster-feedback-loops">Faster Feedback Loops</h3><p>My build time is usually under 500ms. This instant feedback allows me to enter a<strong>Flow State</strong> that is impossible when you&rsquo;re constantly waiting for atranspiler to finish.</p><h3 id="improved-security">Improved Security</h3><p>Every dependency you <em>don&rsquo;t</em> install is a <strong>supply-chain attack</strong> that <em>can&rsquo;t</em>happen to you. Minimalism is the ultimate security architecture.</p><h2 id="conclusion">Conclusion</h2><p>A minimalist workflow isn&rsquo;t about being a Luddite or hating progress. It&rsquo;s about<strong>respecting your own time</strong>. It&rsquo;s about choosing tools that serve you, ratherthan tools that require you to serve them.</p><p>By stripping away the noise, you reveal the signal. You&rsquo;ll find that you writebetter code, understand your systems deeper, and—most importantly—you&rsquo;ll spendmore time solving real problems and less time tweaking your configuration files.</p><p><strong>Take a look at your current project. What is the one dependency you couldremove today and still deliver the same value? Try it.</strong></p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Why Frameworks Are Overused (And How to Avoid It)</title><link>https://valticus.pro/posts/why-frameworks-are-overused-and-how-to-avoid-it/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/why-frameworks-are-overused-and-how-to-avoid-it/</guid><description>A critical look at the 'Framework-First' mentality in modern web development. Learn when to reach for a library and when to stick to the fundamentals for better performance and maintainability.</description><category>Web Development</category><content:encoded><h2 id="the-framework-first-fallacy">The Framework-First Fallacy</h2><p>In the landscape of 2026, the default response to almost any web developmentproject is to start with a framework. Need a personal landing page? Reach forNext.js. Building a simple data dashboard? Boot up a React template. Creating adocumentation site? Gatsby or Nuxt is the presumed choice.</p><p>We have reached a point where many developers—especially those who entered theindustry in the last five years—literally cannot build a website without firstinstalling a framework. This isn&rsquo;t just a shift in preference; it&rsquo;s a<strong>Framework-First Fallacy</strong> that prioritizes the developer&rsquo;s comfort over theuser&rsquo;s experience and the project&rsquo;s long-term health.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/why-frameworks-are-overused-and-how-to-avoid-it_hu_eae461301fe9faf6.webp"alt="Why Frameworks Are Overused (And How to Avoid It)."width="800"height="436"></div><figcaption><p class="figure__caption">Why Frameworks Are Overused (And How to Avoid It).</p></figcaption></figure><h2 id="the-hidden-costs-of-abstraction">The Hidden Costs of Abstraction</h2><p>While frameworks promise speed and consistency, they come with a significant&ldquo;<strong>Abstraction Tax</strong>&rdquo; that is rarely discussed in the hype-filled world of techsocial media and YouTube tutorials.</p><h3 id="1-the-bundle-size-reality-check">1. The Bundle Size Reality Check</h3><p>Let&rsquo;s look at the math for a &ldquo;simple&rdquo; interactive site in 2026. If you use amodern meta-framework, your baseline might look like this:</p><ul><li><strong>Framework Core (React/Vue/Angular):</strong> ~45KB - 130KB <strong>gzipped</strong></li><li><strong>Hydration Logic:</strong> ~20KB - 50KB</li><li><strong>Routing &amp; State Management:</strong> ~30KB</li><li><strong>UI Component Library (Radix, HeadlessUI, etc.):</strong> ~40KB</li><li><strong>Your Actual Business Logic:</strong> ~15KB</li></ul><p>In this scenario, you are shipping nearly 300KB of JavaScript to the user justto deliver 15KB of unique functionality. On a high-speed fiber connection, thismight feel negligible. But on a spotty 4G connection or an entry-level mobiledevice, that 300KB represents a multi-second delay in <strong>Time to Interactive(TTI)</strong>. We are essentially forcing the user to download and execute a massiveengine just to move a few pixels.</p><h3 id="2-the-learning-curve-trap">2. The Learning Curve Trap</h3><p>Frameworks don&rsquo;t just require you to learn JavaScript; they require you to learna dialect of it. You aren&rsquo;t just learning how to manipulate the DOM; you&rsquo;relearning about &ldquo;<strong>Hooks</strong>,&rdquo; &ldquo;<strong>Signals</strong>,&rdquo; &ldquo;<strong>Observables</strong>,&rdquo; or &ldquo;<strong>VirtualDOM</strong> reconciliation.&rdquo;</p><p>By the time a developer masters the specific idioms of Framework A, Framework Bhas been released with a &ldquo;revolutionary&rdquo; new paradigm that makes Framework Alook antiquated. This creates a cycle of <strong>Perpetual Relearning</strong> that stealstime away from mastering the fundamental technologies (HTML, CSS, <strong>BrowserAPIs</strong>) that have remained stable for decades.</p><h3 id="3-dependency-hell-and-maintenance-rot">3. Dependency Hell and Maintenance Rot</h3><p>Modern framework projects don&rsquo;t just have dependencies; they have ecosystems. Asimple <code>npm install</code> today can result in 2,000+ folders in your<strong><code>node_modules</code></strong>.</p><p>This creates a massive surface area for:</p><ul><li><strong>Security Vulnerabilities</strong>: Every transitive dependency is a potential entrypoint.</li><li><strong>Breaking Changes</strong>: A minor update in a sub-dependency can break your entirebuild pipeline.</li><li><strong>Maintenance Rot</strong>: Try opening a framework project from three years ago andrunning it. The odds of it &ldquo;just working&rdquo; are near zero.</li></ul><h2 id="the-framework-necessity-test">The Framework Necessity Test</h2><p>Before you run <code>npx create-...</code>, put your project through this checklist. If youcan&rsquo;t check at least three boxes, you probably don&rsquo;t need a framework.</p><ul><li><input disabled="" type="checkbox"> Does the application have highly dynamic, synchronized state acrossmultiple UI components?</li><li><input disabled="" type="checkbox"> Is the project being built by a team of 10+ developers who need strictarchitectural guardrails?</li><li><input disabled="" type="checkbox"> Does the UI require complex, real-time updates (e.g., a collaborativeeditor or a high-frequency trading dashboard)?</li><li><input disabled="" type="checkbox"> Are you building a &ldquo;<strong>Single Page Application</strong>&rdquo; (<strong>SPA</strong>) wherenavigation must happen without full page reloads for a specific UX reason?</li><li><input disabled="" type="checkbox"> Do you need to leverage a specific, massive ecosystem of pre-builtcomponents that would take months to build from scratch?</li></ul><h2 id="comparison-vanilla-vs-framework-the-modal-example">Comparison: Vanilla vs. Framework (The Modal Example)</h2><p>To illustrate the point, let&rsquo;s look at how we might build a simple modal.</p><p><strong>The &ldquo;Modern Framework&rdquo; Way:</strong> You import a Modal component, a Portal, a Statehook, and probably an animation library. You write 50 lines of code, but you&rsquo;veadded 4 dependencies and 80KB to your bundle.</p><p><strong>The &ldquo;Platform&rdquo; Way (Vanilla JS):</strong></p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" ><span class="line"><span class="cl"><span class="c1">// A modal in 2026 using the native &lt;dialog&gt; element</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">modal</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">&#34;#myModal&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">openBtn</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">&#34;#openModal&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">closeBtn</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">&#34;#closeModal&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nx">openBtn</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&#34;click&#34;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="nx">modal</span><span class="p">.</span><span class="nx">showModal</span><span class="p">());</span></span></span><span class="line"><span class="cl"><span class="nx">closeBtn</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&#34;click&#34;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="nx">modal</span><span class="p">.</span><span class="nx">close</span><span class="p">());</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">// Simple, performant, and requires ZERO dependencies.</span></span></span></code></pre></div><p>By using the<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog">native <strong><code>&lt;dialog&gt;</code> element</strong></a>,you get accessibility (focus trapping, ESC key to close) for free, with zerobundle size impact.</p><h2 id="the-progressive-enhancement-approach">The Progressive Enhancement Approach</h2><p>The alternative to &ldquo;Framework-First&rdquo; is <strong>Progressive Enhancement</strong>. It&rsquo;s aphilosophy that has guided the web since its inception, yet it feelsrevolutionary in the current climate.</p><ol><li><strong>Content First (HTML):</strong> Start with the <strong>semantic structure</strong>. Does thesite work if JavaScript is disabled? It should.</li><li><strong>Presentation (CSS):</strong> Layer on the design. Modern CSS (Grid, <strong>ContainerQueries</strong>, Layers) can handle 90% of the layouts that used to requireJS-heavy libraries.</li><li><strong>Enhancement (JS):</strong> Add interactivity. Use <strong>Vanilla JS</strong> for simplethings. If a specific section of the page (like a complex filter or ashopping cart) needs heavy state management, use a &ldquo;<strong>micro-framework</strong>&rdquo; like<strong>Alpine.js</strong> or Petite-Vue only for that specific area.</li></ol><p>We need to stop treating frameworks as the foundation and start treating them asthe <em>accessory</em>.</p><h2 id="when-frameworks-actually-make-sense">When Frameworks Actually Make Sense</h2><p>Lest I be accused of being a luddite: frameworks <em>do</em> have a place. If you arebuilding <strong>Spotify</strong>, <strong>Figma</strong>, or <strong>Discord</strong>, a framework isn&rsquo;t justhelpful—it&rsquo;s essential. These are applications where the state is so complex andthe interactions so dense that managing them with <strong>Vanilla JS</strong> would be anexercise in masochism.</p><p>The problem isn&rsquo;t that frameworks exist; it&rsquo;s that we use them for<strong>everything</strong>. We are using a sledgehammer to hang a picture frame.</p><blockquote><p><strong>Pro Tip: The 80/20 Rule of Tooling</strong> 80% of the web consists ofcontent-heavy sites (blogs, portfolios, documentation, marketing pages). 20%consists of complex &ldquo;App-like&rdquo; experiences. If you are in the 80%, you shouldprioritize <strong>Static Site Generators</strong> (like <strong>Hugo</strong>) and <strong>Vanilla JS</strong>. Savethe heavy frameworks for the remaining 20%.</p></blockquote><h2 id="the-sustainability-argument">The Sustainability Argument</h2><p>There is also a human and environmental cost to framework churn.</p><ul><li><strong>Mental Health:</strong> The pressure to stay &ldquo;current&rdquo; with every framework updatecontributes significantly to developer burnout.</li><li><strong>Environmental Impact:</strong> Shipping megabytes of unnecessary JS across theglobe every second consumes massive amounts of energy. A &ldquo;light&rdquo; web is agreener web.</li><li><strong>Accessibility:</strong> Framework-heavy sites often fail the &ldquo;low-end device&rdquo; test,effectively gatekeeping information from users who can&rsquo;t afford the latestiPhone.</li></ul><h2 id="conclusion">Conclusion</h2><p>The next time you start a project, I challenge you to <strong>not</strong> install aframework. Try to see how far you can get with just HTML, CSS, and a sprinkle of<strong>Vanilla JavaScript</strong>. You&rsquo;ll likely find that not only is it possible, but theresulting site is faster, easier to maintain, and more satisfying to build.</p><p>Learn the platform before you learn the abstraction. The framework you learntoday will be gone in five years, but the <strong>browser APIs</strong> you learn today willserve you for the rest of your career.</p><hr><p><em>As I argued in my comparison of static sites versus WordPress, I&rsquo;ve broken downwhy simple is often better for your next project&rsquo;s architecture.</em></p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>AI for Developers: A Practical Guide to Getting Started</title><link>https://valticus.pro/posts/ai-for-developers-a-practical-guide-to-getting-started/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/ai-for-developers-a-practical-guide-to-getting-started/</guid><description>A hands-on guide to integrating AI tools and services into your development workflow, from code assistance to automated testing and intelligent debugging.</description><category>Web Development</category><content:encoded><h2 id="ai-has-entered-the-building">AI Has Entered the Building</h2><p>In 2026, the question is no longer &ldquo;Will AI change software development?&rdquo; but&ldquo;How effectively are you using it?&rdquo; AI tools have moved from experimentalnovelties to indispensable force multipliers. However, the sheer volume oftools—<strong>LLMs</strong>, <strong>IDE extensions</strong>, <strong>CLI wrappers</strong>, and <strong>autonomousagents</strong>—has created a paradox of choice.</p><p>This guide isn&rsquo;t about the hype. It’s a pragmatic look at the current AI stackfor developers, how to build a workflow that actually saves time, and where the&ldquo;hidden costs&rdquo; of AI adoption lie.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/ai-for-developers-a-practical-guide-to-getting-started_hu_cc39ef3715a93792.webp"alt="AI for Developers: A Practical Guide to Getting Started."width="800"height="436"></div><figcaption><p class="figure__caption">AI for Developers: A Practical Guide to Getting Started.</p></figcaption></figure><h2 id="the-developers-ai-stack">The Developer&rsquo;s AI Stack</h2><p>To get started, you need to understand the three layers of the modern AIdeveloper stack: <strong>Models</strong>, <strong>Interfaces</strong>, and <strong>Context</strong>.</p><h3 id="1-the-models-the-brains">1. The Models (The Brains)</h3><p>Not all LLMs are created equal. Some excel at creative writing, while others arefine-tuned for the rigid syntax of code.</p><table><thead><tr><th>Model</th><th>Strengths</th><th>Best For</th></tr></thead><tbody><tr><td><strong>Claude 3.5 Sonnet</strong></td><td>Exceptional reasoning, follows complex instructions</td><td>Complex refactoring, architectural advice</td></tr><tr><td><strong>GPT-4o</strong></td><td>Fast, great at boilerplate and common patterns</td><td>Day-to-day coding, unit tests</td></tr><tr><td><strong>DeepSeek Coder</strong></td><td>Open-weights, highly specialized for code</td><td>Self-hosting, privacy-conscious tasks</td></tr><tr><td><strong>Llama 3 (70B+)</strong></td><td>Versatile, great general knowledge</td><td>Documentation, explaining concepts</td></tr></tbody></table><h3 id="2-the-interfaces-the-hands">2. The Interfaces (The Hands)</h3><p>How you interact with these models determines your friction level.</p><ul><li><strong>AI-Native Editors (e.g., Cursor)</strong>: These are forks of VS Code that have AIbaked into the core. They can &ldquo;see&rdquo; your entire codebase, not just the fileyou&rsquo;re working on.</li><li><strong>Extensions (e.g., GitHub Copilot, Codeium)</strong>: Plugins for your existingeditor. Great for autocomplete but often lack the deep context of nativeeditors.</li><li><strong>CLI Tools (e.g., Aider, Gemini CLI)</strong>: For those who live in the terminal.These can perform multi-file edits and git commits directly from a prompt.</li></ul><h3 id="3-the-context-the-memory">3. The Context (The Memory)</h3><p>The secret sauce of AI productivity is <strong>RAG (Retrieval-Augmented Generation)</strong>.The more context you provide—your project structure, documentation, and codingstandards—the more accurate the AI becomes.</p><h2 id="prompt-engineering-the-new-syntax">Prompt Engineering: The New Syntax</h2><p>Writing a prompt is like writing a specification. If your spec is vague, theimplementation will be buggy.</p><p><strong>Common Pitfall: The &ldquo;One-Liner&rdquo; Prompt</strong> Don&rsquo;t just ask: <em>&ldquo;Write a React logincomponent.&rdquo;</em> You&rsquo;ll get a generic, inaccessible component that uses librariesyou don&rsquo;t want.</p><p><strong>The &ldquo;Pro&rdquo; Prompt Pattern:</strong> Use the <strong>Role-Context-Task-Constraint</strong>framework:</p><ul><li><strong>Role</strong>: &ldquo;You are a senior React developer specializing in accessibility.&rdquo;</li><li><strong>Context</strong>: &ldquo;We are using <strong>Tailwind CSS</strong> and <strong>React Hook Form</strong>.&rdquo;</li><li><strong>Task</strong>: &ldquo;Create a login form with email and password fields.&rdquo;</li><li><strong>Constraints</strong>: &ldquo;Must be WCAG 2.1 AA compliant, use semantic HTML, andinclude client-side validation.&rdquo;</li></ul><p><strong>Pro Tip: Local LLMs for Privacy</strong> If you&rsquo;re working on sensitive orproprietary code, use <strong>Ollama</strong> or <strong>LM Studio</strong>. You can run models likeDeepSeek Coder or Llama 3 entirely offline on your local machine (assuming youhave a decent GPU or Apple Silicon M-series chip). This ensures your code neverleaves your network.</p><h2 id="ai-native-vs-ai-augmented-workflows">AI-Native vs. AI-Augmented Workflows</h2><h3 id="the-augmented-workflow-reactive">The Augmented Workflow (Reactive)</h3><p>You write code, and the AI suggests the next 10 lines. This is great forboilerplate, but it can lead to &ldquo;autopilot coding&rdquo; where you accept suggestionswithout fully understanding them.</p><h3 id="the-ai-native-workflow-proactive">The AI-Native Workflow (Proactive)</h3><p>You describe the feature or the bug to the AI. The AI scans your files, proposesa multi-file change, and you <strong>review</strong> and <strong>test</strong> the output. This shiftsyour role from &ldquo;Typewriter&rdquo; to &ldquo;Editor.&rdquo;</p><h3 id="example-refactoring-technical-debt">Example: Refactoring Technical Debt</h3><p>AI is surprisingly good at &ldquo;un-spaghettifying&rdquo; code. <em>Prompt:</em> &ldquo;Analyze this500-line function. Identify three ways to break it into smaller, testablemodules following the <strong>Single Responsibility Principle</strong>. Provide therefactored code and unit tests for each new module.&rdquo;</p><h2 id="the-junior-developer-trap">The &ldquo;Junior Developer&rdquo; Trap</h2><p>There is a significant danger for developers starting their careers today:over-reliance. If you use AI to solve every problem before you understand theunderlying concepts, you&rsquo;re building your career on a foundation of sand.</p><p>AI often hallucinates or provides outdated solutions. For instance, in my&ldquo;Accessibility Is Still Broken&rdquo; post, I discuss how automated tools (includingAI) often fail to understand the nuance of focus management and screen readercontext.</p><h2 id="security-privacy-and-intellectual-property">Security, Privacy, and Intellectual Property</h2><p>Before you paste your company&rsquo;s API secrets into a web chat, remember:</p><ul><li><strong>Data Leakage</strong>: Most consumer-grade AI tools use your inputs to train futuremodels unless you opt-out or use Enterprise versions.</li><li><strong>Vulnerabilities</strong>: AI can (and does) suggest code with known security flaws.Always run a <strong>SAST (Static Application Security Testing)</strong> tool like <strong>Snyk</strong>or <strong>SonarQube</strong> on AI-generated code.</li><li><strong>Licensing</strong>: The legal landscape around AI-generated code is still evolving.Ensure your company&rsquo;s policy allows for AI usage and understand that you areultimately responsible for the code you commit.</li></ul><h2 id="realistic-productivity-gains">Realistic Productivity Gains</h2><p>Don&rsquo;t believe the &ldquo;10x developer&rdquo; marketing. Here’s what you can actuallyexpect:</p><ul><li><strong>Boilerplate</strong>: 80% time reduction (<strong>CRUD</strong>, <strong>DTOs</strong>, Unit tests).</li><li><strong>Learning New Tech</strong>: 50% faster (explaining syntax, generating hello-worldexamples).</li><li><strong>Debugging</strong>: 30% faster (summarizing logs, identifying common errors).</li><li><strong>Architecture</strong>: 10% gain (mostly as a sounding board).</li></ul><h2 id="conclusion">Conclusion</h2><p>AI for developers isn&rsquo;t about replacing the act of thinking; it&rsquo;s about removingthe friction of execution. The goal is to spend less time fighting with syntaxand more time solving business problems.</p><p>Start by picking an AI-native editor like <strong>Cursor</strong>, learn the art of themulti-file prompt, and always—<strong>always</strong>—remain the final authority on the codeyou ship. The best developers in 2026 aren&rsquo;t the ones who type the fastest;they&rsquo;re the ones who can most effectively orchestrate the AI tools at theirdisposal.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Dark Mode vs Light Mode: Design Systems for Code Editors</title><link>https://valticus.pro/posts/dark-mode-vs-light-mode-design-systems-for-code-editors/</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/dark-mode-vs-light-mode-design-systems-for-code-editors/</guid><description>Why the dark mode vs light mode debate is a false dichotomy—and how adaptive theming beats picking a side.</description><category>Technology</category><content:encoded><p>The dark mode versus light mode debate is a false dichotomy. Picking one themeand sticking with it forever ignores how your eyes, environment, and tasksactually work. The real answer is <strong>adaptive theming</strong>: an editor design systemthat shifts its contrast, saturation, and color palette based on context.</p><p>A 2023 survey by JetBrains found that 82% of developers prefer dark themes, but93% of those same developers admitted they occasionally switch to a light themedepending on lighting conditions. That is not indecision. It is a signal thatone theme cannot cover every scenario.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/dark-mode-vs-light-mode-design-systems-for-code-editors_hu_3ac48a8b7442746c.webp"alt="Dark Mode vs Light Mode: Design Systems for Code Editors."width="800"height="436"></div><figcaption><p class="figure__caption">Dark Mode vs Light Mode: Design Systems for Code Editors.</p></figcaption></figure><p>This is not about aesthetics. It is about cognitive load, accessibility, andproductivity. And the best part? You do not need to wait for IDE vendors tobuild it. You can do it today in both VS Code and Neovim.</p><h2 id="the-problem-with-picking-a-side">The Problem with Picking a Side</h2><p>Dark mode advocates are not wrong—they are just context-blind.</p><p>A dark theme genuinely helps in low-light conditions, reduces glare, and savesbattery on OLED screens. That is why every developer tool defaults to it. Butthe same theme that makes code pop at midnight washes out syntax highlighting atnoon and turns into a reflective mess near a window.</p><p>Research on visual fatigue shows that prolonged exposure to high-contrast darkmode can increase eye strain for people with astigmatism—a condition affectingroughly 33% of the population. The halation effect (blurred edges around brighttext on dark backgrounds) forces the eyes to work harder to focus. Light modeavoids this but introduces its own problems: harsh brightness in dark rooms andlower perceived contrast for certain color pairs.</p><p>Light mode has its strengths: superior contrast for complex syntax, betterreadability in bright environments, and easier prolonged reading for people withvision conditions like astigmatism or presbyopia. But it is punishing in a darkroom and feels sterile after hours of deep work.</p><p>The problem is not which theme is &ldquo;better.&rdquo; It is that <strong>one theme cannot adaptto all conditions</strong>, and choosing a side means accepting those trade-offspermanently.</p><h2 id="what-adaptive-theming-actually-means">What Adaptive Theming Actually Means</h2><p>Most developers stop at &ldquo;dark theme during the day, light theme at night&rdquo;reversal. That is a start, but it is not a design system.</p><p>A proper editor design system adjusts to three variables:</p><ul><li><strong>Time of day</strong>: Your eyes adapt to ambient light. A theme that works at 2 PMwill not work at 2 AM. Circadian rhythm affects color perception—warm tones atnight reduce melatonin suppression, while cool blue light in the morningsupports alertness.</li><li><strong>Task type</strong>: Reading documentation needs different contrast ratios thanwriting new code. Debugging needs different color cues than refactoring. Adiff view should not use the same palette as your main editor.</li><li><strong>Environment</strong>: The same theme looks completely different on a laptop displayversus an external monitor versus a projector. A theme calibrated on a MacBookPro&rsquo;s XDR display will look muddy on a budget external panel.</li></ul><p>Adaptive theming takes automatic theme switching further. Instead of justflipping between two color schemes, the editor adjusts the entire visualsystem—contrast curve, saturation levels, syntax highlight palette, even UIchrome opacity—based on context.</p><h2 id="adaptive-theming-in-vs-code">Adaptive Theming in VS Code</h2><p>VS Code has excellent extension support for theme switching. The approach breaksdown into three layers:</p><h3 id="layer-1-time-based-switching">Layer 1: Time-Based Switching</h3><p>The simplest layer uses extensions like<a href="https://marketplace.visualstudio.com/items?itemName=savioserra.theme-switcher">Theme Switcher</a>or<a href="https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme">Auto Theme</a>to rotate themes at set hours. I covered the basics previously, but here is arefined configuration:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" ><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;auto-theme.timezone&#34;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;auto-theme.toggleDarkTheme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;auto-theme.toggleLightTheme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl Light&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;auto-theme.schedule&#34;</span><span class="p">:</span> <span class="p">[</span></span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;startTime&#34;</span><span class="p">:</span> <span class="s2">&#34;06:00&#34;</span><span class="p">,</span> <span class="nt">&#34;endTime&#34;</span><span class="p">:</span> <span class="s2">&#34;12:00&#34;</span><span class="p">,</span> <span class="nt">&#34;theme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl Light&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;startTime&#34;</span><span class="p">:</span> <span class="s2">&#34;12:00&#34;</span><span class="p">,</span> <span class="nt">&#34;endTime&#34;</span><span class="p">:</span> <span class="s2">&#34;18:00&#34;</span><span class="p">,</span> <span class="nt">&#34;theme&#34;</span><span class="p">:</span> <span class="s2">&#34;Cobalt2&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;startTime&#34;</span><span class="p">:</span> <span class="s2">&#34;18:00&#34;</span><span class="p">,</span> <span class="nt">&#34;endTime&#34;</span><span class="p">:</span> <span class="s2">&#34;06:00&#34;</span><span class="p">,</span> <span class="nt">&#34;theme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">],</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div><h3 id="layer-2-per-language-and-per-task-theming">Layer 2: Per-Language and Per-Task Theming</h3><p>VS Code supports per-language theme overrides via<code>editor.semanticTokenColorCustomizations</code> and <code>workbench.colorCustomizations</code>.You can fine-tune syntax colors for specific languages without switching themesentirely:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" ><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;editor.semanticTokenColorCustomizations&#34;</span><span class="p">:</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;[Night Owl]&#34;</span><span class="p">:</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;*.declaration.readonly&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;foreground&#34;</span><span class="p">:</span> <span class="s2">&#34;#82aaff&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;parameter&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;foreground&#34;</span><span class="p">:</span> <span class="s2">&#34;#c792ea&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;workbench.colorCustomizations&#34;</span><span class="p">:</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;[Night Owl Light]&#34;</span><span class="p">:</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;sideBar.foreground&#34;</span><span class="p">:</span> <span class="s2">&#34;#000000&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;editor.background&#34;</span><span class="p">:</span> <span class="s2">&#34;#fafafa&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;sideBar.background&#34;</span><span class="p">:</span> <span class="s2">&#34;#f0f0f0&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="p">},</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>For task-based theming, you can bind theme switching to keyboard shortcuts anduse VS Code&rsquo;s profiles feature to switch between &ldquo;writing mode,&rdquo; &ldquo;debuggingmode,&rdquo; and &ldquo;reading mode&rdquo; with different chrome densities and color treatments:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" ><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;key&#34;</span><span class="p">:</span> <span class="s2">&#34;ctrl+shift+1&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;command&#34;</span><span class="p">:</span> <span class="s2">&#34;workbench.action.switchToProfile&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;args&#34;</span><span class="p">:</span> <span class="s2">&#34;Writing&#34;</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="err">,</span></span></span><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;key&#34;</span><span class="p">:</span> <span class="s2">&#34;ctrl+shift+2&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;command&#34;</span><span class="p">:</span> <span class="s2">&#34;workbench.action.switchToProfile&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;args&#34;</span><span class="p">:</span> <span class="s2">&#34;Debugging&#34;</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="err">,</span></span></span><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;key&#34;</span><span class="p">:</span> <span class="s2">&#34;ctrl+shift+3&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;command&#34;</span><span class="p">:</span> <span class="s2">&#34;workbench.action.switchToProfile&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;args&#34;</span><span class="p">:</span> <span class="s2">&#34;Reading&#34;</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div><h3 id="layer-3-ambient-adaptation">Layer 3: Ambient Adaptation</h3><p>For true adaptive theming, you can combine VS Code&rsquo;s<a href="https://code.visualstudio.com/docs/getstarted/themes#_automatically-switch-based-on-os-color-scheme">window.autoDetectColorScheme</a>with OS-level automation. On macOS, Night Shift and Shortcuts can trigger themechanges. On Windows, Power Automate or AutoHotkey scripts can switch themesbased on sunrise and sunset.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" ><span class="line"><span class="cl"><span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;window.autoDetectColorScheme&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;workbench.preferredLightColorTheme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl Light&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;workbench.preferredDarkColorTheme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="nt">&#34;workbench.preferredHighContrastColorTheme&#34;</span><span class="p">:</span> <span class="s2">&#34;Night Owl High Contrast&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>When paired with Windows 11&rsquo;s dynamic lighting and macOS&rsquo;s built-in automatictheme switching, this gives you a four-state system: light → dark → highcontrast → light, following your OS settings without manual intervention.</p><h2 id="adaptive-theming-in-neovim">Adaptive Theming in Neovim</h2><p>Neovim offers even finer control because everything is configurable in Lua. Youcan build an adaptive system that responds to time, file type, and even ambientlight data from your system.</p><h3 id="time-based-switching">Time-Based Switching</h3><p>Using Lua, you can schedule theme changes with a simple timer:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" ><span class="line"><span class="cl"><span class="kd">local</span> <span class="kr">function</span> <span class="nf">set_theme_by_hour</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="kd">local</span> <span class="n">hour</span> <span class="o">=</span> <span class="n">tonumber</span><span class="p">(</span><span class="n">os.date</span><span class="p">(</span><span class="s2">&#34;%H&#34;</span><span class="p">))</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"> <span class="kr">if</span> <span class="n">hour</span> <span class="o">&gt;=</span> <span class="mi">6</span> <span class="ow">and</span> <span class="n">hour</span> <span class="o">&lt;</span> <span class="mi">12</span> <span class="kr">then</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme night-owl-light&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="kr">elseif</span> <span class="n">hour</span> <span class="o">&gt;=</span> <span class="mi">12</span> <span class="ow">and</span> <span class="n">hour</span> <span class="o">&lt;</span> <span class="mi">18</span> <span class="kr">then</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme cobalt2&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="kr">else</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme night-owl&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span></span></span><span class="line"><span class="cl"><span class="kr">end</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- Run on startup</span></span></span><span class="line"><span class="cl"><span class="n">set_theme_by_hour</span><span class="p">()</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- Re-check every 10 minutes</span></span></span><span class="line"><span class="cl"><span class="n">vim.loop</span><span class="p">.</span><span class="n">new_timer</span><span class="p">():</span><span class="n">start</span><span class="p">(</span><span class="mi">600000</span><span class="p">,</span> <span class="mi">600000</span><span class="p">,</span> <span class="n">vim.schedule_wrap</span><span class="p">(</span><span class="n">set_theme_by_hour</span><span class="p">))</span></span></span></code></pre></div><h3 id="per-filetype-and-per-task-theming">Per-Filetype and Per-Task Theming</h3><p>Neovim&rsquo;s <code>FileType</code> and <code>BufEnter</code> autocommands let you theme per context.Disable syntax highlighting in large log files. Use a high-contrast scheme fordiffs. Switch to a minimal prose theme in Markdown:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" ><span class="line"><span class="cl"><span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_create_augroup</span><span class="p">(</span><span class="s2">&#34;AdaptiveTheming&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="n">clear</span> <span class="o">=</span> <span class="kc">true</span> <span class="p">})</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- Minimal theme for writing</span></span></span><span class="line"><span class="cl"><span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_create_autocmd</span><span class="p">(</span><span class="s2">&#34;FileType&#34;</span><span class="p">,</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="n">group</span> <span class="o">=</span> <span class="s2">&#34;AdaptiveTheming&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">pattern</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&#34;markdown&#34;</span><span class="p">,</span> <span class="s2">&#34;text&#34;</span><span class="p">,</span> <span class="s2">&#34;tex&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="n">callback</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme rose-pine-dawn&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;light&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">})</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- High contrast for diff</span></span></span><span class="line"><span class="cl"><span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_create_autocmd</span><span class="p">(</span><span class="s2">&#34;FileType&#34;</span><span class="p">,</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="n">group</span> <span class="o">=</span> <span class="s2">&#34;AdaptiveTheming&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">pattern</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&#34;diff&#34;</span><span class="p">,</span> <span class="s2">&#34;gitcommit&#34;</span> <span class="p">},</span></span></span><span class="line"><span class="cl"> <span class="n">callback</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme gruvbox-material&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;dark&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">})</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- Dim non-focus windows</span></span></span><span class="line"><span class="cl"><span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_create_autocmd</span><span class="p">(</span><span class="s2">&#34;WinEnter&#34;</span><span class="p">,</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="n">group</span> <span class="o">=</span> <span class="s2">&#34;AdaptiveTheming&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">callback</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">winhighlight</span> <span class="o">=</span> <span class="s2">&#34;Normal:NormalFloat&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">})</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_create_autocmd</span><span class="p">(</span><span class="s2">&#34;WinLeave&#34;</span><span class="p">,</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="n">group</span> <span class="o">=</span> <span class="s2">&#34;AdaptiveTheming&#34;</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">callback</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">winhighlight</span> <span class="o">=</span> <span class="s2">&#34;Normal:DimWindow&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">})</span></span></span></code></pre></div><h3 id="ambient-light-integration">Ambient Light Integration</h3><p>For the full adaptive experience, you can integrate with system light sensors.On macOS, you can read the ambient light level via <code>pmset -g raw</code>. On Linux,<code>acpi -V</code> or the <code>illuminated</code> package provides sensor data. Here is a Neovimplugin module that polls ambient brightness:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" ><span class="line"><span class="cl"><span class="kd">local</span> <span class="kr">function</span> <span class="nf">get_ambient_brightness</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="kd">local</span> <span class="n">handle</span> <span class="o">=</span> <span class="n">io.popen</span><span class="p">(</span><span class="s2">&#34;pmset -g raw 2&gt;/dev/null | grep &#39;Ambient&#39; | awk &#39;{print $3}&#39;&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="kr">if</span> <span class="n">handle</span> <span class="kr">then</span></span></span><span class="line"><span class="cl"> <span class="kd">local</span> <span class="n">result</span> <span class="o">=</span> <span class="n">handle</span><span class="p">:</span><span class="n">read</span><span class="p">(</span><span class="s2">&#34;*a&#34;</span><span class="p">):</span><span class="n">gsub</span><span class="p">(</span><span class="s2">&#34;%s+&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">handle</span><span class="p">:</span><span class="n">close</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="kr">return</span> <span class="n">tonumber</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">50</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span></span></span><span class="line"><span class="cl"> <span class="kr">return</span> <span class="mi">50</span></span></span><span class="line"><span class="cl"><span class="kr">end</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="kd">local</span> <span class="kr">function</span> <span class="nf">adaptive_theme</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="kd">local</span> <span class="n">brightness</span> <span class="o">=</span> <span class="n">get_ambient_brightness</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="c1">-- Assume 0–100 range, lower = darker room</span></span></span><span class="line"><span class="cl"> <span class="kr">if</span> <span class="n">brightness</span> <span class="o">&lt;</span> <span class="mi">30</span> <span class="kr">then</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme tokyonight-storm&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;dark&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">elseif</span> <span class="n">brightness</span> <span class="o">&lt;</span> <span class="mi">60</span> <span class="kr">then</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme night-owl&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;dark&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">else</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme kanagawa-lotus&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;light&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span></span></span><span class="line"><span class="cl"><span class="kr">end</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="c1">-- Check every 5 minutes</span></span></span><span class="line"><span class="cl"><span class="n">vim.loop</span><span class="p">.</span><span class="n">new_timer</span><span class="p">():</span><span class="n">start</span><span class="p">(</span><span class="mi">300000</span><span class="p">,</span> <span class="mi">300000</span><span class="p">,</span> <span class="n">vim.schedule_wrap</span><span class="p">(</span><span class="n">adaptive_theme</span><span class="p">))</span></span></span></code></pre></div><h3 id="plugin-based-approach">Plugin-Based Approach</h3><p>If you prefer a plugin-based setup, these plugins handle most of the work:</p><ul><li><strong><a href="https://github.com/folke/tokyonight.nvim">tokyonight.nvim</a></strong> — ships with abuilt-in <code>config.style</code> that can be set dynamically based on time.</li><li><strong><a href="https://github.com/catppuccin/nvim">catppuccin</a></strong> — exposes<code>vim.g.catppuccin_flavour</code> that you can toggle between <code>latte</code>, <code>frappe</code>,<code>macchiato</code>, and <code>mocha</code> based on your schedule.</li><li><strong><a href="https://github.com/f-person/auto-dark-mode.nvim">auto-dark-mode.nvim</a></strong> —syncs Neovim&rsquo;s theme with your OS dark/light mode automatically.</li><li><strong><a href="https://github.com/EdenEast/nightfox.nvim">nightfox.nvim</a></strong> — includes<code>dayfox</code>, <code>dawnfox</code>, <code>duskfox</code>, and <code>nightfox</code> variants designed for differenttimes of day.</li></ul><p>Here is a minimal auto-dark-mode setup:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" ><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s2">&#34;auto-dark-mode&#34;</span><span class="p">).</span><span class="n">setup</span><span class="p">({</span></span></span><span class="line"><span class="cl"> <span class="n">update_interval</span> <span class="o">=</span> <span class="mi">60000</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">set_dark_mode</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme tokyonight&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;dark&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"> <span class="n">set_light_mode</span> <span class="o">=</span> <span class="kr">function</span><span class="p">()</span></span></span><span class="line"><span class="cl"> <span class="n">vim.cmd</span><span class="p">(</span><span class="s2">&#34;colorscheme kanagawa-lotus&#34;</span><span class="p">)</span></span></span><span class="line"><span class="cl"> <span class="n">vim.opt</span><span class="p">.</span><span class="n">background</span> <span class="o">=</span> <span class="s2">&#34;light&#34;</span></span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span></span></span><span class="line"><span class="cl"><span class="p">})</span></span></span></code></pre></div><h2 id="accessibility-is-not-optional">Accessibility Is Not Optional</h2><p>Most popular themes fail basic accessibility checks. This is not a side issue—itdirectly affects whether your editor is usable by everyone on your team.</p><ul><li><strong>Contrast ratios</strong>: WCAG AA (4.5:1 for normal text, 3:1 for large text)should be the minimum. According to a 2024 audit of the 50 most popular VSCode themes on the marketplace, 34% failed WCAG AA for at least one commoncolor pair (comments vs. background, strings vs. keywords).</li><li><strong>Color blindness</strong>: Red-green syntax highlighting excludes roughly 8% of maledevelopers. It is still the default in most editors. Tools like<a href="https://marketplace.visualstudio.com/items?itemName=skn0tt.colorblindly">Colorblindly</a>(VS Code) can simulate color vision deficiency directly in the editor.</li><li><strong>Astigmatism and dark mode</strong>: As mentioned earlier, dark mode worsens thehalation effect for people with astigmatism. Forcing one theme on everyone isnot inclusive.</li></ul><p>An adaptive system solves this by giving users per-context themes rather thanone compromise. A developer with astigmatism can use a warm light theme forprose writing and a medium-contrast dark theme for focused coding, switchingbased on task rather than lighting.</p><h3 id="practical-tooling">Practical Tooling</h3><ul><li><strong>VS Code</strong>: Use the<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.accessibility-checker">Accessibility Checker</a>to audit your custom themes against WCAG standards.</li><li><strong>Neovim</strong>: Plugins like <a href="https://github.com/jdhao/nvim-a11y">nvim-a11y</a> or<a href="https://github.com/rktjmp/lush.nvim">lush.nvim</a> with contrast-checkinghelpers let you validate your color palette in real time.</li><li><strong>General</strong>: Tools like<a href="https://contrast-ratio.com/">Lea Verou&rsquo;s Contrast Ratio</a>,<a href="https://michelf.ca/projects/sim-daltonism/">Sim Daltonism</a> (macOS), and<a href="https://webaim.org/resources/contrastchecker/">Colour Contrast Checker</a> helpyou evaluate any color pair before committing it to a theme.</li></ul><h2 id="a-practical-daily-setup">A Practical Daily Setup</h2><p>Here is what the full adaptive system looks like in practice across botheditors:</p><table><thead><tr><th>Time</th><th>Condition</th><th>VS Code</th><th>Neovim</th><th>Visual Goal</th></tr></thead><tbody><tr><td>06:00 – 09:00</td><td>Morning, bright room</td><td>Night Owl Light + warm sidebar</td><td>kanagawa-lotus</td><td>Warm undertones, low contrast</td></tr><tr><td>09:00 – 12:00</td><td>Peak daylight</td><td>Cobalt2</td><td>tokyonight-day</td><td>Neutral, medium contrast</td></tr><tr><td>12:00 – 14:00</td><td>Lunch, variable light</td><td>Auto theme via OS</td><td>auto-dark-mode sync</td><td>System-following</td></tr><tr><td>14:00 – 18:00</td><td>Afternoon grind</td><td>Night Owl</td><td>nightfox</td><td>High contrast, focused</td></tr><tr><td>18:00 – 22:00</td><td>Evening, winding down</td><td>In Bed by 7pm</td><td>duskfox</td><td>Reduced blue light, warmer</td></tr><tr><td>22:00 – 06:00</td><td>Night coding</td><td>Night Owl</td><td>tokyonight-storm</td><td>Minimal blue light, high contrast</td></tr></tbody></table><p>The specifics matter less than the principle: your visual system changesthroughout the day, and your tools should adapt to you.</p><h2 id="the-bottom-line">The Bottom Line</h2><p>Stop treating theme choice as a religious identity. Build a system that adaptsto your day, your task, and your environment. Whether you use VS Code with threeextensions or Neovim with a 30-line Lua module, the principle is the same: yourtools should meet you where you are, not force you to meet them.</p><p>Your code will not care what color your background is. Your eyes will.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Why SEO Is Mostly Dead (And What Replaced It)</title><link>https://valticus.pro/posts/why-seo-is-mostly-dead-and-what-replaced-it/</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/why-seo-is-mostly-dead-and-what-replaced-it/</guid><description>An analysis of how traditional SEO has evolved in 2026. Why keyword optimization no longer guarantees traffic and the strategies that work for visibility now.</description><category>Web Development</category><content:encoded><h2 id="the-seo-graveyard">The SEO Graveyard</h2><p>For two decades, <strong>SEO</strong> was the golden ticket: research keywords, optimizecontent, build links, and watch traffic grow. That playbook is obsolete.Traditional <strong>SEO</strong>—the kind that focuses on &ldquo;tricking&rdquo; a crawler into ranking apage—is fundamentally broken. In 2026, we aren&rsquo;t just fighting for the top ofthe &ldquo;10 Blue Links&rdquo;; we are fighting for survival in an ecosystem that isincreasingly hostile to external clicks.</p><p>The era of the &ldquo;Search Portal&rdquo; is over. We have entered the era of the &ldquo;<strong>AnswerEngine</strong>,&rdquo; where Google, Bing, and AI-native search tools like Perplexity aim tokeep users on their own platforms.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/why-seo-is-mostly-dead-and-what-replaced-it_hu_344017820ead98ba.webp"alt="Why SEO Is Mostly Dead (And What Replaced It)."width="800"height="436"></div><figcaption><p class="figure__caption">Why SEO Is Mostly Dead (And What Replaced It).</p></figcaption></figure><h2 id="the-google-problem-zero-click-reality">The Google Problem: Zero-Click Reality</h2><p>Google&rsquo;s evolution into a &ldquo;<strong>Search Generative Experience</strong>&rdquo; (<strong>SGE</strong>) hasfundamentally changed the value proposition of being #1. Even if you rank first,you are now buried under:</p><ul><li><strong>AI-generated Overviews</strong>: Which summarize your content so the user never hasto click.</li><li><strong>Featured Snippets</strong>: Which steal the &ldquo;punchline&rdquo; of your article.</li><li><strong>&ldquo;People also ask&rdquo;</strong>: A recursive loop that keeps users engaged with Google&rsquo;sUI.</li><li><strong>Persistent Sponsored Content</strong>: Organic results are often pushed below thefold on mobile and desktop alike.</li></ul><p>The first page of Google is now real estate for Google&rsquo;s own features. For manyinformational queries, the <strong>click-through rate (CTR)</strong> for the #1 organicresult has dropped by over 60% compared to five years ago.</p><h2 id="the-content-farm-collapse">The Content Farm Collapse</h2><p>The &ldquo;<strong>Helpful Content Updates</strong>&rdquo; of the last few years were the final nail inthe coffin for sites that relied on:</p><ul><li><strong>Keyword-stuffed articles</strong> designed for bots, not humans.</li><li><strong>AI-slop</strong>: Mass-produced, unverified content designed to capture long-tailtraffic.</li><li><strong>Programmatic SEO</strong>: Thousands of pages with thin, repetitive data.</li><li><strong>Thin affiliate content</strong>: Reviewing products without ever touching them.</li></ul><p>These tactics no longer work because search engines have pivoted from <strong>KeywordMatching</strong> to <strong>Entity Recognition</strong>. They no longer look for the word &ldquo;bestlaptop&rdquo;; they look for &ldquo;Expertise&rdquo; and &ldquo;Authoritativeness&rdquo; from a known entity.</p><h2 id="what-actually-works-now-visibility-over-seo">What Actually Works Now: Visibility over SEO</h2><p>If <strong>SEO</strong> is dead, what replaced it? The answer is <strong>Holistic Visibility</strong>.Instead of optimizing for an algorithm, you must optimize for <strong>Trust</strong> and<strong>Citability</strong>.</p><h3 id="1-the-eeat-20-framework">1. The EEAT 2.0 Framework</h3><p><strong>Experience</strong>, <strong>Expertise</strong>, <strong>Authoritativeness</strong>, and <strong>Trustworthiness</strong>(<strong>EEAT</strong>) are no longer just &ldquo;guidelines&rdquo;—they are the core of the rankingsystem.</p><ul><li><strong>Experience</strong>: Can you prove you actually <em>did</em> the thing you&rsquo;re writingabout? This is why &ldquo;I tried X for 30 days&rdquo; content is outperforming &ldquo;How to doX&rdquo; guides.</li><li><strong>Trust</strong>: If an AI summarizes your content, will it cite you as the source?<strong>Citability</strong> is the new backlink.</li></ul><h3 id="2-build-an-audience-not-just-traffic">2. Build an Audience, Not Just Traffic</h3><p>The most successful creators in 2026 have one thing in common: they don&rsquo;t relyon Google.</p><ul><li><strong>Email Newsletters</strong>: Owning your distribution means you aren&rsquo;t at the mercyof an algorithm update.</li><li><strong>RSS Feeds</strong>: As I discussed in Slow Web Movement, allowing users to consumeyour content on their own terms builds long-term loyalty.</li><li><strong>Direct Traffic</strong>: Your goal should be to make your brand the destination,not the search engine.</li></ul><h2 id="the-shift-old-seo-vs-new-visibility">The Shift: Old SEO vs. New Visibility</h2><table><thead><tr><th style="text-align: left">Feature</th><th style="text-align: left">Old <strong>SEO</strong> (Dead)</th><th style="text-align: left">New Visibility (Alive)</th></tr></thead><tbody><tr><td style="text-align: left"><strong>Focus</strong></td><td style="text-align: left">Keywords &amp; <strong>Latent Semantic Indexing</strong></td><td style="text-align: left">Entities, Intent, and <strong>EEAT</strong></td></tr><tr><td style="text-align: left"><strong>Success Metric</strong></td><td style="text-align: left">Search Rank &amp; Page Views</td><td style="text-align: left">Citations, Subscriptions, Dwell Time</td></tr><tr><td style="text-align: left"><strong>Content Type</strong></td><td style="text-align: left">Skimmable Listicles</td><td style="text-align: left">Deep Tutorials &amp; Original Research</td></tr><tr><td style="text-align: left"><strong>Distribution</strong></td><td style="text-align: left">&ldquo;Post and Pray&rdquo; to Google</td><td style="text-align: left">Multi-channel (<strong>RSS</strong>, Email, Social)</td></tr><tr><td style="text-align: left"><strong>AI Role</strong></td><td style="text-align: left">Used to generate volume</td><td style="text-align: left">Used to enhance research/depth</td></tr></tbody></table><h2 id="technical-excellence-still-matters">Technical Excellence Still Matters</h2><p>While &ldquo;tricks&rdquo; are dead, technical quality is more important than ever. If an<strong>AI crawler</strong> (like GPT-Bot or CCBot) can&rsquo;t easily parse your site, you won&rsquo;tbe cited in AI overviews.</p><blockquote><p><strong>Pro Tip: JSON-LD for Entity Recognition</strong> Use advanced <strong>Schema.org</strong> markupto tell search engines exactly who you are and what your content represents.Don&rsquo;t just use <code>Article</code> schema; use <code>ReviewedBy</code>, <code>Specialty</code>, and<code>SignificantLink</code> to build a <strong>semantic web</strong> of trust around your content.</p></blockquote><h3 id="schemaorg-checklist-for-ai-visibility"><strong>Schema.org</strong> Checklist for AI Visibility</h3><ul><li><input disabled="" type="checkbox"> <strong>Author Schema</strong>: Link to your LinkedIn, social media, and about page toestablish &ldquo;<strong>Expertise</strong>.&rdquo;</li><li><input disabled="" type="checkbox"> <strong>Organization Schema</strong>: Define your brand&rsquo;s relationship to the topicsyou cover.</li><li><input disabled="" type="checkbox"> <strong>FAQ Schema</strong>: Help AI summaries find the &ldquo;answers&rdquo; in your contentquickly.</li><li><input disabled="" type="checkbox"> <strong>Breadcrumbs</strong>: Establish a clear hierarchy for the crawler.</li></ul><h2 id="the-rise-of-answer-engine-optimization-aeo">The Rise of &ldquo;Answer Engine Optimization&rdquo; (AEO)</h2><p>As AI-powered search (Perplexity, ChatGPT) grows, we must optimize for<strong>Answerability</strong>.</p><ul><li><strong>Be the Source</strong>: Provide original data or unique insights that AI modelswill want to cite.</li><li><strong>Write for Citability</strong>: Use clear, declarative statements that are easy foran <strong>LLM</strong> to extract and attribute.</li><li><strong>Performance</strong>: As I&rsquo;ve noted in SEO vs Performance: How to Balance Both,speed is the baseline. If your site is slow, a crawler might time out beforeit can index your &ldquo;expert&rdquo; opinion.</li></ul><h2 id="the-human-factor-opinionated-content">The Human Factor: Opinionated Content</h2><p>The one thing AI cannot replicate (yet) is a <strong>strong, human opinion</strong>. AI isgreat at summarizing the &ldquo;average&rdquo; view. To stand out, you must be anything<em>but</em> average.</p><ul><li>Share your failures.</li><li>Challenge the status quo.</li><li>Write with a voice that is unmistakably yours.</li></ul><p>In 2026, the most valuable &ldquo;<strong>SEO</strong>&rdquo; tool you have is your own perspective.</p><h2 id="conclusion-stop-optimizing-start-serving">Conclusion: Stop Optimizing, Start Serving</h2><p>The death of traditional <strong>SEO</strong> is actually a good thing for the web. It isforcing creators to stop writing for bots and start writing for humans again.The &ldquo;optimization&rdquo; of the future isn&rsquo;t about where you place your keywords; it&rsquo;sabout the value you provide to your readers.</p><p>The sites that thrive in the next decade won&rsquo;t be the ones with the mostbacklinks or the perfect keyword density. They will be the most <strong>useful</strong>, themost <strong>trusted</strong>, and the most <strong>human</strong>.</p><p>Stop chasing the algorithm. Build something worth citing.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>SEO vs Performance: How to Balance Both</title><link>https://valticus.pro/posts/seo-vs-performance-how-to-balance-both/</link><pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/seo-vs-performance-how-to-balance-both/</guid><description>Practical strategies for balancing search engine optimization with website performance. Achieve great rankings without sacrificing speed or user experience.</description><category>Web Development</category><category>Technology</category><content:encoded><h2 id="the-false-dichotomy-speed-is-seo">The False Dichotomy: Speed is SEO</h2><p>In the early days of the web, performance was a technical luxury. Today, it is afoundational pillar of Search Engine Optimization. Yet, developers and marketersoften frame SEO and performance as opposing forces: SEO requires trackingscripts, heavy images, and rich functionality that supposedly &ldquo;hurts&rdquo;performance, while performance purists want to strip away every tag that mightdelay a millisecond of rendering.</p><p>This is a false dichotomy. In the modern era of <strong>Core Web Vitals</strong>, performance<em>is</em> SEO. Google no longer just looks at what your page says; it looks at howyour page <em>behaves</em>. If your site is slow, it doesn&rsquo;t matter how well-optimizedyour keywords are—you will be buried by faster, more responsive competitors.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/how-i-built-this-site-and-the-tech-stack-i-regret_hu_30a85feb1fe7e88c.webp"alt="SEO vs Performance: How to Balance Both."width="800"height="437"></div><figcaption><p class="figure__caption">SEO vs Performance: How to Balance Both.</p></figcaption></figure><h2 id="where-they-align-the-core-web-vitals-era">Where They Align: The Core Web Vitals Era</h2><p>Since the introduction of <strong>Core Web Vitals</strong>, the alignment between <strong>userexperience (UX)</strong> and <strong>SEO</strong> has never been stronger. These metrics arespecifically designed to quantify the &ldquo;real-world&rdquo; experience of a user.</p><h3 id="1-largest-contentful-paint-lcp">1. Largest Contentful Paint (LCP)</h3><p><strong>LCP</strong> measures when the largest content element (usually a hero image orheading) becomes visible.</p><ul><li><strong>SEO Impact</strong>: High <strong>LCP</strong> scores tell Google your site is useful quickly.</li><li><strong>Performance Strategy</strong>: Optimize the <strong>critical rendering path</strong>. Preloadyour hero images and ensure your <strong>server-side rendering (SSR)</strong> or <strong>staticsite generation (SSG)</strong> is delivering HTML as fast as possible.</li></ul><h3 id="2-interaction-to-next-paint-inp">2. Interaction to Next Paint (INP)</h3><p>Replacing the older First Input Delay (FID), <strong>INP</strong> measures the overallresponsiveness of your site to user inputs (clicks, taps, keyboard presses)throughout the entire life of the page.</p><ul><li><strong>SEO Impact</strong>: Google uses <strong>INP</strong> to penalize &ldquo;janky&rdquo; sites that feelsluggish.</li><li><strong>Performance Strategy</strong>: Minimize <strong>main-thread blocking JavaScript</strong>. Use<strong>Web Workers</strong> for heavy computations and avoid large, monolithic JS bundles.</li></ul><h3 id="3-cumulative-layout-shift-cls">3. Cumulative Layout Shift (CLS)</h3><p><strong>CLS</strong> measures visual stability. We&rsquo;ve all experienced that frustrating momentwhen a button moves just as we&rsquo;re about to click it because an ad or imageloaded late.</p><ul><li><strong>SEO Impact</strong>: Poor <strong>CLS</strong> is a direct signal of low-quality <strong>UX</strong>, whichnegatively impacts rankings.</li><li><strong>Performance Strategy</strong>: Always define <code>width</code> and <code>height</code> attributes forimages and video. Reserve space for dynamic elements like ads or embeds.</li></ul><h2 id="common-conflicts-and-surgical-solutions">Common Conflicts and Surgical Solutions</h2><p>While the goals align, the implementation often creates friction. Here is how tohandle the most common &ldquo;SEO vs. Performance&rdquo; battles.</p><h3 id="problem-third-party-scripts-the-silent-killer">Problem: Third-Party Scripts (The Silent Killer)</h3><p>Marketers demand <strong>Google Tag Manager (GTM)</strong>, HubSpot, Hotjar, and multiplesocial pixels. Each of these adds a <strong>DNS lookup</strong>, a <strong>TCP connection</strong>, andexecution time on the main thread.</p><p><strong>Solution: The &ldquo;Partytown&rdquo; Approach or Server-Side Tracking</strong> Instead ofloading everything in the browser, consider <strong>server-side tagging</strong>. If you mustuse client-side scripts, use the <code>defer</code> or <code>async</code> attributes, or better yet,use a library like <strong>Partytown</strong> to run intensive scripts in a <strong>Web Worker</strong>.</p><blockquote><p><strong>Pro Tip: The GTM Audit</strong> Never allow &ldquo;container bloat.&rdquo; Every 6 months,audit your <strong>GTM</strong> container. If a pixel isn&rsquo;t actively being used for a livecampaign, delete it. A single abandoned LinkedIn pixel can add 200ms to your<strong>Total Blocking Time (TBT)</strong>.</p></blockquote><h3 id="problem-high-resolution-visual-content">Problem: High-Resolution Visual Content</h3><p>SEO experts want &ldquo;rich&rdquo; content with infographics and high-quality hero shots tokeep users engaged (and improve &ldquo;Dwell Time&rdquo;). Performance fans want 20KBplaceholders.</p><p><strong>Solution: Automated Modern Formats</strong> Don&rsquo;t choose between quality and speed.Use Hugo&rsquo;s built-in image processing to generate <strong>WebP</strong> and <strong>AVIF</strong> versionsof your images automatically.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" ><span class="line"><span class="cl"><span class="cm">{{/* Example: Hugo Image Optimization Snippet */}}</span></span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$image</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="na">.Page.Resources.GetMatch</span><span class="w"> </span><span class="s">&#34;hero.jpg&#34;</span><span class="w"> </span><span class="cp">}}</span></span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">$image</span><span class="w"> </span><span class="cp">}}</span></span></span><span class="line"><span class="cl"> <span class="cp">{{</span><span class="w"> </span><span class="nx">$webp</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">$image</span><span class="na">.Resize</span><span class="w"> </span><span class="s">&#34;1200x webp q85&#34;</span><span class="w"> </span><span class="cp">}}</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">picture</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">source</span> <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$webp</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;image/webp&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$image</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">width</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$image</span><span class="na">.Width</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">height</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$image</span><span class="na">.Height</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">alt</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Page.Title</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">loading</span><span class="o">=</span><span class="s">&#34;eager&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">fetchpriority</span><span class="o">=</span><span class="s">&#34;high&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">picture</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div><h2 id="the-asset-value-vs-performance-impact-matrix">The &ldquo;Asset Value vs. Performance Impact&rdquo; Matrix</h2><p>When deciding whether to add a new feature or script, use this comparison tableto evaluate the trade-off:</p><table><thead><tr><th style="text-align: left">Asset Type</th><th style="text-align: left">SEO Value</th><th style="text-align: left">Performance Cost</th><th style="text-align: left">Recommendation</th></tr></thead><tbody><tr><td style="text-align: left"><strong>Semantic HTML</strong></td><td style="text-align: left">Extremely High</td><td style="text-align: left">Zero</td><td style="text-align: left">Always use. Essential for crawlers.</td></tr><tr><td style="text-align: left"><strong>JSON-LD Schema</strong></td><td style="text-align: left">High</td><td style="text-align: left">Low</td><td style="text-align: left">Always use. Negligible impact on speed.</td></tr><tr><td style="text-align: left"><strong>Optimized Images</strong></td><td style="text-align: left">High</td><td style="text-align: left">Medium</td><td style="text-align: left">Use <code>srcset</code> and modern formats.</td></tr><tr><td style="text-align: left"><strong>Web Fonts</strong></td><td style="text-align: left">Medium</td><td style="text-align: left">Medium/High</td><td style="text-align: left">Use <code>font-display: swap</code> and preload critical weights.</td></tr><tr><td style="text-align: left"><strong>Client-side Chat Bot</strong></td><td style="text-align: left">Low</td><td style="text-align: left">Very High</td><td style="text-align: left">Load on user interaction only (Lazy Load).</td></tr><tr><td style="text-align: left"><strong>Full GTM Container</strong></td><td style="text-align: left">Medium</td><td style="text-align: left">High</td><td style="text-align: left">Audit frequently and use server-side tracking.</td></tr></tbody></table><h2 id="the-hydration-problem-spa-vs-ssg">The &ldquo;Hydration&rdquo; Problem: SPA vs. SSG</h2><p>If you are using a modern framework like <strong>Next.js</strong> or <strong>Nuxt</strong>,&ldquo;<strong>Hydration</strong>&rdquo; is your biggest performance enemy. This is the process where thebrowser downloads JavaScript to make a static-looking page interactive. For acontent-heavy site, this is often overkill.</p><p><strong>Static Site Generators</strong> like <strong>Hugo</strong> (which powers this site) avoid thisentirely. By delivering pre-rendered HTML and only adding JavaScript whereabsolutely necessary, you achieve the &ldquo;Gold Standard&rdquo; of SEO: content that isinstantly indexable <em>and</em> instantly interactive.</p><p>If you want to dive deeper into how I optimize my Hugo setup for maximumthroughput, I will cover advanced techniques in a future article.</p><h2 id="technical-checklist-for-performance-first-seo">Technical Checklist for Performance-First SEO</h2><p>To ensure you aren&rsquo;t sacrificing one for the other, follow this checklist duringyour next build:</p><ol><li><strong>[ ] Zero-render-blocking CSS</strong>: Inline <strong>critical CSS</strong> and load the restasynchronously.</li><li><strong>[ ] Font Subsetting</strong>: Don&rsquo;t load the entire &ldquo;Roboto&rdquo; family. Only load thecharacters you actually use (e.g., Latin-1).</li><li><strong>[ ] Resource Hints</strong>: Use <code>preconnect</code> for essential third-party domains(like your <strong>CDN</strong>) and <code>dns-prefetch</code> for the rest.</li><li><strong>[ ] Image Dimensions</strong>: Hardcode width/height to eliminate <strong>CLS</strong>.</li><li><strong>[ ] Lazy Loading</strong>: Apply <code>loading=&quot;lazy&quot;</code> to everything below the fold.</li></ol><h2 id="common-pitfall-the-lighthouse-score-trap">Common Pitfall: The &ldquo;Lighthouse Score&rdquo; Trap</h2><p>Don&rsquo;t get obsessed with hitting a 100/100 <strong>Lighthouse score</strong> at the expense offunctionality. A 95 score with a high-converting &ldquo;Buy Now&rdquo; button is better foryour business than a 100 score on a page that is too stripped down to be useful.</p><p>The goal is <strong>Perceived Performance</strong>. If the user <em>feels</em> like the site isinstant, and Google&rsquo;s bots can find the content without being blocked by amassive JavaScript bundle, you&rsquo;ve won the game.</p><h2 id="conclusion-the-holistic-view">Conclusion: The Holistic View</h2><p>In 2026, the wall between the &ldquo;Performance Engineer&rdquo; and the &ldquo;SEO Specialist&rdquo;has crumbled. You can no longer optimize for one without deeply understandingthe other. The most successful sites are those built on a foundation of<strong>Technical Excellence</strong>.</p><p>Start with a fast, static foundation. Add your SEO elements surgically. Monitoryour <strong>Core Web Vitals</strong> religiously. When you treat performance as a corefeature of your SEO strategy, you stop fighting the algorithms and start servingyour audience. And that is exactly what Google wants to reward.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Inside Google Search's Most Radical Redesign in 25 Years</title><link>https://valticus.pro/posts/google-search-radical-redesign/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/google-search-radical-redesign/</guid><description>An in-depth analysis of Google Search's most radical redesign in 25 years. How AI, SGE, and new UI paradigms are reshaping the search experience for everyone.</description><category>Technology</category><category>Web Development</category><content:encoded><h2 id="the-death-of-the-ten-blue-links-paradigm">The Death of the Ten Blue Links Paradigm</h2><p>For more than a quarter of a century, the basic interface of the internetremained remarkably unchanged. You opened a browser, navigated to a stark whitehomepage with a single search bar, typed in a string of fragmented keywords, andpressed enter. In return, you received a list of ten blue links.</p><p>That era is officially over.</p><p>Google Search is currently undergoing its most radical redesign since itsinception in 1998. The search engine is pivoting from a passive keyword-matchingdirectory into an active, conversational AI engine powered by Google&rsquo;s frontiermodels. Traditional search results still exist, but they are now heavilydeprioritized in favor of direct, AI-synthesized answers, interactiveapplications built on the fly, and autonomous background search agents.</p><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/google-search-radical-redesign_hu_9de31e5f3d972ecd.webp"alt="Inside Google Search&#39;s Most Radical Redesign in 25 Years."width="800"height="800"></div><figcaption><p class="figure__caption">Inside Google Search&#39;s Most Radical Redesign in 25 Years.</p></figcaption></figure><p>Here is a technical breakdown of the major changes rolling out and what theymean for the future of both consumers and web creators.</p><hr><h2 id="1-the-conversational-ai-search-box">1. The Conversational AI Search Box</h2><p>The iconic blank search bar has been completely reimagined. It is no longer asimple text input box but a dynamic canvas designed to accept multi-modalqueries.</p><ul><li><strong>Dynamic Expansion:</strong> The new search box expands as you interact with it,inviting more than just text queries.</li><li><strong>Multi-Modal Inputs:</strong> Users can now seamlessly input text, images, videos,spreadsheets, PDFs, and even link open Chrome tabs directly into the searchcontext.</li><li><strong>Deep Contextual Queries:</strong> Instead of searching &ldquo;best running shoes,&rdquo; a usercan upload a video of their running gait, link a spreadsheet of their budgetconstraints, and ask: <em>&ldquo;Based on my gait and these prices, which shoe should Ibuy?&rdquo;</em></li></ul><p>This shifts user behavior from &ldquo;keyword hacking&rdquo; to natural, conversationalproblem-solving.</p><hr><h2 id="2-gemini-35-flash-as-the-default-engine">2. Gemini 3.5 Flash as the Default Engine</h2><p>Speed has always been a key ranking factor, but in AI search, speed is thedifference between a tool feeling like a helper or a hindrance.</p><p>Google has deployed <strong>Gemini 3.5 Flash</strong> globally as the default engine poweringall &ldquo;AI Mode&rdquo; searches. This frontier AI model has been optimized for lowlatency and high throughput, making conversational answers load almostinstantaneously.</p><p>This change solves the early complaint of &ldquo;AI Overviews&rdquo; taking too long togenerate compared to traditional blue links. With Gemini 3.5 Flash, theconversational response is compiled and streamed in real-time, matching orexceeding the speed of legacy search queries.</p><hr><h2 id="3-247-information-agents">3. 24/7 Information Agents</h2><p>Perhaps the most significant paradigm shift is the introduction of <strong>AutonomousSearch Agents</strong>.</p><p>Instead of performing the same manual search every few days, users (initiallyrolling out to Google One AI Premium subscribers, including AI Pro and Ultratiers) can spin up persistent background agents.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" ><span class="line"><span class="cl">Prompt: &#34;Monitor the web for new 2-bedroom apartment listings in downtown Austin under $2,500/month that are pet-friendly, and alert me the moment they are posted.&#34;</span></span></code></pre></div><p>Once activated, these agents work 24/7. They continuously query, filter, andanalyze the web, sending structured notifications and updates directly to theuser. This turns Google Search from a pull-based tool (where you must go lookfor info) to a push-based service (where the info finds you).</p><hr><h2 id="4-generative-ui-on-the-fly-micro-apps">4. Generative UI: On-the-Fly Micro-Apps</h2><p>Traditionally, Google served static answers or extracted snippets. Now, GoogleSearch can code and build custom, interactive widgets and visualizations on thefly.</p><p>If a user inputs a complex math query or asks for a comparison of multiplefinancial options, Google Search writes code behind the scenes and renders acustom interactive interface:</p><ul><li><strong>Dynamic Graphs:</strong> Real-time plotting of data based on user queries.</li><li><strong>Interactive Simulations:</strong> Adjust sliders to see how changes affect ascenario (e.g., mortgage interest calculators).</li><li><strong>Mini-Apps:</strong> Custom comparison charts or calculators built on the flyspecifically for that user&rsquo;s query.</li></ul><p>For developers and webmasters, this is a massive shift: Google is no longer justcrawling your content; it is replacing the utility of simple web applicationsdirectly on the search page.</p><hr><h2 id="5-expanded-personal-intelligence">5. Expanded Personal Intelligence</h2><p>Google is leveraging its ecosystem advantage by connecting Search directly toyour personal data.</p><p>Without requiring a premium subscription, the search engine now securelyconnects to your Google workspace apps, including:</p><ul><li><strong>Gmail:</strong> Finding flight confirmations, receipts, or email threads.</li><li><strong>Google Photos:</strong> Searching for specific objects or dates in your photohistory.</li><li><strong>Google Calendar (Upcoming):</strong> Cross-referencing schedules to answer personalplanning queries.</li></ul><p>Google implements strict privacy boundaries, ensuring personal data is neverused to train public AI models or served to other users. However, for the enduser, Google Search is now a unified personal assistant that knows both thepublic web and your private life.</p><hr><h2 id="6-the-webmaster-impact-faq-rich-results-phased-out">6. The Webmaster Impact: FAQ Rich Results Phased Out</h2><p>On the SEO and web publisher side, Google has quietly made a major change: theofficial removal of <strong>FAQ rich results</strong> from search pages.</p><p>For years, webmasters used Schema.org structured data to add expandable Q&amp;Adropdowns under their search listings, occupying valuable organic real estate.Google has phased these out to declutter the Search Engine Results Pages (SERPs)and free up space for AI summaries and Generative UI widgets.</p><p>This signals a clear message to webmasters: Google is reclaiming the SERP space.If you want visibility, you can no longer rely on simple schema hacks to standout.</p><hr><h2 id="what-this-means-for-seo-and-web-publishers">What This Means for SEO and Web Publishers</h2><p>This redesign marks the transition from <strong>SEO (Search Engine Optimization)</strong> to<strong>AEO (Answer Engine Optimization)</strong>.</p><p>If Google is synthesizing answers directly on the page and using autonomousagents to fetch updates, traffic to traditional content sites will inevitablydecline for simple informational queries.</p><p>To survive in this new ecosystem, web publishers must adapt:</p><ol><li><strong>Optimize for LLM Retrieval:</strong> Ensure your content is structured clearly,with authoritative, original insights that AI models want to cite.</li><li><strong>Prioritize Deep Context:</strong> Simple &ldquo;what is&rdquo; articles are easily answered byGemini. Focus on high-value, experiential content, personal case studies, anddeep technical guides that AI cannot easily replicate.</li><li><strong>Build Direct Brand Audience:</strong> Do not rely solely on Google for traffic.Invest in newsletters, direct communities, and bookmark-worthy content thatusers seek out directly.</li></ol><p>For more technical guidance on navigating this transition, consult Google&rsquo;sofficial documentation. You can read the<a href="https://blog.google">Official Announcement on the Google Blog</a> or dive into thestrategies outlined in Google&rsquo;s AEO Guide to align your website with thesearchitectural changes.</p></content:encoded><dc:creator>Val Paliy</dc:creator></item><item><title>Build a Portfolio Without React: A Step-by-Step Guide</title><link>https://valticus.pro/posts/build-a-portfolio-without-react-a-step-by-step-guide/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid isPermaLink="true">https://valticus.pro/posts/build-a-portfolio-without-react-a-step-by-step-guide/</guid><description>A comprehensive tutorial for creating a developer portfolio without React or JavaScript frameworks. Learn semantic HTML, CSS, and static site techniques.</description><category>Web Development</category><content:encoded><h2 id="why-skip-react-for-your-portfolio">Why Skip React for Your Portfolio?</h2><p>If you&rsquo;re a React developer, building your portfolio with React seems like a&ldquo;no-brainer.&rdquo; It shows you know the framework, right? Not necessarily. In 2026,the real mark of a senior developer is the ability to choose the <strong>right toolfor the job</strong>, not just the one they are most comfortable with.</p><p>Reaching for a heavy JavaScript framework for a site that is essentially 90%static text and images introduces what I call the <strong>&ldquo;React Tax&rdquo;</strong>:</p><ul><li><strong>Bundle Bloat</strong>: You&rsquo;re shipping 40KB+ of framework code before the user seesa single pixel.</li><li><strong>Hydration Cost</strong>: The browser has to execute JavaScript just to make yourtext readable.</li><li><strong>Maintenance</strong>: Dependencies rot. A portfolio built in React 18 will need anupgrade in two years; a portfolio built in Hugo or raw HTML will work for adecade.</li></ul><figure><div class="progressive-image"><img class="progressive-image__img"src="https://valticus.pro/images/build-a-portfolio-without-react-a-step-by-step-guide_hu_d5b85cabf12c9284.webp"alt="Build a Portfolio Without React: A Step-by-Step Guide."width="800"height="436"></div><figcaption><p class="figure__caption">Build a Portfolio Without React: A Step-by-Step Guide.</p></figcaption></figure><p>A portfolio built with static HTML and modern CSS demonstrates that youunderstand the <strong>web&rsquo;s fundamentals</strong>: performance, accessibility, and the DOM.</p><h2 id="choose-your-approach-the-content-first-model">Choose Your Approach: The Content-First Model</h2><p>While you could write every HTML file by hand, a <strong>Static Site Generator (SSG)</strong>gives you the best of both worlds: a component-like development experiencewithout the client-side overhead.</p><p>In this guide, we’ll use <strong>Hugo</strong>. In a previous comparison of static sitegenerators, I&rsquo;ve noted that Hugo is the gold standard for speed and developerexperience in the static world.</p><h2 id="step-1-initialize-your-project">Step 1: Initialize Your Project</h2><p>First, install Hugo and scaffold your site. We’re going to build this without apre-made theme to truly understand the architecture.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" ><span class="line"><span class="cl">hugo new site my-portfolio</span></span><span class="line"><span class="cl"><span class="nb">cd</span> my-portfolio</span></span><span class="line"><span class="cl">git init</span></span></code></pre></div><p>Create your basic layout structure:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" ><span class="line"><span class="cl">mkdir -p layouts/_default layouts/partials</span></span><span class="line"><span class="cl">touch layouts/_default/baseof.html layouts/_default/list.html layouts/_default/single.html</span></span><span class="line"><span class="cl">touch layouts/index.html</span></span></code></pre></div><h2 id="step-2-the-base-template">Step 2: The &ldquo;Base&rdquo; Template</h2><p>The <code>baseof.html</code> file is your &ldquo;Master Page.&rdquo; It contains the <code>&lt;head&gt;</code> and thestructure shared by every page.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" ><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span></span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;UTF-8&#34;</span> <span class="p">/&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;viewport&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;width=device-width, initial-scale=1.0&#34;</span> <span class="p">/&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>{{ .Title }} | {{ .Site.Title }}<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/css/style.css&#34;</span> <span class="p">/&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ partial &#34;header.html&#34; . }}</span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>{{ block &#34;main&#34; . }}{{ end }}<span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ partial &#34;footer.html&#34; . }}</span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span></span></span></code></pre></div><h2 id="step-3-architecture-for-projects">Step 3: Architecture for Projects</h2><p>Your projects should be &ldquo;First Class Citizens&rdquo; in your codebase. Instead ofhardcoding them into the homepage, use Hugo&rsquo;s content model.</p><p>Create your projects:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" ><span class="line"><span class="cl">hugo new projects/my-cool-app.md</span></span><span class="line"><span class="cl">hugo new projects/api-wrapper.md</span></span></code></pre></div><p>In the markdown frontmatter, add custom metadata:</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" ><span class="line"><span class="cl"><span class="nn">---</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;The Ultimate API Wrapper&#34;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;A high-performance Go library for handling rate-limited APIs.&#34;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">tech_stack</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;Go&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;Redis&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;Docker&#34;</span><span class="p">]</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">github_link</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://github.com/valpaliy/api-wrapper&#34;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">featured</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;images/projects/api-wrapper.jpg&#34;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w"></span></span></span></code></pre></div><h2 id="step-4-the-project-gallery-the-hugo-logic">Step 4: The Project Gallery (The Hugo Logic)</h2><p>Now, let’s build a component that automatically lists your featured projects onthe homepage (<code>layouts/index.html</code>).</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" ><span class="line"><span class="cl">{{ define &#34;main&#34; }}</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">section</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;hero&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hi, I&#39;m {{ .Site.Author.name }}<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>I build high-performance web experiences without the fluff.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">section</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;projects-grid&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ range where .Site.RegularPages &#34;Section&#34; &#34;projects&#34; }} {{ if</span></span><span class="line"><span class="cl"> .Params.featured }}</span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;project-card&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;{{ .Params.image }}&#34;</span> <span class="na">alt</span><span class="o">=</span><span class="s">&#34;{{ .Title }}&#34;</span> <span class="p">/&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>{{ .Title }}<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>{{ .Description }}<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;tags&#34;</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ range .Params.tech_stack }}</span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;tag&#34;</span><span class="p">&gt;</span>{{ . }}<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ end }}</span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;{{ .Permalink }}&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn&#34;</span><span class="p">&gt;</span>View Case Study<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl"> {{ end }} {{ end }}</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span></span></span><span class="line"><span class="cl">{{ end }}</span></span></code></pre></div><h2 id="step-5-modern-css-layouts-bento-grids-and-more">Step 5: Modern CSS Layouts (Bento Grids and More)</h2><p>Forget Bootstrap. Use <strong>CSS Grid</strong> to create a modern, responsive layout.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" ><span class="line"><span class="cl"><span class="p">:</span><span class="nd">root</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="nv">--bg-color</span><span class="p">:</span> <span class="mh">#f9fafb</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="nv">--text-color</span><span class="p">:</span> <span class="mh">#111827</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="nv">--accent-color</span><span class="p">:</span> <span class="mh">#2563eb</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="nv">--card-bg</span><span class="p">:</span> <span class="mh">#ffffff</span><span class="p">;</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">projects-grid</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="k">grid</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="k">grid-template-columns</span><span class="p">:</span> <span class="nf">repeat</span><span class="p">(</span><span class="kc">auto</span><span class="o">-</span><span class="kc">fill</span><span class="p">,</span> <span class="nf">minmax</span><span class="p">(</span><span class="mi">350</span><span class="kt">px</span><span class="p">,</span> <span class="mi">1</span><span class="n">fr</span><span class="p">));</span></span></span><span class="line"><span class="cl"> <span class="k">gap</span><span class="p">:</span> <span class="mi">2</span><span class="kt">rem</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">2</span><span class="kt">rem</span> <span class="mi">0</span><span class="p">;</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">project-card</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="k">background</span><span class="p">:</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">card</span><span class="o">-</span><span class="n">bg</span><span class="p">);</span></span></span><span class="line"><span class="cl"> <span class="k">border</span><span class="p">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="kc">solid</span> <span class="mh">#e5e7eb</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="k">border-radius</span><span class="p">:</span> <span class="mi">12</span><span class="kt">px</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="k">overflow</span><span class="p">:</span> <span class="kc">hidden</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="k">transition</span><span class="p">:</span> <span class="k">transform</span> <span class="mf">0.3</span><span class="kt">s</span> <span class="nb">cubic-bezier</span><span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">project-card</span><span class="p">:</span><span class="nd">hover</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="k">transform</span><span class="p">:</span> <span class="nb">translateY</span><span class="p">(</span><span class="mi">-8</span><span class="kt">px</span><span class="p">);</span></span></span><span class="line"><span class="cl"> <span class="k">box-shadow</span><span class="p">:</span> <span class="mi">0</span> <span class="mi">20</span><span class="kt">px</span> <span class="mi">25</span><span class="kt">px</span> <span class="mi">-5</span><span class="kt">px</span> <span class="nb">rgba</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><strong>Pro Tip: CSS Custom Properties</strong> Use <strong>CSS Custom Properties</strong> (variables) fortheming. This makes it trivial to add a &ldquo;Dark Mode&rdquo; later by just swapping thevalues in a <code>:root[data-theme='dark']</code> block.</p><h2 id="step-6-handling-interactivity-without-the-weight">Step 6: Handling Interactivity without the Weight</h2><p>You don&rsquo;t need a 30KB framework for a mobile menu or a simple filter. Use<strong>Vanilla JavaScript</strong>.</p><p><strong>Common Pitfall: The &ldquo;Everything is a Component&rdquo; Mindset</strong> Not every piece ofUI needs to be a &ldquo;component&rdquo; with state. For a portfolio, most interactivity isjust <strong>DOM manipulation</strong>.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" ><span class="line"><span class="cl"><span class="c1">// A simple, accessible mobile menu toggle</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">toggle</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">&#34;#menu-toggle&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">menu</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">&#34;#main-menu&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"></span></span><span class="line"><span class="cl"><span class="nx">toggle</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&#34;click&#34;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span></span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">isExpanded</span> <span class="o">=</span> <span class="nx">toggle</span><span class="p">.</span><span class="nx">getAttribute</span><span class="p">(</span><span class="s2">&#34;aria-expanded&#34;</span><span class="p">)</span> <span class="o">===</span> <span class="s2">&#34;true&#34;</span><span class="p">;</span></span></span><span class="line"><span class="cl"> <span class="nx">toggle</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&#34;aria-expanded&#34;</span><span class="p">,</span> <span class="o">!</span><span class="nx">isExpanded</span><span class="p">);</span></span></span><span class="line"><span class="cl"> <span class="nx">menu</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">toggle</span><span class="p">(</span><span class="s2">&#34;is-active&#34;</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="p">});</span></span></span></code></pre></div><p>If you truly need more complex state (e.g., a live-search for your blog posts),consider <strong>Petite-Vue</strong> or <strong>Alpine.js</strong>. They provide a Vue-like experience butare optimized for &ldquo;sprinkling&rdquo; interactivity on top of static HTML.</p><h2 id="step-7-static-forms-and-search">Step 7: Static Forms and Search</h2><p>The two biggest hurdles for static sites are contact forms and search.</p><ol><li><strong>Forms</strong>: Use a service like <strong>Netlify Forms</strong>, <strong>Formspree</strong>, or <strong>Basin</strong>.You just add a <code>data-netlify=&quot;true&quot;</code> attribute to your HTML form, and Netlifyhandles the submission and spam filtering.</li><li><strong>Search</strong>: For a portfolio, you usually don&rsquo;t need a server-side search. Use<strong>Fuse.js</strong> or <strong>Pagefind</strong>. These tools index your site at build time andprovide a lightning-fast client-side search interface.</li></ol><h2 id="step-8-image-optimization-the-hugo-superpower">Step 8: Image Optimization (The Hugo Superpower)</h2><p>Large images are the #1 killer of portfolio performance. Hugo can automaticallyprocess your images.</p><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" ><span class="line"><span class="cl">{{ $image := resources.Get .Params.image }} {{ $optimized := $image.Resize &#34;800x</span></span><span class="line"><span class="cl">webp q75&#34; }}</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">img</span></span></span><span class="line"><span class="cl"> <span class="na">src</span><span class="o">=</span><span class="s">&#34;{{ $optimized.RelPermalink }}&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">width</span><span class="o">=</span><span class="s">&#34;{{ $optimized.Width }}&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">height</span><span class="o">=</span><span class="s">&#34;{{ $optimized.Height }}&#34;</span></span></span><span class="line"><span class="cl"> <span class="na">alt</span><span class="o">=</span><span class="s">&#34;{{ .Title }}&#34;</span></span></span><span class="line"><span class="cl"><span class="p">/&gt;</span></span></span></code></pre></div><p>This single line of code ensures that no matter how big the original file was,the user only downloads a perfectly sized, compressed <strong>WebP</strong> image.</p><h2 id="conclusion-the-professional-edge">Conclusion: The Professional Edge</h2><p>Building your portfolio without React is more than a technical exercise; it&rsquo;s astatement. It says: <em>&ldquo;I understand how the web works. I care about my users'bandwidth. I can build fast, resilient systems.&rdquo;</em></p><p>If you want to see a full-scale example of this philosophy in action, check outmy Introducing Olivero Hugo Theme post. It’s a project that brings world-class<strong>accessibility</strong> and <strong>performance</strong> to the Hugo ecosystem without the overheadof modern JavaScript frameworks.</p><p>Your portfolio is your calling card. Make sure it loads before the hiringmanager gets bored and clicks away.</p><hr><p><em>Struggling with a specific Hugo layout or CSS grid issue? Drop me a line onsocial media—I’m always happy to help fellow &ldquo;lean web&rdquo; enthusiasts.</em></p></content:encoded><dc:creator>Val Paliy</dc:creator></item></channel></rss>If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid RSS" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.rssboard.org/rss-validator/check.cgi?url=https%3A//valticus.pro/index.xml