<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Viktor Taraskevych</title>
    <description>The latest articles on DEV Community by Viktor Taraskevych (@vik_tar).</description>
    <link>https://dev.to/vik_tar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122456%2F1e6301fa-e12c-4b3d-9e3b-6eb436b9868f.jpg</url>
      <title>DEV Community: Viktor Taraskevych</title>
      <link>https://dev.to/vik_tar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vik_tar"/>
    <language>en</language>
    <item>
      <title>Git merge vs git rebase, explained through relationships 💔➡️❤️</title>
      <dc:creator>Viktor Taraskevych</dc:creator>
      <pubDate>Mon, 05 Oct 2026 07:18:00 +0000</pubDate>
      <link>https://dev.to/vik_tar/git-merge-vs-git-rebase-explained-through-relationships-43m</link>
      <guid>https://dev.to/vik_tar/git-merge-vs-git-rebase-explained-through-relationships-43m</guid>
      <description>&lt;p&gt;You and your partner are dating. Each of you has a life before this: your exes, your habits, your questionable mug collection. Those are your branches.&lt;/p&gt;

&lt;p&gt;Then you decide to move in together. There are two ways to do it.&lt;/p&gt;

&lt;p&gt;🪢 git merge: the honest marriage&lt;/p&gt;

&lt;p&gt;You combine your lives and the whole past stays where it was. Her ex is in the history. Your "I'm going to be a DJ" phase is in the history. On top of it all sits one big commit, "Wedding 🎉", tying everything together.&lt;/p&gt;

&lt;p&gt;✅ Totally honest. Everyone can see where you both came from.&lt;br&gt;
❌ At family dinners, relatives scroll through your git log and start asking questions.&lt;/p&gt;

&lt;p&gt;🔁 git rebase: "there was no one before you"&lt;/p&gt;

&lt;p&gt;You take your life and replay it as if it started after you met. One clean, beautiful line. No branches. No DJ phase.&lt;/p&gt;

&lt;p&gt;✅ The history looks perfect.&lt;br&gt;
❌ It's not quite you anymore: new commits, different hashes.&lt;/p&gt;

&lt;p&gt;⚠️ The golden rule of rebase&lt;/p&gt;

&lt;p&gt;Never rebase history that other people have already seen.&lt;/p&gt;

&lt;p&gt;Your mum remembers your ex. Your friends remember the DJ phase. Run git push --force on your biography, and the next birthday party will hit a conflict that can't be resolved automatically.&lt;/p&gt;

&lt;p&gt;TL;DR:&lt;/p&gt;

&lt;p&gt;Local branch, nobody's seen it → rebase, make it pretty&lt;br&gt;
Shared history, everyone knows → merge, and learn to live with it&lt;/p&gt;

&lt;p&gt;So, is your team Team Merge or Team Rebase? 👇&lt;/p&gt;

&lt;h1&gt;
  
  
  git #frontend #developerhumor #softwareengineering
&lt;/h1&gt;

</description>
      <category>beginners</category>
      <category>git</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>What's the difference between Dependency Inversion and Liskov Substitution — or how to stay a good parent?</title>
      <dc:creator>Viktor Taraskevych</dc:creator>
      <pubDate>Mon, 28 Sep 2026 10:21:49 +0000</pubDate>
      <link>https://dev.to/vik_tar/whats-the-difference-between-dependency-inversion-and-liskov-substitution-or-how-to-stay-a-good-42dm</link>
      <guid>https://dev.to/vik_tar/whats-the-difference-between-dependency-inversion-and-liskov-substitution-or-how-to-stay-a-good-42dm</guid>
      <description>&lt;p&gt;Both principles are about replacing one caregiver with another. The difference is who breaks things.&lt;/p&gt;

&lt;p&gt;DIP — the family's responsibility&lt;br&gt;
Imagine a child who can only fall asleep if Mom sings that specific song.&lt;br&gt;
Mom leaves for a trip — and nobody can replace her. Not Dad, not Grandma, not a nanny.&lt;br&gt;
The problem isn't the others. The problem is that the family built everything around one specific person.&lt;br&gt;
DIP says: depend on the role ("someone who puts the child to sleep"), not on the person. Then who shows up is just a detail.&lt;/p&gt;

&lt;p&gt;👉 Violating DIP = you can't replace anyone.&lt;/p&gt;

&lt;p&gt;LSP — the caregiver's responsibility&lt;br&gt;
Now the family did everything right: any caregiver is welcome.&lt;br&gt;
A nanny arrives and says: "I don't feed kids" — or "I only work with kids over five."&lt;br&gt;
The family couldn't have prevented this. The nanny accepted the role but didn't keep its promises.&lt;br&gt;
LSP says: if you take the role, you keep the contract. Your style can differ, your obligations can't.&lt;/p&gt;

&lt;p&gt;👉 Violating LSP = you replaced someone, and it broke.&lt;/p&gt;

&lt;p&gt;In short:&lt;br&gt;
DIP — can we swap at all? (the family's design)&lt;br&gt;
LSP — is the swap safe? (the caregiver's behavior)&lt;/p&gt;

&lt;h1&gt;
  
  
  SOLID #SoftwareEngineering #CleanCode #OOP #ProgrammingHumor
&lt;/h1&gt;

</description>
      <category>architecture</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>OAuth "by the book" doesn't mean secure</title>
      <dc:creator>Viktor Taraskevych</dc:creator>
      <pubDate>Sun, 20 Sep 2026 17:51:37 +0000</pubDate>
      <link>https://dev.to/vik_tar/oauth-by-the-book-doesnt-mean-secure-24pk</link>
      <guid>https://dev.to/vik_tar/oauth-by-the-book-doesnt-mean-secure-24pk</guid>
      <description>&lt;p&gt;Went through an article on an OAuth/OIDC attack - sharing the takeaways.&lt;/p&gt;

&lt;p&gt;The problem&lt;/p&gt;

&lt;p&gt;Common belief: follow "best practices" - BFF, HttpOnly cookies, PKCE - and your app is protected against authorization theft. In practice, it's not.&lt;/p&gt;

&lt;p&gt;How the attack works&lt;/p&gt;

&lt;p&gt;If an attacker can run JS on your app's page (via XSS, a compromised dependency, or a malicious extension):&lt;/p&gt;

&lt;p&gt;The user has an active IdP session (SSO) - authorization happens silently.&lt;/p&gt;

&lt;p&gt;The attacker secretly (hidden iframe/window) launches their own OAuth flow in the victim's browser.&lt;/p&gt;

&lt;p&gt;The browser auto-completes it and receives an authorization code.&lt;/p&gt;

&lt;p&gt;The attacker intercepts that code from the location before the app processes it.&lt;/p&gt;

&lt;p&gt;From their own environment, they exchange the code for a session - gaining access as the user.&lt;/p&gt;

&lt;p&gt;They don't need the victim's existing tokens, just a parallel flow of their own.&lt;/p&gt;

&lt;p&gt;Why usual defenses don't help&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HttpOnly cookies: code is stolen from the auth flow itself, not a cookie.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BFF: just moves tokens to the server; the API is still reachable via the session the attacker gets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PKCE: the attacker can start their own cycle with their own parameters and plug the stolen code in.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RFC 9700 and FAPI 2.0 both acknowledge that for redirect-based flows, no complete protection exists once the authorization response leaks.&lt;/p&gt;

&lt;p&gt;What actually works&lt;/p&gt;

&lt;p&gt;Form Post Response Mode: the authorization server sends the code via a hidden HTML form (POST) directly to the backend, bypassing the browser/JS entirely. Nothing left to intercept.&lt;/p&gt;

&lt;p&gt;Other measures (defense in depth, not silver bullets):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;baseline XSS protection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;blocking iframe embedding (CSP: frame-ancestors, frame-src)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;requiring explicit user interaction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;binding the code to IP/device fingerprint&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;separate subdomain for redirect URI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why it matters&lt;/p&gt;

&lt;p&gt;Not a new attack, but rarely discussed - standards' threat models often exclude such a "powerful" attacker to keep requirements manageable. XSS isn't rare in practice, so the attack stays applicable.&lt;/p&gt;

&lt;p&gt;Takeaway: buzzwords like confidential client, BFF, PKCE, HttpOnly create a sense of security but don't replace understanding what each one actually protects against. Threat-model your own app before trusting a checklist.&lt;/p&gt;

&lt;h1&gt;
  
  
  OAuth #WebSecurity #Frontend #AppSec
&lt;/h1&gt;

</description>
      <category>authentication</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>Next.js 16.3 update</title>
      <dc:creator>Viktor Taraskevych</dc:creator>
      <pubDate>Sat, 12 Sep 2026 17:49:13 +0000</pubDate>
      <link>https://dev.to/vik_tar/nextjs-163-update-4jl1</link>
      <guid>https://dev.to/vik_tar/nextjs-163-update-4jl1</guid>
      <description>&lt;p&gt;Next.js 16.3 is the biggest framework update since 16.0, and most of the improvements ship with zero code changes.&lt;br&gt;
What every project gets:&lt;br&gt;
Up to 90% less memory in dev - Turbopack now uses disk caching and memory eviction by default. Real case: a 50-route app dropped from ~4.6GB to ~840MB RAM&lt;br&gt;
Up to 5.5x faster repeat builds, thanks to the same disk cache now working with next build too&lt;br&gt;
Up to 22% more requests under load - SSR moved from Web Streams to native Node.js streams&lt;br&gt;
TypeScript 7-10x faster type checking&lt;br&gt;
Edge runtime is now officially deprecated&lt;br&gt;
Separately - Instant Navigations, opt-in features rethinking navigation in server-driven apps:&lt;br&gt;
→ Partial Prefetching - instead of an aggressive full-page prefetch on every link, one reusable "shell" per route, cached for the session → Instant Insights - a devtool that automatically catches navigations that weren't instant and hands you a fix prompt → Better ISR - pages without a build-time prerender now show an instant shell to the first visitor instead of a blocking load → Navigation Inspector - visual debugging of loading states in dev → Playwright helper instant() - catches regressions when a navigation stops being instant after a refactor&lt;br&gt;
This will become the default in the next major version - worth a look now.&lt;br&gt;
&lt;a href="https://lnkd.in/dXMz9jYH" rel="noopener noreferrer"&gt;https://lnkd.in/dXMz9jYH&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  nextjs #frontend #webdev #reactjs
&lt;/h1&gt;

</description>
      <category>nextjs</category>
      <category>performance</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
