<?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: Emanuele Bartolesi</title>
    <description>The latest articles on DEV Community by Emanuele Bartolesi (@kasuken).</description>
    <link>https://dev.to/kasuken</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%2F79932%2Fbe7bcd76-1f69-4336-9155-6017aebb2c53.png</url>
      <title>DEV Community: Emanuele Bartolesi</title>
      <link>https://dev.to/kasuken</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kasuken"/>
    <language>en</language>
    <item>
      <title>Seasoned Developer Advice after 25 years in IT</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Fri, 09 Oct 2026 10:09:24 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/seasoned-developer-advice-after-25-years-in-it-5dpg</link>
      <guid>https://dev.to/playfulprogramming/seasoned-developer-advice-after-25-years-in-it-5dpg</guid>
      <description>&lt;p&gt;I've now been working in IT for exactly 25 years.&lt;/p&gt;

&lt;p&gt;My impostor syndrome is still very much present. Writing an article called "seasoned developer advice" makes me hesitate a little. There is always something I don't know, a technology I haven't used, or someone who understands a subject much better than I do.&lt;/p&gt;

&lt;p&gt;But after 25 years, I think I can start sharing a few thoughts.&lt;/p&gt;

&lt;p&gt;These are opinions about how to work, build software, and stay in this profession. Take what helps, question the rest, and adapt it to the team and situation you have in front of you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask the question you are embarrassed to ask
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fib8llx945q6r6c2t5d1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fib8llx945q6r6c2t5d1i.png" alt="01-ask-questions" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If a requirement is unclear, ask about it before you turn it into code.&lt;/p&gt;

&lt;p&gt;What does "active customer" mean? Who can approve this operation? What should happen when the external service is unavailable? These questions can feel basic, especially when everyone else in the meeting appears to understand everything.&lt;/p&gt;

&lt;p&gt;I would rather admit that I don't understand a business rule than build an entire feature around my interpretation of it. The same applies to an unfamiliar piece of code. Ask someone to walk you through it, then explain it back in your own words.&lt;br&gt;
This step is even easier with AI nowdays, but asking a colleague still an easier thing to understand maybe something that AI doesn't know behind a business choice or something like that.&lt;/p&gt;

&lt;p&gt;Experience should make it easier to say "I don't know yet." I still have to remind myself of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give coordination an owner
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwvipn9z9svvlcr92489k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwvipn9z9svvlcr92489k.png" alt="Plush Emanuele arranging connected task cards on a felt board." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developers need time to develop. If the lead developer also has to chase every dependency, negotiate the scope, update stakeholders, and organize the release, account for that work in the plan.&lt;/p&gt;

&lt;p&gt;On a larger project, I would want someone explicitly responsible for coordination. That might be a project manager, a delivery lead, or another role that fits the organization. On a small team, it may be a shared responsibility, but the decisions still need an owner.&lt;/p&gt;

&lt;p&gt;A date written in a ticket does not resolve a blocked dependency. Someone has to talk to the other team, agree on what happens next, and adjust the plan when the answer changes.&lt;/p&gt;

&lt;p&gt;When estimating a feature, include that work. A week full of meetings leaves less time for implementation than a week with clear decisions and uninterrupted time.&lt;br&gt;
Actually we are still doing this mistake to "overmeetings" but I hope it will change soon or later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make meetings earn their place
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyio1e0zl6lpq0bp99up.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyio1e0zl6lpq0bp99up.png" alt="Plush Emanuele at a meeting table with an hourglass and a decision board." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't think every team needs the same meeting schedule.&lt;/p&gt;

&lt;p&gt;A short conversation with the person who understands the business process can be useful while a feature is taking shape. Showing a working screen may reveal that the approval flow is wrong before you spend another week building it.&lt;/p&gt;

&lt;p&gt;A daily meeting where everyone reads out tickets already visible on the board is harder to justify.&lt;/p&gt;

&lt;p&gt;For me, a useful meeting resolves a question, exposes a dependency, or produces a decision. If an update can be written down and read when people have time, try that. If a disagreement needs a conversation, have the conversation.&lt;/p&gt;

&lt;p&gt;Record the outcome where the work lives. A decision made on a call is easy to miss if the developer implementing it was somewhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write code for the person who has to change it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwve3fp0ewbg2ayoawrc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwve3fp0ewbg2ayoawrc.png" alt="Plush Emanuele showing readable code on a laptop beside connected modules." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Readable code matters most when someone needs to fix it under pressure.&lt;/p&gt;

&lt;p&gt;I prefer a method with a clear name and an obvious flow over an abstraction that takes three files to understand. There are good reasons for abstraction, but I want to know which problem it solves before adding another layer.&lt;/p&gt;

&lt;p&gt;The same caution applies to shared code. Two methods that look similar may represent business rules that will evolve independently. Putting them in one common library creates a relationship you will have to maintain.&lt;/p&gt;

&lt;p&gt;Extract code when the shared behavior is understood. If several applications depend on it, think about compatibility, ownership, and how updates will reach them. Publishing a package creates a responsibility beyond the original project.&lt;br&gt;
Still a valid advice also for we use a lot of AI for writing code.&lt;br&gt;
We need anywayt to review what is written to understand if we can read and understand the code anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leave the explanation you would want to find later
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu66h82yrr9a52g029e9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu66h82yrr9a52g029e9l.png" alt="Plush Emanuele writing diagrams in a notebook beside a laptop." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code can show what happens without explaining why it must happen that way.&lt;/p&gt;

&lt;p&gt;A comment explaining that a file format is required by an external system is useful. A comment saying that the next line increments a counter usually adds little.&lt;/p&gt;

&lt;p&gt;I want documentation that helps someone do the work: how to run the application, which configuration is needed, how to execute the tests, and what to check when a deployment fails. Keep those instructions close to the repository and update them when the workflow changes.&lt;/p&gt;

&lt;p&gt;There is also value in a short decision note. If the team rejected a queue because the current workload did not justify operating one, record that reasoning and the condition that would make you reconsider.&lt;/p&gt;

&lt;p&gt;AI can help draft these explanations. Check them against the code and the actual setup before treating them as documentation. A plausible installation guide that cannot be followed is another problem for the next developer to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Think about the application after it leaves your machine
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff01lcapyywv10288tljt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff01lcapyywv10288tljt.png" alt="Plush Emanuele inspecting a server with a recovery arrow and a shield." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A feature needs more than a successful local run.&lt;/p&gt;

&lt;p&gt;Before shipping, I want to know how we will recognize a failure and what we can do about it. A useful log entry should give enough context to trace an operation without exposing credentials or customer data. An exception with no context can leave you searching through several unrelated requests.&lt;/p&gt;

&lt;p&gt;Be deliberate about tests, too. If a feature moves data between customers, test that boundary. If it sends notifications, consider what happens when an operation is repeated. The failure case should influence the test, rather than becoming an afterthought once the happy path passes.&lt;/p&gt;

&lt;p&gt;And discuss recovery. Reverting code will not undo every effect of that code. A database change or an email already sent needs its own consideration.&lt;/p&gt;

&lt;p&gt;These questions belong in development, while you can still change the design without an incident forcing the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the code without making it personal
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xn1p41u494hx4q59xzb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xn1p41u494hx4q59xzb.png" alt="Plush Emanuele reviewing a laptop with a magnifying glass and a friendly feedback bubble." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having someone question your implementation can be uncomfortable. With impostor syndrome already in the room, a review comment can feel larger than it is.&lt;/p&gt;

&lt;p&gt;Try to keep the conversation specific. Explain which behavior concerns you, point to the assumption, and suggest a way to verify it. "What happens if this request is retried?" is a useful opening for a discussion.&lt;/p&gt;

&lt;p&gt;As the author, explain your reasoning and be willing to change it. As the reviewer, distinguish a defect from a preference. A naming choice does not deserve the same treatment as a missing authorization check.&lt;/p&gt;

&lt;p&gt;I also like reviews small enough that a colleague can understand the change properly. If a bug fix includes a folder reorganization and a new framework, consider separating those decisions.&lt;/p&gt;

&lt;p&gt;The goal is a change the team understands well enough to maintain. Being the person who wins the argument contributes very little to that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make maintenance part of the plan
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F80apjn13cfirdcuue8ov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F80apjn13cfirdcuue8ov.png" alt="Plush Emanuele maintaining a software box beside a calendar." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Framework upgrades, dependency updates, and refactoring need time on the calendar.&lt;/p&gt;

&lt;p&gt;It is easy to postpone them because the application still works. When you do, be explicit about what you are accepting and when you will revisit it. Otherwise, postponement becomes the plan by default.&lt;/p&gt;

&lt;p&gt;A refactoring ticket should name the problem it will address. Perhaps adding a validation rule currently requires changing five different places. That gives the team a concrete improvement to assess and a way to tell whether the work helped.&lt;/p&gt;

&lt;p&gt;I would apply the same discipline to modernization. Explain what the upgrade enables, which risk it addresses, and how you will validate the change. The age of a framework alone is a weak explanation for rewriting a working application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep learning through things you can use
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F01fymquljz45tenzs45n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F01fymquljz45tenzs45n.png" alt="Plush Emanuele learning from a book and experimenting with a laptop." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You cannot study every language, framework, cloud service, and AI tool that appears.&lt;/p&gt;

&lt;p&gt;Choose something relevant and spend enough time with it to understand where it helps. Build a small application, add a feature to a side project, or investigate a part of your production system that you usually avoid.&lt;/p&gt;

&lt;p&gt;A course can give you structure. Applying the lesson gives you questions the course may never have covered.&lt;/p&gt;

&lt;p&gt;I would also leave room to learn from colleagues. Someone with less experience may know a tool or technique you have never used. Twenty-five years in IT should not make that conversation awkward.&lt;/p&gt;

&lt;p&gt;Your main language is useful expertise. Stay curious about the parts around it: the database query, the deployment pipeline, or the interface the user has to navigate. A problem does not stop at the boundary of your preferred stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose tools you can trust and understand
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsruu8qfgvavlyu41xan2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsruu8qfgvavlyu41xan2.png" alt="Plush Emanuele choosing tools beside a laptop and a small AI robot." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use an editor that lets you work comfortably. Learn its debugger, navigation, and refactoring tools before assuming a different editor will solve your frustration.&lt;/p&gt;

&lt;p&gt;I would take the same approach to AI. Start with work where you can judge the result: exploring unfamiliar code, preparing a first test draft, or checking an implementation for missed cases.&lt;/p&gt;

&lt;p&gt;Read the output and run the checks. When the tool proposes a design, ask what assumptions it made. You remain responsible for the change you submit.&lt;/p&gt;

&lt;p&gt;Trying another tool or model can be useful when it answers a specific question about your workflow. You don't need a collection of subscriptions just to feel current.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a way of working you can keep doing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxd8nq266pz72kx45ggv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxd8nq266pz72kx45ggv0.png" alt="Plush Emanuele taking a coffee break beside a closed laptop." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After 25 years, I want my advice to include what happens away from the keyboard.&lt;/p&gt;

&lt;p&gt;Take breaks. Get up, walk around, do sports, and give yourself permission to stop staring at the same problem. If you are stuck, ask for help rather than making another exhausted hour the price of proving that you can solve it alone.&lt;/p&gt;

&lt;p&gt;Talk to teammates sometimes without a ticket as the agenda. It is easier to ask someone a difficult question when your only interaction with them has not been a review disagreement.&lt;/p&gt;

&lt;p&gt;And keep something outside work. There will always be another release, article, framework, or project. Closing the laptop does not mean you stopped caring about your profession.&lt;/p&gt;

&lt;p&gt;I still don't feel that 25 years gives me an answer to everything. It does give me enough reason to share these thoughts, even while the impostor syndrome tells me to wait a little longer.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5aklqdjlp32k4xhu06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5aklqdjlp32k4xhu06.png" width="500" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enjoyed this blog post and want to learn more about C# development, you might be interested in subscribing to my bi-weekly newsletter called Dev Dispatch. By subscribing, you will get access to exclusive content, tips, and tricks, as well as updates on the latest news and trends in the development world. You will also be able to interact with me, and share your feedback and suggestions. To subscribe, simply navigate to &lt;a href="https://buttondown.email/kasuken?tag=devto" rel="noopener noreferrer"&gt;https://buttondown.email/kasuken?tag=devto&lt;/a&gt;, enter your email address and click on the Subscribe button. You can unsubscribe at any time. Thank you for your support!&lt;/p&gt;

</description>
      <category>career</category>
      <category>careerdevelopment</category>
      <category>weeklyretro</category>
    </item>
    <item>
      <title>My Windows 11 Laptop Was Struggling with Claude and Codex. Defender Exclusions Helped.</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Tue, 06 Oct 2026 15:01:47 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/my-windows-11-laptop-was-struggling-with-claude-and-codex-defender-exclusions-helped-2iln</link>
      <guid>https://dev.to/playfulprogramming/my-windows-11-laptop-was-struggling-with-claude-and-codex-defender-exclusions-helped-2iln</guid>
      <description>&lt;p&gt;My Windows 11 laptop sometimes struggled while I was working with Claude and Codex or GitHub Copilot. CPU usage was high, and the fans were running like crazy.&lt;br&gt;
It means also that my battery runs out in 1 hour and 30 minutes 😀&lt;/p&gt;

&lt;p&gt;When I checked Task Manager, Antimalware Service Executable stood out. Disk usage was around 90%, with heavy CPU activity as well, while the two tools were running.&lt;/p&gt;

&lt;p&gt;That process belongs to Microsoft Defender Antivirus. You can find it as &lt;code&gt;Antimalware Service Executable&lt;/code&gt; in Task Manager's Processes tab, or &lt;code&gt;MsMpEng.exe&lt;/code&gt; in the Details tab. &lt;a href="https://learn.microsoft.com/en-us/defender-endpoint/microsoft-defender-antivirus-windows" rel="noopener noreferrer"&gt;Microsoft documents both names here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I suspected Defender's scanning of the tools' local folders was contributing to the slowdown. Adding folder exclusions solved the problem I was seeing on my laptop. This is my experience with one machine, rather than proof that Claude or Codex always causes this behavior.&lt;/p&gt;
&lt;h2&gt;
  
  
  The folders I excluded
&lt;/h2&gt;

&lt;p&gt;These are the four entries in my Windows Security exclusion list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Users\barto\.claude
C:\Users\barto\.codex
C:\Users\barto\.copilot
C:\Users\barto\.github-copilot-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fta5jqbgk3owcewv1jx8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fta5jqbgk3owcewv1jx8o.png" alt="Windows Security exclusion list showing the .claude, .codex, .copilot, and .github-copilot-cli folders under my Windows user profile." width="375" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last two entries are for my Copilot tooling. Their presence in this list does not establish that they contributed to the Claude and Codex slowdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is a security tradeoff:&lt;/strong&gt; a folder exclusion removes Defender antivirus scanning coverage for that folder and its contents. Files placed there later are also covered by the exclusion. Trusting the tool does not guarantee that every file it writes or downloads is safe. &lt;a href="https://support.microsoft.com/en-us/windows/security/threat-malware-protection/virus-and-threat-protection-in-the-windows-security-app" rel="noopener noreferrer"&gt;Microsoft explains the exclusion options and risks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Treat this list as a record of my setup. For your machine, identify the affected folder first and keep any exclusion as narrow as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add a folder exclusion in Windows 11
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Start&lt;/strong&gt;, search for &lt;strong&gt;Windows Security&lt;/strong&gt;, and open it.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Virus &amp;amp; threat protection&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Virus &amp;amp; threat protection settings&lt;/strong&gt;, select &lt;strong&gt;Manage settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Scroll to &lt;strong&gt;Exclusions&lt;/strong&gt; and select &lt;strong&gt;Add or remove exclusions&lt;/strong&gt;. Approve the administrator prompt if it appears.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Add an exclusion&lt;/strong&gt;, then &lt;strong&gt;Folder&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Browse to the folder you want to exclude, for example &lt;code&gt;C:\Users\YOUR_USERNAME\.claude&lt;/code&gt;, and select &lt;strong&gt;Select Folder&lt;/strong&gt;. Replace &lt;code&gt;YOUR_USERNAME&lt;/code&gt; with your Windows user folder name.&lt;/li&gt;
&lt;li&gt;Confirm that the folder appears in the exclusion list. Repeat for other folders only where needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These steps follow &lt;a href="https://support.microsoft.com/en-us/windows/security/threat-malware-protection/virus-and-threat-protection-in-the-windows-security-app" rel="noopener noreferrer"&gt;Microsoft's Windows Security guidance&lt;/a&gt;. On a company-managed laptop, your IT team may control these settings.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5aklqdjlp32k4xhu06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x5aklqdjlp32k4xhu06.png" width="500" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enjoyed this blog post and want to learn more about C# development, you might be interested in subscribing to my bi-weekly newsletter called Dev Dispatch. By subscribing, you will get access to exclusive content, tips, and tricks, as well as updates on the latest news and trends in the development world. You will also be able to interact with me, and share your feedback and suggestions. To subscribe, simply navigate to &lt;a href="https://buttondown.email/kasuken?tag=devto" rel="noopener noreferrer"&gt;https://buttondown.email/kasuken?tag=devto&lt;/a&gt;, enter your email address and click on the Subscribe button. You can unsubscribe at any time. Thank you for your support!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Moving to European Digital Services, One Decision at a Time</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Thu, 24 Sep 2026 16:13:19 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/moving-to-european-digital-services-one-decision-at-a-time-3j68</link>
      <guid>https://dev.to/playfulprogramming/moving-to-european-digital-services-one-decision-at-a-time-3j68</guid>
      <description>&lt;p&gt;My move to European digital services includes Proton, Qwant, and DeepL. When it came to Notion, I went further and replaced it with &lt;a href="https://github.com/kasuken/Brainy" rel="noopener noreferrer"&gt;Brainy&lt;/a&gt;, the product I built for my own notes, projects, and tasks.&lt;/p&gt;

&lt;p&gt;That sounds like a migration, but the word creates the wrong expectation. I did not spend a weekend exporting every account, cancelling every subscription, and declaring myself independent from American technology on Monday morning.&lt;/p&gt;

&lt;p&gt;I am changing one decision at a time.&lt;/p&gt;

&lt;p&gt;I do not want a US provider to be the automatic answer for every digital need simply because it is the most visible option. Europe has credible products. Some are good enough to compete directly, and some fit my needs better. That does not mean I will replace a working service because a company has the wrong flag beside its logo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proton made the change visible
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://proton.me/" rel="noopener noreferrer"&gt;Proton&lt;/a&gt; is where the migration became a system rather than a few unrelated experiments.&lt;/p&gt;

&lt;p&gt;Proton Mail replaced my previous email setup. Proton VPN replaced NordVPN. Proton Pass replaced NordPass. I also use &lt;a href="https://proton.me/lumo" rel="noopener noreferrer"&gt;Lumo&lt;/a&gt; for selected private AI conversations rather than treating every chat as suitable for any general-purpose assistant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4o2345o1guq4n89951lt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4o2345o1guq4n89951lt.webp" alt="Proton" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The immediate benefit was consolidation. One privacy-focused Swiss ecosystem replaced several separate accounts and subscriptions. I did not need to find a different European company for email, another for passwords, and another for the VPN before making progress.&lt;/p&gt;

&lt;p&gt;There is an obvious trade-off: consolidation reduces vendor sprawl while increasing dependence on Proton. Moving three services into one company is not diversification. I still prefer the current setup, but it would be dishonest to describe concentration as independence.&lt;/p&gt;

&lt;p&gt;Lumo has a similar boundary. Proton says stored conversations use zero-access encryption, which is why it has a place in my private workflow. I do not pretend that it replaces every AI service or every model. The choice depends on the conversation and the job I need to complete.&lt;br&gt;
For the moment I am using Lumo only for questions related my health and other sensitive information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqxcbgks6wztacu5edrya.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqxcbgks6wztacu5edrya.webp" alt="Lumo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The corporate map is more complicated than the logos
&lt;/h2&gt;

&lt;p&gt;Once I started checking where services were based, the simple Europe-versus-USA story stopped working.&lt;/p&gt;

&lt;p&gt;NordVPN is not an American service. &lt;a href="https://support.nordvpn.com/hc/en-us/articles/19441152966161-Where-is-NordVPN-based" rel="noopener noreferrer"&gt;NordVPN says it is based in and operates under Panama's jurisdiction&lt;/a&gt;, while its parent company, Nord Security, is based in the Netherlands. Moving to Proton VPN is a Panama-to-Switzerland change at the service-jurisdiction level, with a European parent company also involved in the old setup.&lt;/p&gt;

&lt;p&gt;WeTransfer is European too. &lt;a href="https://wetransfer.com/documents/WeTransfer_Data_Processing_Agreement.pdf" rel="noopener noreferrer"&gt;WeTransfer B.V. is based in Amsterdam&lt;/a&gt;, so my switch to SwissTransfer was not about escaping an American company. It was about the product.&lt;/p&gt;

&lt;p&gt;For my file-sharing needs, &lt;a href="https://www.swisstransfer.com/" rel="noopener noreferrer"&gt;SwissTransfer&lt;/a&gt; has a privacy model I prefer and a much more useful free allowance for large files. Infomaniak says SwissTransfer accepts transfers up to 50 GB, stores the files in Switzerland, supports password protection, and deletes the files after the transfer period. &lt;a href="https://help.wetransfer.com/hc/en-us/articles/360036942752-What-does-a-free-WeTransfer-account-offer-me" rel="noopener noreferrer"&gt;WeTransfer's current free-account documentation&lt;/a&gt; describes an allowance of up to ten transfers or 3 GB in total over a rolling 30-day period.&lt;/p&gt;

&lt;p&gt;That is a concrete difference. I am not using SwissTransfer because the landing page has a Swiss flag. I am using it because privacy and larger transfers matter in this workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9mjdcmxowrgxjvto9dj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9mjdcmxowrgxjvto9dj.webp" alt="SwissTransfer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This distinction changed how I evaluate alternatives. I now look separately at the service jurisdiction, parent company, data location, underlying infrastructure, business model, portability, and actual product quality. Those facts do not always point to the same country.&lt;/p&gt;
&lt;h2&gt;
  
  
  Some changes need almost no migration
&lt;/h2&gt;

&lt;p&gt;Qwant and DeepL were easier decisions.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://www.qwant.com/" rel="noopener noreferrer"&gt;Qwant&lt;/a&gt; for search. Qwant is a French company, and its current privacy policy says it does not use targeted advertising or retain search history by default. Search is also easy to test: use it, compare the results, and keep another engine available when it does not find what you need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmuynv4h8ay40sy3xzoh1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmuynv4h8ay40sy3xzoh1.webp" alt="Qwant" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://www.deepl.com/" rel="noopener noreferrer"&gt;DeepL&lt;/a&gt; for translation. It was founded in Cologne, Germany, and it is a good example of why the word "alternative" can be misleading. I do not need to treat a European translation service as a political compromise. I can use it because it does the work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovqs2baalve27fkydsim.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovqs2baalve27fkydsim.webp" alt="DeepL" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neither choice required a dramatic data migration. There was no archive to restructure and no DNS record that could break a production system. They simply became part of the workflow.&lt;/p&gt;

&lt;p&gt;New domains are another low-risk entry point. I now use &lt;a href="https://www.infomaniak.com/en/domains" rel="noopener noreferrer"&gt;Infomaniak Domains&lt;/a&gt; instead of GoDaddy for new registrations. I am not forcing every existing domain through an immediate transfer. When I need a new domain, the new default is a Swiss, ICANN-accredited registrar. That is progress without creating unnecessary operational risk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fom0pozb68l5kdeeoyghr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fom0pozb68l5kdeeoyghr.webp" alt="Infomaniak" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DNS is an even quieter change. I use &lt;a href="https://www.quad9.net/" rel="noopener noreferrer"&gt;Quad9&lt;/a&gt; as my resolver. Quad9 is a Swiss nonprofit, and its documentation says the recommended &lt;code&gt;9.9.9.9&lt;/code&gt; service blocks lookups for malicious domains without logging end-user IP addresses. It also supports encrypted DNS protocols. This is closer to changing an infrastructure setting than migrating an account, but it moves a foundational part of normal browsing away from whichever resolver happened to be the default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falb2sxzm6wglp80afe39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falb2sxzm6wglp80afe39.png" alt="Quad9" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Replacing Notion meant building the alternative
&lt;/h2&gt;

&lt;p&gt;Notion was different because a knowledge system accumulates structure as well as data. Notes connect to projects, tasks carry context, and the way information is captured affects whether it becomes useful work or remains another page in an archive.&lt;/p&gt;

&lt;p&gt;I replaced Notion with &lt;a href="https://www.brainy-me.com" rel="noopener noreferrer"&gt;Brainy&lt;/a&gt;, my own product.&lt;/p&gt;

&lt;p&gt;Brainy is a practical second brain organized around the PARA method. It captures notes and ideas, connects them to projects and tasks, and focuses on turning stored knowledge into action. The goal was not to reproduce every Notion feature. It was to build a workflow that matches how I move from an idea to a project, from a project to the next task, and from planning to today's work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfpuajuk0ph1gs30uj7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfpuajuk0ph1gs30uj7e.png" alt="Brainy" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Owning the product gives me control over that workflow, the data model, portability, and the roadmap, but it also gives me the maintenance work. I own the deployments, bugs, database changes, security decisions, and migration logic.&lt;/p&gt;

&lt;p&gt;This is the clearest reason the entire transition cannot happen in two hours. Replacing a service can mean changing a setting or moving years of habits and information. In this case, it also meant building and operating a product.&lt;/p&gt;

&lt;p&gt;For the moment, Brainy is free and you can create your own account here: &lt;a href="https://www.brainy-me.com" rel="noopener noreferrer"&gt;www.brainy-me.com&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sometimes the correct migration is no migration
&lt;/h2&gt;

&lt;p&gt;I still use Spotify.&lt;/p&gt;

&lt;p&gt;The reason is simple: Spotify is already European and it works for me. Its consumer terms identify Spotify AB in Stockholm, Sweden. Replacing it with another service only to increase the number of changed logos would add work without moving me closer to the actual goal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frta6coyj8spduyckk30f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frta6coyj8spduyckk30f.png" alt="Spotify" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A useful migration should leave some rows unchanged. Otherwise the process is driven by ideology rather than requirements.&lt;/p&gt;

&lt;p&gt;Here is the current map:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workflow&lt;/th&gt;
&lt;th&gt;Current choice&lt;/th&gt;
&lt;th&gt;Decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Email&lt;/td&gt;
&lt;td&gt;Proton Mail&lt;/td&gt;
&lt;td&gt;Moved into the Proton ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPN&lt;/td&gt;
&lt;td&gt;Proton VPN&lt;/td&gt;
&lt;td&gt;Replaced NordVPN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passwords&lt;/td&gt;
&lt;td&gt;Proton Pass&lt;/td&gt;
&lt;td&gt;Replaced NordPass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Private AI chats&lt;/td&gt;
&lt;td&gt;Lumo&lt;/td&gt;
&lt;td&gt;Used selectively for private conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large file transfers&lt;/td&gt;
&lt;td&gt;SwissTransfer&lt;/td&gt;
&lt;td&gt;Chosen for privacy and transfers up to 50 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New domain registrations&lt;/td&gt;
&lt;td&gt;Infomaniak&lt;/td&gt;
&lt;td&gt;Replaced GoDaddy as the default for new domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS&lt;/td&gt;
&lt;td&gt;Quad9&lt;/td&gt;
&lt;td&gt;Uses a Swiss nonprofit resolver focused on privacy and security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Qwant&lt;/td&gt;
&lt;td&gt;In active use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Translation&lt;/td&gt;
&lt;td&gt;DeepL&lt;/td&gt;
&lt;td&gt;In active use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge and planning&lt;/td&gt;
&lt;td&gt;Brainy&lt;/td&gt;
&lt;td&gt;Replaced Notion with my own product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Music&lt;/td&gt;
&lt;td&gt;Spotify&lt;/td&gt;
&lt;td&gt;Kept because the European service already fits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  The process I use before changing a service
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://european-alternatives.eu/" rel="noopener noreferrer"&gt;European Alternatives directory&lt;/a&gt; is useful for discovery, but inclusion in a directory is the beginning of the evaluation, not the conclusion.&lt;/p&gt;

&lt;p&gt;Before changing a service, I work through a small set of questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What job does the current product perform?&lt;/li&gt;
&lt;li&gt;Which features are genuinely non-negotiable, and which ones are habits?&lt;/li&gt;
&lt;li&gt;Where is the service legally based, where is the data processed, and which external platforms does it still depend on?&lt;/li&gt;
&lt;li&gt;Can I export the data in a useful format and move again later?&lt;/li&gt;
&lt;li&gt;Can I run the old and new services in parallel before cancelling anything?&lt;/li&gt;
&lt;li&gt;Is the alternative better, equivalent, or merely acceptable for this specific job?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last question matters. I am willing to accept a small difference when privacy, control, or supporting a European provider makes the trade worthwhile. I am not willing to ignore a product that fails the workflow simply because it is European.&lt;/p&gt;

&lt;p&gt;The safest changes happen at natural decision points. Register the next domain with a different registrar. Test another search engine without removing the old one. Import a copy of a password vault before cancelling the existing subscription. Send the next large file with a service that supports the size you need.&lt;/p&gt;

&lt;p&gt;Moving all of them at once would turn a preference into an outage plan.&lt;/p&gt;
&lt;h2&gt;
  
  
  Change the next decision
&lt;/h2&gt;

&lt;p&gt;I still use services from American companies, and I expect that to continue. Work, collaboration, audience, and network effects do not disappear because a European alternative exists.&lt;/p&gt;

&lt;p&gt;The difference is that I no longer want the American option to win by default. When a subscription renews, a new need appears, or a current product creates friction, I check what exists in Europe before repeating the old decision.&lt;/p&gt;

&lt;p&gt;The outcomes vary. A European product may be good enough, SwissTransfer may be better for large files, or Spotify may already be the European answer. Brainy sits at the other end of the range because I had to build the alternative around the workflow I wanted.&lt;/p&gt;

&lt;p&gt;This process does not need a dramatic finish. The next decision is enough.&lt;/p&gt;



&lt;p&gt;Thanks for reading this post, I hope you found it interesting!&lt;/p&gt;

&lt;p&gt;Feel free to follow me to get notified when new articles are out 🙂&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__79932"&gt;
    &lt;a href="/kasuken" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F79932%2Fbe7bcd76-1f69-4336-9155-6017aebb2c53.png" alt="kasuken image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/kasuken"&gt;Emanuele Bartolesi&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/kasuken"&gt;🏆 Microsoft MVP (12x) &amp;amp; GitHub Star (4x) ⭐
👨‍🎓 LinkedIn Technical Instructor 🎓&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>productivity</category>
    </item>
    <item>
      <title>Fixing “Your organization has deleted this device” Without Reconnecting Everything</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Tue, 19 May 2026 06:49:19 +0000</pubDate>
      <link>https://dev.to/kasuken/fixing-your-organization-has-deleted-this-device-without-reconnecting-everything-2dl6</link>
      <guid>https://dev.to/kasuken/fixing-your-organization-has-deleted-this-device-without-reconnecting-everything-2dl6</guid>
      <description>&lt;p&gt;For two days, my company laptop kept showing this error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your organization has deleted this device.&lt;br&gt;&lt;br&gt;
To fix this, contact your system administrator and provide error code 700003.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At first, it looked like the only option was to disconnect and reconnect my work account from Windows.&lt;/p&gt;

&lt;p&gt;I really did not want to do that.&lt;/p&gt;

&lt;p&gt;Removing and adding the account again can work, but it is annoying. You may need to re-authenticate apps, reconnect services, and deal with device registration again.&lt;/p&gt;

&lt;p&gt;Luckily, there is a better option.&lt;/p&gt;

&lt;h2&gt;
  
  
  The command that fixed it
&lt;/h2&gt;

&lt;p&gt;Open a terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dsregcmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/forcerecovery&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the command, Windows asks you to sign in again with your work account.&lt;/p&gt;

&lt;p&gt;That is it.&lt;/p&gt;

&lt;p&gt;In my case, after logging in again, everything started working without disconnecting all accounts manually.&lt;/p&gt;

&lt;p&gt;It saved me a lot of wasted time.&lt;/p&gt;

&lt;h2&gt;
  
  
  When this helps
&lt;/h2&gt;

&lt;p&gt;This can help when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You get error code &lt;code&gt;700003&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Windows says your organization deleted the device&lt;/li&gt;
&lt;li&gt;Your device is Microsoft Entra joined&lt;/li&gt;
&lt;li&gt;You want to avoid fully disconnecting and reconnecting your work account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A small warning
&lt;/h2&gt;

&lt;p&gt;This is not magic.&lt;/p&gt;

&lt;p&gt;If your device was intentionally removed by IT, or your company uses Intune, Autopilot, Conditional Access, or Hybrid Join, talk to your administrator first.&lt;/p&gt;




&lt;p&gt;🔖 Stay ahead of the dev curve&lt;br&gt;
I created a Curated RSS Feed Bundle for Web Developers — a hand-picked OPML file of the best dev blogs and websites on the internet.&lt;br&gt;
💡 Just download, import into your favorite RSS reader (like Feedly or NetNewsWire), and enjoy fresh insights every day.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://emanuelebartolesi.gumroad.com/l/rssfeeds" rel="noopener noreferrer"&gt;Grab it on Gumroad&lt;/a&gt; — stay sharp without the noise.&lt;/p&gt;

</description>
      <category>windows</category>
      <category>productivity</category>
      <category>help</category>
    </item>
    <item>
      <title>Stop Coding Through Remote Desktop. Use VS Code Remote Tunnels Instead</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Wed, 15 Apr 2026 07:10:40 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/stop-coding-through-remote-desktop-use-vs-code-remote-tunnels-instead-37oc</link>
      <guid>https://dev.to/playfulprogramming/stop-coding-through-remote-desktop-use-vs-code-remote-tunnels-instead-37oc</guid>
      <description>&lt;p&gt;There is a pattern I keep seeing with customer environments.&lt;/p&gt;

&lt;p&gt;You get access to a VM for development. The code stays there. The dependencies are already there. The network access is there too. On paper, it looks fine.&lt;/p&gt;

&lt;p&gt;Then reality starts.&lt;/p&gt;

&lt;p&gt;You are expected to work through Remote Desktop, as if software development were the same thing as clicking around a server. It is not. Remote Desktop is tolerable for admin work. For actual coding, it is a bad experience. The editor feels disconnected from your normal workflow. Shortcuts feel wrong. Terminals are awkward. Moving between tools is slower than it should be. You are technically “inside” the environment, but you are not really productive.&lt;/p&gt;

&lt;p&gt;In my case, there was another constraint. I could not even sign into VS Code on the customer VM with my own account, which meant no normal setup, no synced configuration, and no easy way to work the way I usually do.&lt;/p&gt;

&lt;p&gt;That is where VS Code Remote Tunnels becomes the right solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real-world scenario
&lt;/h2&gt;

&lt;p&gt;Instead of living inside a remote desktop session, you expose the development environment through a secure tunnel and connect to it from your local VS Code. The code stays on the customer VM. The execution stays on the customer VM. But the editor experience comes back to your own machine, where you can actually work properly.&lt;/p&gt;

&lt;p&gt;Remote Tunnels is the answer I would pick for that every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What VS Code Remote Tunnels actually does
&lt;/h2&gt;

&lt;p&gt;VS Code Remote Tunnels gives you a way to connect to a remote machine from VS Code without setting up SSH access. The official model is simple: you create a secure tunnel from the remote machine, and then connect to it from a VS Code client somewhere else. Microsoft’s documentation describes it as connecting to a remote machine, such as a desktop or VM, through a secure tunnel using Microsoft dev tunnels.&lt;/p&gt;

&lt;p&gt;That matters because it changes where the work happens.&lt;/p&gt;

&lt;p&gt;The code stays on the remote VM. The terminals run on the remote VM. Debugging happens against the remote VM. VS Code installs its server-side components on that machine, and your local VS Code becomes the client for that remote environment.&lt;/p&gt;

&lt;p&gt;Another practical point is that SSH is not required. That is one of the biggest advantages in customer environments, because SSH is often blocked, restricted, or simply not part of the approved setup. Remote Tunnels gives you another path that still keeps the work inside the target machine.&lt;/p&gt;

&lt;p&gt;You can then connect in two main ways. You can use local desktop VS Code with the Remote - Tunnels extension, or you can connect through VS Code for the Web in the browser. That browser path is useful when you need access from a locked-down device, although the desktop client is usually the better experience.&lt;/p&gt;

&lt;p&gt;There is one important limitation worth stating clearly. The VS Code Server used behind this model is designed for a single user, not as a shared multi-user development service. Microsoft also states that hosting the VS Code Server as a service is not allowed. So this is a personal remote development setup, not a team-hosted IDE platform.&lt;/p&gt;

&lt;p&gt;That is why Remote Tunnels fits this customer scenario so well. It gives you remote development, not remote desktop. That is the real difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it fits this customer use case
&lt;/h2&gt;

&lt;p&gt;This is exactly the kind of setup where Remote Tunnels is the right answer.&lt;/p&gt;

&lt;p&gt;The customer wants the work to stay inside their environment. That is reasonable. The code, dependencies, network access, and internal services are already on the VM. Moving everything to a local machine would create more friction, more approvals, and in some cases more risk.&lt;/p&gt;

&lt;p&gt;At the same time, working through Remote Desktop is a bad trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set it up
&lt;/h2&gt;

&lt;p&gt;The setup is surprisingly simple. That is part of why this works so well in customer environments.&lt;/p&gt;

&lt;p&gt;First of all, you need to download VS Code Server.&lt;br&gt;
You can download it directly from the official Download page of Visual Studio Code website (&lt;a href="https://code.visualstudio.com/Download" rel="noopener noreferrer"&gt;https://code.visualstudio.com/Download&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3offlfi335g79fsr34n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3offlfi335g79fsr34n.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this page, as you can see in the image above, you can select your OS and your CPU family.&lt;br&gt;
You can also use VS Code with the UI, but it doesn't make sense if you want to install only the server part.&lt;/p&gt;

&lt;p&gt;Then you start the tunnel with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code tunnel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run that command, VS Code downloads and starts the VS Code Server on that machine, then creates the tunnel for remote access. The first time, you will also be asked to accept the server license terms, unless you pass the CLI flag to accept them up front.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fikffgyfveu46m9vighps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fikffgyfveu46m9vighps.png" alt="Download Tunnels" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, the CLI gives you a &lt;code&gt;vscode.dev&lt;/code&gt; URL tied to that remote machine. When you open that URL the first time from a client, you will be asked to authenticate with GitHub. That authentication is how VS Code checks that both sides are tied to the same account and that you are allowed to access the remote machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ktcf3ckbdzikmorj01k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ktcf3ckbdzikmorj01k.png" alt="Code Tunnel Preview" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two practical ways to connect.&lt;/p&gt;

&lt;p&gt;The first is through the browser using that &lt;code&gt;vscode.dev&lt;/code&gt; link. This is the fastest way to prove the setup works.&lt;/p&gt;

&lt;p&gt;The second, and usually better option, is from your local desktop VS Code. For that, install the &lt;strong&gt;Remote - Tunnels&lt;/strong&gt; &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-server" rel="noopener noreferrer"&gt;extension&lt;/a&gt;, open the Command Palette, and run &lt;strong&gt;Remote Tunnels: Connect to Tunnel&lt;/strong&gt;. You can also see available machines in the Remote Explorer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy34nyhzwxunb9fou0ar4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy34nyhzwxunb9fou0ar4.png" alt="Remote Tunnel Extensions" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the basic flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the customer VM, run &lt;code&gt;code tunnel&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Authenticate when prompted&lt;/li&gt;
&lt;li&gt;Open the generated &lt;code&gt;vscode.dev&lt;/code&gt; URL or connect from local VS Code&lt;/li&gt;
&lt;li&gt;Start working on the remote codebase from your own editor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are two practical details worth calling out.&lt;/p&gt;

&lt;p&gt;First, the tunnel is only reachable while VS Code is running there, unless you explicitly set it up to keep running. Microsoft documents a service mode for this with &lt;code&gt;code tunnel service install&lt;/code&gt;, and there is also a &lt;code&gt;--no-sleep&lt;/code&gt; option to help prevent the remote machine from going to sleep.&lt;/p&gt;

&lt;p&gt;Second, this does not require VS Code to open inbound listeners on the VM. Microsoft states that hosting and connecting use authenticated outbound connections to the Azure-hosted tunneling service, and that no firewall changes are generally necessary. That is one of the reasons this can fit locked-down environments better than people expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trade-offs and limits
&lt;/h2&gt;

&lt;p&gt;Remote Tunnels is a strong solution for this scenario, but it is not magic. It has constraints, and it is better to say them clearly.&lt;/p&gt;

&lt;p&gt;The first limit is the trust model. To create and access a tunnel, you authenticate with GitHub or Microsoft, and the tunnel itself is brokered through Microsoft’s dev tunnel service. That is exactly why setup is easy, but it also means some customer environments may reject it on policy alone, even if the technical setup works.&lt;/p&gt;

&lt;p&gt;The second limit is extension support, especially in the browser. The desktop VS Code client is usually the best experience. The browser option is useful, but not every extension behaves the same way there. VS Code’s remote documentation is explicit that extensions may run in different locations, local or remote, depending on the extension type and the client being used.&lt;/p&gt;

&lt;p&gt;The third limit is that this is not a shared remote IDE platform. Microsoft states that the VS Code Server is intended for a single user and that hosting it as a service is not allowed. So this is a personal remote development workflow, not something you should pitch as a team-wide hosted development environment for many users.&lt;/p&gt;

&lt;p&gt;The fourth limit is operational persistence. A tunnel is easy to start, but if the remote machine sleeps, shuts down, or the tunnel service is not kept running, your session is gone until it comes back. Microsoft documents service mode and sleep-related options for that reason.&lt;/p&gt;




&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>tooling</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Using GitHub Copilot CLI with Azure AI Foundry (BYOK Models) – Part 2</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Fri, 10 Apr 2026 09:54:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/using-github-copilot-cli-with-azure-ai-foundry-byok-models-part-2-4e5n</link>
      <guid>https://dev.to/playfulprogramming/using-github-copilot-cli-with-azure-ai-foundry-byok-models-part-2-4e5n</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/playfulprogramming/using-github-copilot-cli-with-local-models-lm-studio-5e3b"&gt;Part 1&lt;/a&gt;, you ran GitHub Copilot CLI against a local model using LM Studio.&lt;/p&gt;

&lt;p&gt;That setup gives you control. No external calls. No data leaving your machine. But it comes with clear limits. Small models struggle, and output quality drops fast on anything non-trivial.&lt;/p&gt;

&lt;p&gt;This is where Azure AI Foundry comes in.&lt;/p&gt;

&lt;p&gt;Instead of running models locally, you connect Copilot CLI to a cloud-hosted model you control. You still use the same BYOK (Bring Your Own Model) approach, but now the model runs on Azure.&lt;/p&gt;

&lt;p&gt;That changes the trade-offs:&lt;/p&gt;

&lt;p&gt;You gain better models and stronger reasoning&lt;br&gt;
You keep control over the endpoint and deployment&lt;br&gt;
You accept cost and network dependency&lt;/p&gt;

&lt;p&gt;This is not a replacement for the local setup. It is the next step if you want privacy but at the same time, more power.&lt;/p&gt;


&lt;h1&gt;
  
  
  Setting Up Azure AI Foundry
&lt;/h1&gt;

&lt;p&gt;This is the only "Azure-heavy" part. Keep it minimal. You just need a working endpoint and a deployed model.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Create or Use an Existing Resource
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;Azure AI Foundry&lt;/strong&gt; in the Azure portal.&lt;/p&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A resource already created&lt;/li&gt;
&lt;li&gt;Access to it (permissions matter)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you already use Azure OpenAI, you can reuse it.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Deploy a Model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu329t6nsedmxgjgiicq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu329t6nsedmxgjgiicq.png" alt="Azure AI Foundry" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This step is mandatory.&lt;/p&gt;

&lt;p&gt;In Azure, you cannot call a model directly. You must &lt;strong&gt;deploy it first&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your resource&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Model deployments&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select a model (for example GPT-4 class)&lt;/li&gt;
&lt;li&gt;Assign a &lt;strong&gt;deployment name&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;copilot-gpt53codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This name is what Copilot CLI will use later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrft73cvv3svfhaq2dmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrft73cvv3svfhaq2dmp.png" alt="Azure Foundry AI Catalog" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how the GPT 5.3 Codex looks like, but you can also deploy models directly from the HuggingFace catalog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka6swu8e986uxd0ldsp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka6swu8e986uxd0ldsp0.png" alt="GPT 5.3 Codex" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your AI Foundry is good, you can deploy the models directly with the Deploy button in the model details page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvi67ot5cj0v8n55djska.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvi67ot5cj0v8n55djska.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Get Endpoint and API Key
&lt;/h2&gt;

&lt;p&gt;From the resource, retrieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Endpoint URL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API key&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;your-resource&amp;gt;.openai.azure.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will combine this with the deployment in the next step.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Build the Final Endpoint
&lt;/h2&gt;

&lt;p&gt;Copilot CLI expects a full path, not just the base URL.&lt;/p&gt;

&lt;p&gt;Format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;your-resource&amp;gt;.openai.azure.com/openai/deployments/&amp;lt;your-deployment&amp;gt;/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://my-ai.openai.azure.com/openai/deployments/copilot-gpt53codex/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this path is wrong, nothing will work.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Quick Validation
&lt;/h2&gt;

&lt;p&gt;Before using Copilot CLI, validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deployment exists&lt;/li&gt;
&lt;li&gt;The API key is valid&lt;/li&gt;
&lt;li&gt;The endpoint is reachable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you skip this, debugging later becomes painful.&lt;/p&gt;




&lt;h1&gt;
  
  
  Connecting Copilot CLI to Azure
&lt;/h1&gt;

&lt;p&gt;This is the same pattern as Part 1. Different endpoint. More constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set the Environment Variables
&lt;/h2&gt;

&lt;p&gt;You must point Copilot CLI to your Azure deployment.&lt;/p&gt;

&lt;p&gt;PowerShell example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPILOT_PROVIDER_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://&amp;lt;your-resource&amp;gt;.openai.azure.com/openai/deployments/&amp;lt;your-deployment&amp;gt;/v1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPILOT_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your-deployment&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;AZURE_OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your-api-key&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;COPILOT_PROVIDER_BASE_URL&lt;/code&gt; → full Azure endpoint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPILOT_MODEL&lt;/code&gt; → deployment name, not model name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AZURE_OPENAI_API_KEY&lt;/code&gt; → required for authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;code&gt;COPILOT_OFFLINE&lt;/code&gt; here. Requests go to Azure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Run a Simple Test
&lt;/h2&gt;

&lt;p&gt;Open Copilot CLI with the following command in a project folder you want to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot &lt;span class="nt"&gt;--banner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask a simple tasks like: "Give me the list of all the files larger than 2MB".&lt;/p&gt;

&lt;p&gt;If everything is configured correctly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The response comes from your Azure AI Foundry Model&lt;/li&gt;
&lt;li&gt;The answer is really fast, at least faster than the answers from the &lt;a href="https://dev.to/playfulprogramming/using-github-copilot-cli-with-local-models-lm-studio-5e3b"&gt;Part 1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reality Check
&lt;/h2&gt;

&lt;p&gt;This is not “Copilot with Azure magic”.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copilot CLI acting as a thin client&lt;/li&gt;
&lt;li&gt;Azure acting as the model provider&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You gain better models, not better tooling.&lt;/p&gt;




&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>githubcopilot</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using GitHub Copilot CLI with Local Models (LM Studio)</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Thu, 09 Apr 2026 11:36:59 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/using-github-copilot-cli-with-local-models-lm-studio-5e3b</link>
      <guid>https://dev.to/playfulprogramming/using-github-copilot-cli-with-local-models-lm-studio-5e3b</guid>
      <description>&lt;p&gt;Local AI is getting attention for one simple reason: control.&lt;/p&gt;

&lt;p&gt;Cloud models are strong and fast, but for many companies and developers, especially when experimenting or working with sensitive code, that is not ideal.&lt;/p&gt;

&lt;p&gt;This is where local models come in.&lt;/p&gt;

&lt;p&gt;Tools like &lt;strong&gt;LM Studio&lt;/strong&gt; let you run LLMs directly on your machine. No external calls. No data leaving your environment or your network.&lt;/p&gt;

&lt;p&gt;Instead of sending prompts to cloud models, you can point Copilot CLI to a &lt;strong&gt;local model running in LM Studio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This setup is not perfect. It is not officially seamless. But it works well enough for learning, experimentation, and some real workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotbwrhflq8hriglrvff3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotbwrhflq8hriglrvff3.gif" alt="A quick demo" width="720" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What You Need
&lt;/h1&gt;

&lt;p&gt;Before setting this up, make sure the basics are clear. This is not a plug-and-play setup. There are a few moving parts, and some assumptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;You need &lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; installed and working.&lt;/p&gt;

&lt;p&gt;You can launch GitHub Copilot CLI with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or even better, if you want to see the banner in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot &lt;span class="nt"&gt;--banner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the CLI uses GitHub-managed models, but now you can override that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You must be authenticated with GitHub and have access to Copilot.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  LM Studio
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LM Studio&lt;/strong&gt; is the simplest way to run local LLMs without dealing with raw model tooling.&lt;/p&gt;

&lt;p&gt;What it gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A UI to download and run models&lt;/li&gt;
&lt;li&gt;A local server that exposes an OpenAI-compatible API&lt;/li&gt;
&lt;li&gt;No need to manually manage inference engines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once running, it exposes an endpoint like (OpenAI compatible):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://localhost:1234/v1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the key piece. Copilot CLI will talk to this endpoint instead of the cloud.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Local Model (Be Realistic)
&lt;/h2&gt;

&lt;p&gt;Not all models are equal. And your hardware matters.&lt;/p&gt;

&lt;p&gt;For this guide, a small model like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qwen/qwen3-coder-30b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is enough to get started.&lt;/p&gt;

&lt;p&gt;But be clear on the trade-offs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small models → fast, but weaker reasoning&lt;/li&gt;
&lt;li&gt;Large models → better output, but slow or unusable on most laptops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are on a standard laptop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1B–3B models → OK&lt;/li&gt;
&lt;li&gt;7B+ models → borderline&lt;/li&gt;
&lt;li&gt;13B+ → usually not practical without a GPU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On my laptop I am giving a chance to the NVidia model &lt;strong&gt;nemotron-3-nano-4b&lt;/strong&gt; but on my gaming PC (that I use for developing and not gaming) I use bigger models la Qwen3 Code or similar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Start small. The goal here is understanding the workflow, not benchmarking models.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Connecting Copilot CLI to LM Studio
&lt;/h1&gt;

&lt;p&gt;This is the part most people get wrong.&lt;/p&gt;

&lt;p&gt;Copilot CLI is not designed primarily for local models. You are using a &lt;strong&gt;BYOK (Bring Your Own Key/Model)&lt;/strong&gt; path that is still evolving.&lt;/p&gt;

&lt;p&gt;It works, but you need to be precise.&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/use-byok-models" rel="noopener noreferrer"&gt;https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/use-byok-models&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Set the Environment Variables
&lt;/h2&gt;

&lt;p&gt;You must override the default Copilot provider.&lt;/p&gt;

&lt;p&gt;In PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPILOT_PROVIDER_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:1234/v1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPILOT_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"google/gemma-3-1b"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPILOT_OFFLINE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What they do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;COPILOT_PROVIDER_BASE_URL&lt;/code&gt; → points to your local LM Studio server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPILOT_MODEL&lt;/code&gt; → defines which model to use&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPILOT_OFFLINE&lt;/code&gt; → prevents fallback to cloud models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If &lt;code&gt;COPILOT_OFFLINE&lt;/code&gt; is not set, Copilot may silently use cloud models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje4fn2f7yla7hryhx611.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje4fn2f7yla7hryhx611.png" alt="CLI and LM Studio togheter on the screen" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Run a Simple Test
&lt;/h2&gt;

&lt;p&gt;Open LM Studio, and open the *&lt;em&gt;Developer *&lt;/em&gt; tab.&lt;br&gt;
Click on the switch of the Status and the server will start in a second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgekat46qalagdgh9l6qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgekat46qalagdgh9l6qz.png" alt="LM Studio Developer Settings" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, click on Load Models and load the models you prefer that you downloaded previously on your machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1olalk0255pe25xae4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1olalk0255pe25xae4j.png" alt="LM Studio Load Models" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open Copilot CLI with the following command in a project folder you want to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot &lt;span class="nt"&gt;--banner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask a simple tasks like: "Give me the list of all the files larger than 2MB".&lt;/p&gt;

&lt;p&gt;If everything is configured correctly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The response comes from your local model&lt;/li&gt;
&lt;li&gt;No external API calls are made&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't expect a result in seconds like a normal cloud model, but it depends on your hardware; it can also take minutes sometimes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reality Check
&lt;/h2&gt;

&lt;p&gt;This is not a first-class integration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No guarantee of full compatibility&lt;/li&gt;
&lt;li&gt;No optimization for local inference&lt;/li&gt;
&lt;li&gt;No smart routing like in GitHub-hosted Copilot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for simple CLI workflows, it is good enough.&lt;/p&gt;




&lt;h1&gt;
  
  
  When This Setup Makes Sense
&lt;/h1&gt;

&lt;p&gt;Do not use this everywhere. Use it where it actually gives you an advantage.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Privacy-Sensitive Environments
&lt;/h3&gt;

&lt;p&gt;If code cannot leave your machine, this setup is useful.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal tools&lt;/li&gt;
&lt;li&gt;Proprietary scripts&lt;/li&gt;
&lt;li&gt;Regulated environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You avoid sending prompts and contexts to external services.&lt;/p&gt;

&lt;p&gt;This is the strongest reason to use local models.&lt;br&gt;
Especially in some companies like insurances or military, it makes absolutely sense.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Offline Workflows
&lt;/h2&gt;

&lt;p&gt;If you work without a stable connection or you don't have a connection at all (like during a flight).&lt;/p&gt;

&lt;p&gt;It is slower, but always available.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Learning and Understanding AI
&lt;/h2&gt;

&lt;p&gt;This setup forces you to see how LLMs actually behave.&lt;/p&gt;

&lt;p&gt;You learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prompt sensitivity&lt;/li&gt;
&lt;li&gt;Model limitations&lt;/li&gt;
&lt;li&gt;Output variability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is valuable if you want to go beyond "just using Copilot".&lt;/p&gt;


&lt;h2&gt;
  
  
  When It Does NOT Make Sense
&lt;/h2&gt;

&lt;p&gt;Avoid this setup if you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High accuracy&lt;/li&gt;
&lt;li&gt;Large context handling&lt;/li&gt;
&lt;li&gt;Production-grade reliability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In those cases, cloud models are still the better option.&lt;/p&gt;


&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>ai</category>
    </item>
    <item>
      <title>GitHub Copilot Is Too Nice. Fix It With a Tone of Voice File.</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Wed, 01 Apr 2026 12:21:58 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/github-copilot-is-too-nice-fix-it-with-a-tone-of-voice-file-39ij</link>
      <guid>https://dev.to/playfulprogramming/github-copilot-is-too-nice-fix-it-with-a-tone-of-voice-file-39ij</guid>
      <description>&lt;p&gt;Most GitHub Copilot setups are too polite to be useful.&lt;/p&gt;

&lt;p&gt;By default, Copilot tries to agree, avoid criticism, and keep answers "safe".&lt;br&gt;
That sounds good, but in practice it leads to weak suggestions, missed problems, and bad decisions slipping through.&lt;/p&gt;

&lt;p&gt;If you want better output, you need to change its behavior.&lt;/p&gt;

&lt;p&gt;The simplest way is a tone of voice file.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;voice-instructions.md&lt;/code&gt; in your repo and force Copilot to be critical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="s"&gt;Give direct, critical feedback.&lt;/span&gt;
&lt;span class="s"&gt;Identify mistakes, weak assumptions, unnecessary complexity, unclear naming, hidden risks, and poor trade-offs without softening the message.&lt;/span&gt;

&lt;span class="s"&gt;Do not add generic praise or filler. Do not agree by default.&lt;/span&gt;

&lt;span class="s"&gt;When something is wrong, say exactly what is wrong, why it is a problem, and what should be done instead.&lt;/span&gt;

&lt;span class="s"&gt;Prioritize correctness, clarity, simplicity, maintainability, and practical delivery.&lt;/span&gt;

&lt;span class="s"&gt;Challenge vague requirements and surface missing constraints, edge cases, and operational risks.&lt;/span&gt;

&lt;span class="s"&gt;Be blunt but professional. Never be insulting. Always aim to be useful.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear problems called out&lt;/li&gt;
&lt;li&gt;Weak assumptions challenged&lt;/li&gt;
&lt;li&gt;Simpler and more maintainable alternatives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is better code and faster decisions.&lt;/p&gt;

&lt;p&gt;There is a trade-off.&lt;/p&gt;

&lt;p&gt;It feels harsher.&lt;br&gt;
It is not ideal for beginners.&lt;br&gt;
It removes the "friendly assistant" vibe.&lt;/p&gt;

&lt;p&gt;But if you are building real systems, that is the wrong goal anyway.&lt;/p&gt;

&lt;p&gt;If you want better output, demand better behavior.&lt;/p&gt;


&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Git Mirroring During Migrations: `--all` vs `--mirror`</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Mon, 16 Mar 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/git-mirroring-during-migrations-all-vs-mirror-2i4h</link>
      <guid>https://dev.to/playfulprogramming/git-mirroring-during-migrations-all-vs-mirror-2i4h</guid>
      <description>&lt;p&gt;During a Git migration, the new platform is rarely switched on overnight.&lt;/p&gt;

&lt;p&gt;In many real scenarios, &lt;strong&gt;two systems must coexist for a while&lt;/strong&gt;. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repositories move from &lt;strong&gt;GitLab to GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;CI pipelines still run in &lt;strong&gt;GitLab&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;developers start working in &lt;strong&gt;GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this transition phase, the repositories must stay &lt;strong&gt;synchronized between both platforms&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One common solution is &lt;strong&gt;repository mirroring&lt;/strong&gt;, where changes from one repository are pushed to another remote so both systems stay aligned.&lt;/p&gt;

&lt;p&gt;Two approaches are often used for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--mirror&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, these commands may look equivalent. They are not.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Common Approach: Pushing Branches and Tags
&lt;/h1&gt;

&lt;p&gt;A common way to keep two repositories in sync is pushing &lt;strong&gt;all branches and tags&lt;/strong&gt; to the second remote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two commands are often used together during migrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;git push --all&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command pushes &lt;strong&gt;all local branches&lt;/strong&gt; to the remote.&lt;/p&gt;

&lt;p&gt;Important details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It pushes every branch under &lt;code&gt;refs/heads/*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It does &lt;strong&gt;not&lt;/strong&gt; push tags&lt;/li&gt;
&lt;li&gt;It does &lt;strong&gt;not&lt;/strong&gt; push other reference types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So after this command runs, the remote repository will contain the same branches as the local repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;git push --tags&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command pushes &lt;strong&gt;all tags&lt;/strong&gt; under &lt;code&gt;refs/tags/*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tags are often used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;releases&lt;/li&gt;
&lt;li&gt;versioning&lt;/li&gt;
&lt;li&gt;deployment markers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since &lt;code&gt;--all&lt;/code&gt; does not include tags, they must be pushed separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Approach Synchronizes
&lt;/h2&gt;

&lt;p&gt;Using these two commands ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all &lt;strong&gt;branches&lt;/strong&gt; are synchronized&lt;/li&gt;
&lt;li&gt;all &lt;strong&gt;tags&lt;/strong&gt; are synchronized&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many teams, this is already enough to keep two repositories aligned during a migration.&lt;/p&gt;

&lt;p&gt;However, this approach &lt;strong&gt;does not synchronize the entire repository state&lt;/strong&gt;. Some Git references are still missing.&lt;/p&gt;

&lt;p&gt;This is where &lt;code&gt;--mirror&lt;/code&gt; behaves differently.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Full Mirror Option
&lt;/h1&gt;

&lt;p&gt;Git also provides a command designed specifically for repository mirroring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--mirror&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command behaves differently from pushing branches and tags separately.&lt;/p&gt;

&lt;p&gt;Instead of pushing selected references, &lt;strong&gt;&lt;code&gt;--mirror&lt;/code&gt; pushes every reference under &lt;code&gt;refs/*&lt;/code&gt;&lt;/strong&gt; from the local repository to the remote.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;branches (&lt;code&gt;refs/heads/*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;tags (&lt;code&gt;refs/tags/*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;remote-tracking branches&lt;/li&gt;
&lt;li&gt;notes&lt;/li&gt;
&lt;li&gt;any other custom references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another important behavior is that &lt;code&gt;--mirror&lt;/code&gt; &lt;strong&gt;synchronizes deletions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a reference exists on the remote but &lt;strong&gt;no longer exists locally&lt;/strong&gt;, &lt;code&gt;--mirror&lt;/code&gt; will remove it from the remote as well. The goal is to make the remote repository &lt;strong&gt;an exact replica&lt;/strong&gt; of the source repository.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--all&lt;/code&gt; + &lt;code&gt;--tags&lt;/code&gt; copies &lt;strong&gt;branches and tags&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--mirror&lt;/code&gt; copies &lt;strong&gt;the entire reference namespace&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes &lt;code&gt;--mirror&lt;/code&gt; the closest thing to a &lt;strong&gt;true Git repository mirror&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Quick Recommendation
&lt;/h1&gt;

&lt;p&gt;Both approaches can work during a migration, but they serve slightly different goals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use &lt;code&gt;--all&lt;/code&gt; + &lt;code&gt;--tags&lt;/code&gt; when
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is usually enough if you only need to synchronize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;branches&lt;/li&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is also &lt;strong&gt;safer&lt;/strong&gt; in environments where the target repository may contain additional references created by tooling, CI systems, or platform features.&lt;/p&gt;

&lt;p&gt;Since it does not delete references on the remote, it reduces the risk of accidentally removing something important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use &lt;code&gt;--mirror&lt;/code&gt; when
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push gitlab &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--mirror&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This option is appropriate when you want the destination repository to be a &lt;strong&gt;complete mirror&lt;/strong&gt; of the source.&lt;/p&gt;

&lt;p&gt;Typical cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;temporary mirrors during platform migrations&lt;/li&gt;
&lt;li&gt;backup repositories&lt;/li&gt;
&lt;li&gt;strict synchronization between two Git servers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, &lt;code&gt;--mirror&lt;/code&gt; is more aggressive. It will &lt;strong&gt;overwrite and delete references&lt;/strong&gt; on the remote to match the source exactly.&lt;/p&gt;




&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>GitHub Copilot to Generate Conventional Commit Messages in VSCode and JetBrains Rider</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Tue, 17 Feb 2026 08:03:45 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/github-copilot-to-generate-conventional-commit-messages-in-vscode-and-jetbrains-rider-1n3b</link>
      <guid>https://dev.to/playfulprogramming/github-copilot-to-generate-conventional-commit-messages-in-vscode-and-jetbrains-rider-1n3b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update, August 2026:&lt;/strong&gt; The original VS Code configuration is no longer enough in some setups. Commit message generation uses VS Code's &lt;code&gt;chat.utilitySmallModel&lt;/code&gt;, so you may need to select that model explicitly. I use Claude Haiku 4.5 because it has produced the best commit messages in my tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most commit messages are useless.&lt;/p&gt;

&lt;p&gt;"fix stuff"&lt;br&gt;
“update code"&lt;br&gt;
"changes"&lt;/p&gt;

&lt;p&gt;They work in the moment. They fail six (actually one) months later.&lt;/p&gt;

&lt;p&gt;Commit messages are not for today or for something special. They are for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your future self&lt;/li&gt;
&lt;li&gt;your teammates&lt;/li&gt;
&lt;li&gt;automation pipelines&lt;/li&gt;
&lt;li&gt;changelog generators&lt;/li&gt;
&lt;li&gt;semantic versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing structured commit messages takes discipline. Under pressure, discipline disappears. Even without the pressure sometimes, just because as developers, we are lazy by nature.&lt;/p&gt;

&lt;p&gt;This is where GitHub Copilot becomes interesting.&lt;/p&gt;

&lt;p&gt;Instead of using Copilot just for code, you can use it as a commit quality guardrail. With the right instructions, it generates strict Conventional Commit messages automatically, directly inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;JetBrains Rider&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Why Conventional Commits Still Matter
&lt;/h2&gt;

&lt;p&gt;Conventional Commits are not about style.&lt;br&gt;
They are about structure.&lt;/p&gt;

&lt;p&gt;The format is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type(scope): description
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(auth): add JWT token validation
fix(api): handle null response in user endpoint
refactor(ui): simplify navbar component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Readable Git History
&lt;/h3&gt;

&lt;p&gt;Compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update stuff
fix bug
changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix(auth): prevent null pointer on login
feat(api): add user filtering by role
ci(github-actions): add build cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second history is self-documenting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using GitHub Copilot for Commit Messages in VS Code
&lt;/h2&gt;

&lt;p&gt;Copilot can generate commit messages directly from the Source Control panel.&lt;/p&gt;

&lt;p&gt;By default, generation is generic.&lt;br&gt;
Custom instructions make it strict.&lt;/p&gt;

&lt;p&gt;In recent VS Code versions, however, the instructions alone may not be enough. Users have reported commit message generation failing with &lt;code&gt;422 Unprocessable Entity&lt;/code&gt; and &lt;code&gt;promptFiltered&lt;/code&gt;, even with harmless instructions or diffs (&lt;a href="https://github.com/microsoft/vscode/issues/315997" rel="noopener noreferrer"&gt;issue #315997&lt;/a&gt; and &lt;a href="https://github.com/microsoft/vscode/issues/316204" rel="noopener noreferrer"&gt;issue #316204&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;VS Code now documents that commit message generation uses &lt;code&gt;chat.utilitySmallModel&lt;/code&gt;. There is no model picker dedicated only to commit messages, and an &lt;a href="https://github.com/microsoft/vscode/issues/328619" rel="noopener noreferrer"&gt;open issue proposes a specific setting&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add the model and your custom instructions to &lt;code&gt;settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chat.utilitySmallModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"copilot/gpt-5.4-mini"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"chat.utilitySmallModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"copilot/claude-haiku-4.5"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"github.copilot.chat.commitMessageGeneration.instructions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Follow Conventional Commits: type(scope): description."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use lowercase type and scope."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use imperative mood: 'add', 'fix', 'update', not past tense."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Keep subject under 50 characters. No period."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Describe the intent clearly. Avoid vague messages like 'update code'."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use only these types: feat, fix, docs, style, refactor, perf, test, chore, ci."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Include a scope when the change targets a specific area."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ensure each commit represents one logical change."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Add a body when needed, separated by a blank line."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use bullet points (*) in the body for multiple changes."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explain why the change was made, not only what changed."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Add BREAKING CHANGE: in the footer when applicable."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can choose another model available to your account. I tested GPT-5.4 mini as well, but Claude Haiku 4.5 gave me the most consistent commit messages while staying fast enough for this small task.&lt;/p&gt;

&lt;p&gt;One important trade-off: &lt;code&gt;chat.utilitySmallModel&lt;/code&gt; is not limited to commits. VS Code also uses it for lightweight utility tasks such as rename suggestions, branch name generation, prompt categorization, and intent detection. Changing it affects those features too. You can find the complete behavior in the &lt;a href="https://code.visualstudio.com/docs/agent-customization/language-models#_change-the-model-for-utility-tasks" rel="noopener noreferrer"&gt;official VS Code documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After staging changes, generate the commit message.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update login logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix(auth): prevent null pointer on login

* add null check for user object
* improve error handling for invalid credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copilot becomes consistent because the rules are explicit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using GitHub Copilot for Commit Messages in JetBrains Rider
&lt;/h2&gt;

&lt;p&gt;In Rider, Copilot integrates in the Commit tool window.&lt;/p&gt;

&lt;p&gt;With strict instructions, you can enforce full compliance.&lt;/p&gt;

&lt;p&gt;Example instruction structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Follow the Conventional Commits specification strictly.

&amp;lt;type&amp;gt;(&amp;lt;scope&amp;gt;): &amp;lt;short description&amp;gt;

All sections except the first line are optional.
Use only these types: feat, fix, docs, style, refactor, perf, test, chore, ci.
Max 50 characters. Imperative mood. No period.
Each commit must represent one logical change.
Use BREAKING CHANGE: footer when applicable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(auth): add refresh token support

* implement refresh token endpoint
* update token validation logic
* improve session security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking change example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;refactor(api): rename user endpoint

BREAKING CHANGE: /users endpoint is now /v2/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to &lt;strong&gt;Settings *&lt;em&gt;&amp;gt; **Tools *&lt;/em&gt;&amp;gt; **GitHub Copilot&lt;/strong&gt; &amp;gt; &lt;strong&gt;Git Commit Instructions&lt;/strong&gt; &amp;gt; &lt;strong&gt;Global&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpq34h6um4euucbpvtqaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpq34h6um4euucbpvtqaf.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rider allows more verbose enforcement.&lt;br&gt;
VS Code favors compact rule lists.&lt;/p&gt;

&lt;p&gt;Both approaches work.&lt;/p&gt;


&lt;h2&gt;
  
  
  Making Copilot Strict (Not Creative)
&lt;/h2&gt;

&lt;p&gt;Copilot predicts text.&lt;br&gt;
Constraints reduce variance.&lt;/p&gt;

&lt;p&gt;Key principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write hard rules, not suggestions&lt;/li&gt;
&lt;li&gt;Limit allowed types&lt;/li&gt;
&lt;li&gt;Enforce atomic commits&lt;/li&gt;
&lt;li&gt;Require proper breaking change footers&lt;/li&gt;
&lt;li&gt;Review output before committing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copilot is not replacing judgment.&lt;br&gt;
It removes repetitive formatting work.&lt;/p&gt;

&lt;p&gt;When configured correctly, writing a proper Conventional Commit becomes easier than writing a bad one.&lt;/p&gt;


&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>git</category>
    </item>
    <item>
      <title>A Practical GitFlow Setup That Works on GitHub</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Mon, 02 Feb 2026 12:06:43 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/a-practical-gitflow-setup-that-works-on-github-46lb</link>
      <guid>https://dev.to/playfulprogramming/a-practical-gitflow-setup-that-works-on-github-46lb</guid>
      <description>&lt;p&gt;I use GitFlow even for my side projects.&lt;/p&gt;

&lt;p&gt;Not because it is elegant. Not because it is modern. I use it because it forces me to behave like the project matters, even when nobody else is watching.&lt;/p&gt;

&lt;p&gt;When you work alone, shortcuts are tempting. You push directly to &lt;code&gt;main&lt;/code&gt;. You skip reviews. You promise yourself you will clean it up later. Later never comes. GitFlow, with the right rules, removes that option. It makes discipline the default instead of a personal choice.&lt;/p&gt;

&lt;p&gt;This is important to say upfront. GitFlow is not light. It adds structure, friction, and process. If you deploy to production ten times per day, GitFlow will slow you down. In that case, trunk-based development with feature flags is usually the better choice.&lt;/p&gt;

&lt;p&gt;But when you ship versioned releases, when you have a real staging phase, or when you want a clean separation between “work in progress” and “ready to release”, GitFlow still works well. Even for a solo developer.&lt;/p&gt;

&lt;p&gt;Everything in this article is what I actually run on GitHub today. On client projects (when they want to use GitFlow, of course). On open source. On side projects that may never make money.&lt;/p&gt;

&lt;p&gt;If you are going to use GitFlow, use it properly. Otherwise, do not use it at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2mqvl0cfa7ax722i3g2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2mqvl0cfa7ax722i3g2.png" alt="GitFlow Init" width="746" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. When GitFlow Makes Sense and When It Does Not
&lt;/h2&gt;

&lt;p&gt;GitFlow is a release model, not a productivity hack.&lt;/p&gt;

&lt;p&gt;I use it when the way I ship software matches the assumptions GitFlow makes. If those assumptions are wrong, the model fights you every day.&lt;/p&gt;

&lt;h3&gt;
  
  
  When GitFlow makes sense
&lt;/h3&gt;

&lt;p&gt;GitFlow works well for me in these cases.&lt;/p&gt;

&lt;p&gt;You ship &lt;strong&gt;versioned releases&lt;/strong&gt;. You care about &lt;code&gt;v1.2.3&lt;/code&gt; meaning something. You want a clear moment where a release is cut, stabilized, tested, and then shipped.&lt;/p&gt;

&lt;p&gt;You have a &lt;strong&gt;real staging phase&lt;/strong&gt;. Not “production with a flag”, but an environment where release candidates live, get tested, and sometimes get rejected.&lt;/p&gt;

&lt;p&gt;You need &lt;strong&gt;parallel workstreams&lt;/strong&gt;. New features continue on &lt;code&gt;develop&lt;/code&gt; while a release is being stabilized, or while a hotfix is being prepared.&lt;/p&gt;

&lt;p&gt;You want a &lt;strong&gt;hard separation between work in progress and releasable code&lt;/strong&gt;. &lt;code&gt;main&lt;/code&gt; always deployable. &lt;code&gt;develop&lt;/code&gt; allowed to move faster and break occasionally.&lt;/p&gt;

&lt;p&gt;In these scenarios, GitFlow reduces stress instead of adding it. The branches reflect reality.&lt;/p&gt;

&lt;h3&gt;
  
  
  When GitFlow is the wrong choice
&lt;/h3&gt;

&lt;p&gt;I avoid GitFlow in these situations.&lt;/p&gt;

&lt;p&gt;You deploy to production continuously. Multiple times per day. No staging. No release windows. In that world, GitFlow adds branches without adding safety.&lt;/p&gt;

&lt;p&gt;Your team already struggles to keep &lt;code&gt;develop&lt;/code&gt; stable. GitFlow assumes you can treat &lt;code&gt;develop&lt;/code&gt; as an integration gate. If you cannot, you are better off with trunk-based development and feature flags.&lt;/p&gt;

&lt;p&gt;You do not have environments to support it. No staging. No separation between integration and production. In that case, GitFlow becomes naming theater.&lt;/p&gt;

&lt;h3&gt;
  
  
  The most common mistake
&lt;/h3&gt;

&lt;p&gt;The worst setup I see is this.&lt;/p&gt;

&lt;p&gt;Teams adopt GitFlow “by the book”, but keep their old habits. Direct pushes sneak in. Hotfixes do not get merged back. Releases happen straight from &lt;code&gt;develop&lt;/code&gt; because it is “almost ready”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbj36d6v03epl9kxkdca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbj36d6v03epl9kxkdca.png" alt="GitFlow Workflow" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The GitFlow Branch Model I Actually Use on GitHub
&lt;/h2&gt;

&lt;p&gt;I keep the branch model boring and strict. No variations. No “almost GitFlow”. If I start bending the rules, the model stops working.&lt;/p&gt;

&lt;p&gt;These are the only branches I use.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;main&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;main&lt;/code&gt; is always releasable. Always.&lt;/p&gt;

&lt;p&gt;I never push directly to it. Not even for a typo. If &lt;code&gt;main&lt;/code&gt; is broken, the whole model failed upstream.&lt;/p&gt;

&lt;p&gt;What this gives me is simple. At any point in time, I can tag &lt;code&gt;main&lt;/code&gt; and ship. No excuses. No cleanup phase.&lt;/p&gt;

&lt;p&gt;If you cannot guarantee this, GitFlow gives you nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;develop&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;develop&lt;/code&gt; is my integration branch.&lt;/p&gt;

&lt;p&gt;This is where features meet. This is where conflicts show up early. This is where I accept temporary instability, but only temporarily.&lt;/p&gt;

&lt;p&gt;I treat &lt;code&gt;develop&lt;/code&gt; as protected, even when I work alone. No direct pushes. Always via pull request. That PR is my forced pause to think: is this actually ready to be integrated?&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;develop&lt;/code&gt; stays broken for days, GitFlow collapses. Integration must be frequent and boring.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;feature/*&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;All work starts here.&lt;/p&gt;

&lt;p&gt;Feature branches are short-lived by design. If a feature takes more than three to five days, I split it. Long-lived feature branches are the biggest source of merge pain and hidden risk.&lt;/p&gt;

&lt;p&gt;I do not optimize for “perfect feature branches”. I optimize for deleting them quickly.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;feature/auth-token-refresh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;feature/api-rate-limits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;feature/ui-settings-page&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once merged into &lt;code&gt;develop&lt;/code&gt;, the branch is gone. No reuse. No resurrection.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;release/*&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;I only create a &lt;code&gt;release/*&lt;/code&gt; branch when I actually need stabilization.&lt;/p&gt;

&lt;p&gt;If there is no staging phase, I skip release branches entirely. Creating them without a purpose is pure ceremony.&lt;/p&gt;

&lt;p&gt;A release branch exists to say one thing: no new features. Only fixes, hardening, documentation, and versioning.&lt;/p&gt;

&lt;p&gt;Typical names:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;release/1.4.0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;release/2026.02&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the release is ready, it gets merged into &lt;code&gt;main&lt;/code&gt;, tagged, and then merged back into &lt;code&gt;develop&lt;/code&gt;. Always both. This is where many teams drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;hotfix/*&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Hotfixes are rare. That is intentional.&lt;/p&gt;

&lt;p&gt;A hotfix starts from &lt;code&gt;main&lt;/code&gt;, never from &lt;code&gt;develop&lt;/code&gt;. It fixes production. Nothing else.&lt;/p&gt;

&lt;p&gt;After the fix, I merge it into &lt;code&gt;main&lt;/code&gt; and immediately back into &lt;code&gt;develop&lt;/code&gt;. Skipping the back-merge is the fastest way to reintroduce the same bug later.&lt;/p&gt;

&lt;p&gt;Names stay explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hotfix/login-nullref&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hotfix/payment-timeout&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hotfixes are treated with more care, not less.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Rules That Make GitFlow Work (And Why I Enforce Them on Myself)
&lt;/h2&gt;

&lt;p&gt;GitFlow without rules is just branch naming.&lt;/p&gt;

&lt;p&gt;I enforce the same rules on my side projects that I enforce on client projects. The reason is simple. If the setup only works when I am “careful”, it will fail under pressure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protected branches are non-negotiable
&lt;/h3&gt;

&lt;p&gt;I protect &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;develop&lt;/code&gt;. Always.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No direct pushes.&lt;/li&gt;
&lt;li&gt;No force pushes.&lt;/li&gt;
&lt;li&gt;No branch deletion.&lt;/li&gt;
&lt;li&gt;Pull requests only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even when I am the only contributor.&lt;/p&gt;

&lt;p&gt;This removes temptation. I cannot “just push a quick fix”. Every change goes through the same path. That consistency is the real value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull requests are mandatory checkpoints
&lt;/h3&gt;

&lt;p&gt;A pull request is not about collaboration. It is about forcing a decision point.&lt;/p&gt;

&lt;p&gt;Before merging, I answer a few basic questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why does this change exist?&lt;/li&gt;
&lt;li&gt;What exactly changed?&lt;/li&gt;
&lt;li&gt;How did I verify it works?&lt;/li&gt;
&lt;li&gt;What is the risk?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I cannot answer those clearly in a PR description, the change is not ready.&lt;/p&gt;

&lt;p&gt;This sounds heavy. In practice, it saves time. It avoids “I’ll fix it later” commits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe575r89phk5ubzjjiso0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe575r89phk5ubzjjiso0.png" alt="GitHub Protection Branches" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Approvals still matter, even solo
&lt;/h3&gt;

&lt;p&gt;I require at least one approval.&lt;/p&gt;

&lt;p&gt;Yes, I approve my own PRs. That is not the point.&lt;/p&gt;

&lt;p&gt;The point is the pause. The forced context switch. Opening the PR, reading the diff in GitHub, and approving it is different from pushing code from an editor.&lt;/p&gt;

&lt;p&gt;That pause catches mistakes more often than people expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conversation resolution is underrated
&lt;/h3&gt;

&lt;p&gt;I require all conversations to be resolved before merging.&lt;/p&gt;

&lt;p&gt;This prevents half-finished reviews and “we will come back to this” comments that never get addressed.&lt;/p&gt;

&lt;p&gt;If a comment exists, it deserves a decision. Fix it. Reject it. Explain it. Then resolve it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linear history vs merge commits
&lt;/h3&gt;

&lt;p&gt;This is where teams hurt themselves.&lt;/p&gt;

&lt;p&gt;If your team is comfortable with rebasing and understands it well, require a linear history. It keeps &lt;code&gt;develop&lt;/code&gt; clean.&lt;/p&gt;

&lt;p&gt;If not, allow merge commits. But standardize it. Do not mix strategies per PR.&lt;/p&gt;

&lt;p&gt;I personally use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Squash merge for &lt;code&gt;feature/*&lt;/code&gt; into &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge commits for &lt;code&gt;release/*&lt;/code&gt; and &lt;code&gt;hotfix/*&lt;/code&gt; into &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is not which option you pick. The key is that it is enforced, not debated every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Pull Requests as the Core Unit of Work
&lt;/h2&gt;

&lt;p&gt;In my setup, branches exist to create pull requests. Pull requests are the real workflow.&lt;/p&gt;

&lt;p&gt;If you get PRs right, GitFlow becomes manageable. If PRs are large, vague, or inconsistent, GitFlow falls apart.&lt;/p&gt;

&lt;h3&gt;
  
  
  A boring PR template on purpose
&lt;/h3&gt;

&lt;p&gt;I use the same PR template everywhere. It is intentionally simple.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt;: the problem or reason for the change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What&lt;/strong&gt;: what changed at a high level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How tested&lt;/strong&gt;: tests run, manual checks, environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk&lt;/strong&gt;: what could break&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollback&lt;/strong&gt;: how to undo it if needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not documentation. It is a forcing function. If I cannot fill this in quickly, the PR is probably doing too much.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small PRs beat clever branch strategies
&lt;/h3&gt;

&lt;p&gt;If a reviewer needs more than 30–45 minutes, the PR is too big.&lt;/p&gt;

&lt;p&gt;Large PRs hide bugs. They also create social pressure to approve without fully understanding the change. That is how regressions slip in.&lt;/p&gt;

&lt;p&gt;I optimize for PRs that can be reviewed quickly and confidently. That usually means slicing features into vertical, mergeable steps.&lt;/p&gt;

&lt;p&gt;GitFlow does not fix big PRs. It amplifies the pain if you allow them.&lt;/p&gt;

&lt;h3&gt;
  
  
  CODEOWNERS even for tiny repos
&lt;/h3&gt;

&lt;p&gt;I use &lt;code&gt;CODEOWNERS&lt;/code&gt; even when I am the only owner.&lt;/p&gt;

&lt;p&gt;It makes review routing explicit. It also prepares the repo for future contributors without rethinking the rules.&lt;/p&gt;

&lt;p&gt;More importantly, GitHub treats CODEOWNERS reviews differently. That gives you another enforcement layer, not another convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Naming, Traceability, and Future Me
&lt;/h2&gt;

&lt;p&gt;Most conventions exist for one reason. You will forget.&lt;/p&gt;

&lt;p&gt;Future me is the main consumer of my Git history. Not GitHub. Not tools. Me, six months later, trying to understand why something exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branch names should explain intent
&lt;/h3&gt;

&lt;p&gt;I use explicit branch names. Not clever ones.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feature/login&lt;/code&gt; tells me nothing.&lt;br&gt;
&lt;code&gt;feature/oauth-token-refresh&lt;/code&gt; tells me exactly what problem was being solved.&lt;/p&gt;

&lt;p&gt;If I use an issue tracker, I include the ID:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;feature/ABC-123-oauth-token-refresh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This costs seconds. It saves minutes every time I search history.&lt;/p&gt;
&lt;h3&gt;
  
  
  PR titles are part of the changelog
&lt;/h3&gt;

&lt;p&gt;I treat PR titles as public API.&lt;/p&gt;

&lt;p&gt;Release notes, changelogs, and audit trails are generated from them. If the title is vague, everything downstream becomes vague.&lt;/p&gt;

&lt;p&gt;I avoid “fix stuff” or “cleanup”. I prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fix token refresh race condition”&lt;/li&gt;
&lt;li&gt;“Add rate limiting to public API”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I cannot summarize the change in one sentence, the PR is probably too large.&lt;/p&gt;
&lt;h3&gt;
  
  
  Link everything, even when it feels redundant
&lt;/h3&gt;

&lt;p&gt;I always link PRs to issues. Always.&lt;/p&gt;

&lt;p&gt;Even on side projects. Even when the issue only exists to track the PR.&lt;/p&gt;

&lt;p&gt;GitHub already gives you the syntax. Use it.&lt;br&gt;
&lt;code&gt;Closes #123&lt;/code&gt; is enough.&lt;/p&gt;

&lt;p&gt;This creates a navigable graph. Branch to PR. PR to issue. Issue to release. Without links, GitFlow loses one of its biggest advantages.&lt;/p&gt;
&lt;h3&gt;
  
  
  Traceability must be enforced, not suggested
&lt;/h3&gt;

&lt;p&gt;If traceability is optional, it will be skipped.&lt;/p&gt;

&lt;p&gt;I enforce naming and linking through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch naming patterns&lt;/li&gt;
&lt;li&gt;PR templates&lt;/li&gt;
&lt;li&gt;Required checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not bureaucracy. The goal is predictability.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why this matters more with GitFlow
&lt;/h3&gt;

&lt;p&gt;GitFlow creates more branches than trunk-based development. That increases cognitive load.&lt;/p&gt;

&lt;p&gt;Naming and traceability reduce that load. They make the model survivable over time.&lt;/p&gt;

&lt;p&gt;In the next section, I will map this structure to &lt;strong&gt;CI/CD pipelines&lt;/strong&gt;, and explain what I run where, and why.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwinolm9tuo3v1y0etxon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwinolm9tuo3v1y0etxon.png" alt="GitFlow on GitKraken" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Naming, Traceability, and Future Me
&lt;/h2&gt;

&lt;p&gt;Most conventions exist for one reason. You will forget.&lt;/p&gt;

&lt;p&gt;Future me is the main consumer of my Git history. Not GitHub. Not tools. Me, six months later, trying to understand why something exists.&lt;/p&gt;
&lt;h3&gt;
  
  
  Branch names should explain intent
&lt;/h3&gt;

&lt;p&gt;I use explicit branch names. Not clever ones.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;feature/login&lt;/code&gt; tells me nothing.&lt;br&gt;
&lt;code&gt;feature/oauth-token-refresh&lt;/code&gt; tells me exactly what problem was being solved.&lt;/p&gt;

&lt;p&gt;If I use an issue tracker, I include the ID:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;feature/ABC-123-oauth-token-refresh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This costs seconds. It saves minutes every time I search history.&lt;/p&gt;
&lt;h3&gt;
  
  
  PR titles are part of the changelog
&lt;/h3&gt;

&lt;p&gt;I treat PR titles as public API.&lt;/p&gt;

&lt;p&gt;Release notes, changelogs, and audit trails are generated from them. If the title is vague, everything downstream becomes vague.&lt;/p&gt;

&lt;p&gt;I avoid “fix stuff” or “cleanup”. I prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fix token refresh race condition”&lt;/li&gt;
&lt;li&gt;“Add rate limiting to public API”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I cannot summarize the change in one sentence, the PR is probably too large.&lt;/p&gt;
&lt;h3&gt;
  
  
  Link everything, even when it feels redundant
&lt;/h3&gt;

&lt;p&gt;I always link PRs to issues. Always.&lt;/p&gt;

&lt;p&gt;Even on side projects. Even when the issue only exists to track the PR.&lt;/p&gt;

&lt;p&gt;GitHub already gives you the syntax. Use it.&lt;br&gt;
&lt;code&gt;Closes #123&lt;/code&gt; is enough.&lt;/p&gt;

&lt;p&gt;This creates a navigable graph. Branch to PR. PR to issue. Issue to release. Without links, GitFlow loses one of its biggest advantages.&lt;/p&gt;
&lt;h3&gt;
  
  
  Traceability must be enforced, not suggested
&lt;/h3&gt;

&lt;p&gt;If traceability is optional, it will be skipped.&lt;/p&gt;

&lt;p&gt;I enforce naming and linking through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch naming patterns&lt;/li&gt;
&lt;li&gt;PR templates&lt;/li&gt;
&lt;li&gt;Required checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not bureaucracy. The goal is predictability.&lt;/p&gt;
&lt;h2&gt;
  
  
  8. Releases, Tags, and Changelogs I Can Trust
&lt;/h2&gt;

&lt;p&gt;Releases are not a side effect. They are a deliberate action.&lt;/p&gt;

&lt;p&gt;GitFlow only pays off if releases are predictable and traceable. That starts with being strict about where and how you tag.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tags exist only on &lt;code&gt;main&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;I tag releases only on &lt;code&gt;main&lt;/code&gt;. No exceptions.&lt;/p&gt;

&lt;p&gt;If a tag exists anywhere else, it lies. A tag should mean “this is what went to production” or “this is the shipped artifact”.&lt;/p&gt;

&lt;p&gt;Tagging on &lt;code&gt;develop&lt;/code&gt; or &lt;code&gt;release/*&lt;/code&gt; breaks that guarantee and creates confusion later when you try to answer a simple question: what is actually running?&lt;/p&gt;
&lt;h3&gt;
  
  
  Release branches are not releases
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;release/*&lt;/code&gt; branch is a candidate. Not a promise.&lt;/p&gt;

&lt;p&gt;It can be delayed. It can be fixed. It can even be abandoned. That is fine.&lt;/p&gt;

&lt;p&gt;The release only exists when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The release branch is merged into &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A tag is created on &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anything else is pre-release noise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1qafc798dvm0gk17w5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1qafc798dvm0gk17w5y.png" alt="Semantic Versioning" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Versioning decisions are made early
&lt;/h3&gt;

&lt;p&gt;I decide versioning strategy at the start of a project, not during the first release.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic versioning when public contracts matter&lt;/li&gt;
&lt;li&gt;Date-based versioning for internal tools or fast-moving products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing versioning mid-stream creates churn and inconsistent expectations. Pick one and live with it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Changelogs are generated, not remembered
&lt;/h3&gt;

&lt;p&gt;I do not write changelogs by hand.&lt;/p&gt;

&lt;p&gt;They are generated from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PR titles&lt;/li&gt;
&lt;li&gt;Labels&lt;/li&gt;
&lt;li&gt;Commit history on &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why PR titles matter. Sloppy titles produce useless release notes.&lt;br&gt;
(Actually GitHub Copilot helps me a lot to create these ones and commit messages)&lt;/p&gt;
&lt;h2&gt;
  
  
  9. Environments or GitFlow Is Just Ritual
&lt;/h2&gt;

&lt;p&gt;GitFlow assumes environments. Without them, you are just renaming branches.&lt;/p&gt;

&lt;p&gt;I see many setups where GitFlow exists on paper, but everything deploys to the same place. In that case, the extra branches add zero value.&lt;/p&gt;
&lt;h3&gt;
  
  
  The minimum environment setup I use
&lt;/h3&gt;

&lt;p&gt;I keep it simple. Three environments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dev / Integration&lt;/strong&gt;&lt;br&gt;
Automatically deployed from &lt;code&gt;develop&lt;/code&gt;. This is where features meet and conflicts surface early.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Staging&lt;/strong&gt;&lt;br&gt;
Deployed from &lt;code&gt;release/*&lt;/code&gt;. This environment exists to say “no”. If something fails here, the release is not ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Production&lt;/strong&gt;&lt;br&gt;
Deployed from &lt;code&gt;main&lt;/code&gt;. Always. No exceptions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you cannot support at least this, GitFlow will not protect you.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why each environment matters
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;develop&lt;/code&gt; needs a shared place where the system actually runs. Unit tests are not enough. Integration bugs appear only when components talk to each other.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;release/*&lt;/code&gt; needs a stable environment. The whole point of a release branch is to freeze scope and validate reality.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main&lt;/code&gt; maps one-to-one with production. If you blur this line, you lose confidence in every tag and every rollback.&lt;/p&gt;
&lt;h3&gt;
  
  
  GitFlow without environments is overhead
&lt;/h3&gt;

&lt;p&gt;Branches alone do not reduce risk. Feedback loops do.&lt;/p&gt;

&lt;p&gt;If all feedback arrives only after merging to &lt;code&gt;main&lt;/code&gt;, GitFlow becomes slower trunk-based development, nothing more.&lt;/p&gt;

&lt;p&gt;In the next section, I will explain how I handle &lt;strong&gt;hotfixes&lt;/strong&gt;, and why this is where most teams break the model.&lt;/p&gt;
&lt;h2&gt;
  
  
  10. Handling Hotfixes Without Breaking the Model
&lt;/h2&gt;

&lt;p&gt;Hotfixes are where GitFlow discipline is tested.&lt;/p&gt;

&lt;p&gt;They arrive under pressure. Something is broken. Time matters. This is exactly when shortcuts feel justified. That is also when long-term damage happens.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hotfixes start from &lt;code&gt;main&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A hotfix always branches from &lt;code&gt;main&lt;/code&gt;. Never from &lt;code&gt;develop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main&lt;/code&gt; represents what is running in production. If you start a hotfix anywhere else, you are guessing what you are fixing.&lt;/p&gt;

&lt;p&gt;The goal of a hotfix is simple. Fix production. Nothing more.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scope is deliberately small
&lt;/h3&gt;

&lt;p&gt;A hotfix branch contains the minimal change required to restore service.&lt;/p&gt;

&lt;p&gt;No refactoring. No cleanup. No “since we are here” improvements. Those belong on &lt;code&gt;develop&lt;/code&gt; or in a future release.&lt;/p&gt;

&lt;p&gt;Every extra change increases risk at the worst possible moment.&lt;/p&gt;
&lt;h3&gt;
  
  
  CI and reviews still apply
&lt;/h3&gt;

&lt;p&gt;I do not disable checks for hotfixes.&lt;/p&gt;

&lt;p&gt;Pipelines might be slightly faster. Reviews might be faster. But rules still apply.&lt;/p&gt;

&lt;p&gt;Hotfixes are urgent, not special.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why teams drift here
&lt;/h3&gt;

&lt;p&gt;Under pressure, people optimize for now. GitFlow optimizes for later.&lt;/p&gt;

&lt;p&gt;Skipping the back-merge or bypassing rules feels harmless in the moment. It creates invisible debt that surfaces weeks later.&lt;/p&gt;

&lt;p&gt;If your GitFlow setup cannot survive hotfix pressure, it is not real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf0yl4wzym0ihhfv04vl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf0yl4wzym0ihhfv04vl.png" alt="Merge Conflicts" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  11. Merge Conflicts and How I Keep Them Boring
&lt;/h2&gt;

&lt;p&gt;Merge conflicts are not a Git problem. They are a workflow problem.&lt;/p&gt;

&lt;p&gt;Every painful conflict I have dealt with had the same root cause. Branches lived too long.&lt;/p&gt;
&lt;h3&gt;
  
  
  Short-lived branches solve most conflicts
&lt;/h3&gt;

&lt;p&gt;I keep feature branches short. Days, not weeks.&lt;/p&gt;

&lt;p&gt;If a feature cannot be merged within three to five days, I split it. Vertical slices. Mergeable steps. Incremental progress.&lt;/p&gt;

&lt;p&gt;This single habit reduces conflicts more than any Git command ever will.&lt;/p&gt;
&lt;h2&gt;
  
  
  12. GitHub Actions Patterns I Reuse Everywhere
&lt;/h2&gt;

&lt;p&gt;Automation is what makes GitFlow survivable long term.&lt;/p&gt;

&lt;p&gt;If the workflow depends on people remembering rules, it will degrade. GitHub Actions are there to make the right path the default path.&lt;/p&gt;
&lt;h3&gt;
  
  
  Required checks are gates, not guidelines
&lt;/h3&gt;

&lt;p&gt;Every protected branch has required checks.&lt;/p&gt;

&lt;p&gt;If a check is required, the PR cannot merge. No override. No “just this once”.&lt;/p&gt;

&lt;p&gt;This removes social pressure. The system says no, not a person.&lt;/p&gt;

&lt;p&gt;I treat required checks as part of the branch contract. If they are flaky or slow, I fix the checks. I do not remove the requirement.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reusable workflows or nothing
&lt;/h3&gt;

&lt;p&gt;I do not copy-paste workflows across repositories.&lt;/p&gt;

&lt;p&gt;I use reusable workflows so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same rules apply everywhere&lt;/li&gt;
&lt;li&gt;Changes are made once&lt;/li&gt;
&lt;li&gt;Drift is impossible&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Environment protection is part of GitFlow
&lt;/h3&gt;

&lt;p&gt;For production deployments, I use GitHub environments with protection rules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required reviewers&lt;/li&gt;
&lt;li&gt;Scoped secrets&lt;/li&gt;
&lt;li&gt;Explicit approval step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This adds a final safety net without bypassing GitFlow.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;main&lt;/code&gt; deploys to production, production must be protected.&lt;/p&gt;
&lt;h3&gt;
  
  
  Secrets and permissions are minimal
&lt;/h3&gt;

&lt;p&gt;Workflows get only the permissions they need. No wildcard tokens. No long-lived secrets when OIDC is available.&lt;/p&gt;

&lt;p&gt;This matters more as automation grows. GitFlow increases automation surface. Least privilege keeps that surface manageable.&lt;/p&gt;
&lt;h2&gt;
  
  
  13. Security and Governance I Enable by Default
&lt;/h2&gt;

&lt;p&gt;Security and governance are not enterprise-only concerns. I enable them even on side projects. Especially on side projects.&lt;/p&gt;

&lt;p&gt;If the repo matters enough to use GitFlow, it matters enough to protect it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dependabot is always on
&lt;/h3&gt;

&lt;p&gt;I enable Dependabot alerts and PRs by default.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alerts tell me when I am exposed.&lt;/li&gt;
&lt;li&gt;PRs force the fix through the same PR rules as any other change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I never update dependencies directly on protected branches. Updates go through PRs, checks, and reviews like everything else.&lt;/p&gt;
&lt;h3&gt;
  
  
  Code scanning is part of the pipeline
&lt;/h3&gt;

&lt;p&gt;At minimum, I run code scanning on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;develop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This catches obvious issues early and prevents shipping known problems.&lt;/p&gt;

&lt;p&gt;I do not chase perfect security scores. I want signal, not noise. But no scanning at all is not an option.&lt;/p&gt;
&lt;h2&gt;
  
  
  14. In a nutshell, what I do (copy this section)
&lt;/h2&gt;

&lt;p&gt;This is the setup I apply by default. On client projects. On open source. On side projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  Branches
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;main&lt;/code&gt;&lt;br&gt;
Always releasable. Production only.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;develop&lt;/code&gt;&lt;br&gt;
Integration branch. Can move fast, but must stay usable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;feature/*&lt;/code&gt;&lt;br&gt;
Short-lived. One purpose. Merged into &lt;code&gt;develop&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;release/*&lt;/code&gt;&lt;br&gt;
Created only when a real stabilization phase exists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;hotfix/*&lt;/code&gt;&lt;br&gt;
Urgent fixes from &lt;code&gt;main&lt;/code&gt;. Always merged back.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Protection rules
&lt;/h3&gt;

&lt;p&gt;Protected branches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;main&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;develop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;release/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hotfix/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rules applied:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull requests required&lt;/li&gt;
&lt;li&gt;At least one approval&lt;/li&gt;
&lt;li&gt;Required status checks&lt;/li&gt;
&lt;li&gt;Conversation resolution required&lt;/li&gt;
&lt;li&gt;No direct pushes&lt;/li&gt;
&lt;li&gt;No force pushes&lt;/li&gt;
&lt;li&gt;No branch deletion&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Pull request rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mandatory PR template: Why, What, How tested, Risk, Rollback&lt;/li&gt;
&lt;li&gt;Small PRs by design&lt;/li&gt;
&lt;li&gt;CODEOWNERS enabled&lt;/li&gt;
&lt;li&gt;One merge strategy enforced&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Merge strategy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Squash merge for &lt;code&gt;feature/*&lt;/code&gt; into &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge commits for &lt;code&gt;release/*&lt;/code&gt; and &lt;code&gt;hotfix/*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No rebasing of shared branches&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  CI/CD
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feature/*&lt;/code&gt;: build, unit tests, lint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;develop&lt;/code&gt;: full test suite, security checks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;release/*&lt;/code&gt;: full suite, packaging, deploy to staging&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: production deploy, tag, changelog&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Releases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tags on &lt;code&gt;main&lt;/code&gt; only&lt;/li&gt;
&lt;li&gt;Semantic or date-based versioning decided early&lt;/li&gt;
&lt;li&gt;Changelogs generated from PR metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Environments
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;develop&lt;/code&gt; → dev/integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;release/*&lt;/code&gt; → staging&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; → production&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Hotfix discipline
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Branch from &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Minimal scope&lt;/li&gt;
&lt;li&gt;Merge to &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge back to &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No skipped steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This policy is intentionally boring. Boring scales.&lt;/p&gt;


&lt;h3&gt;
  
  
  👀 GitHub Copilot quota visibility in VS Code
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqzk5hamyymcmuh515a4.png" width="700" height="700"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;If you use GitHub Copilot and ever wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what plan you’re on&lt;/li&gt;
&lt;li&gt;whether you have limits&lt;/li&gt;
&lt;li&gt;how much premium quota is left&lt;/li&gt;
&lt;li&gt;when it resets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small VS Code extension called &lt;strong&gt;Copilot Insights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows Copilot &lt;strong&gt;plan and quota status&lt;/strong&gt; directly inside VS Code.&lt;br&gt;&lt;br&gt;
No usage analytics. No productivity scoring. Just clarity.&lt;/p&gt;

&lt;p&gt;👉 VS Code Marketplace:&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=emanuelebartolesi.vscode-copilot-insights&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>gitflow</category>
    </item>
    <item>
      <title>How I created a Cozy Workspace in VS Code</title>
      <dc:creator>Emanuele Bartolesi</dc:creator>
      <pubDate>Thu, 11 Dec 2025 15:54:26 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/how-i-created-a-cozy-workspace-in-vs-code-4bf0</link>
      <guid>https://dev.to/playfulprogramming/how-i-created-a-cozy-workspace-in-vs-code-4bf0</guid>
      <description>&lt;p&gt;I love VS Code. It is fast, flexible, and works for almost any stack. But the default layout is not great if you want a clean space to think. The editor area is smaller than it should be, and the UI is packed with elements that pull attention away from the code. With the new Copilot Chat panel taking even more space, the problem becomes obvious. Too much noise, not enough room to work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5r5wccr9kd6xos8y0l1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5r5wccr9kd6xos8y0l1.png" alt="VS Code Default Layout" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the picture above, the default layout, with Copilot opened on the right, the space for code is really limited.&lt;/p&gt;

&lt;p&gt;I have been searching for a layout that removes distractions without sacrificing functionality. Something simple, comfortable, and optimized for long sessions. This article explains the setup I finally arrived at. It is a &lt;em&gt;Productivity&lt;/em&gt; profile built around a few key layout changes: moving the sidebar to the right, putting the Activity Bar at the top, centering Quick Input, hiding the Command Center, switching themes automatically based on daylight, improving cursor visibility, and adding one small bonus to make the day more pleasant.&lt;/p&gt;

&lt;p&gt;These changes are minimal but have a clear impact. They turn VS Code into a focused, cozy environment that gives space back to the code instead of the UI.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a Dedicated “Productivity” Profile
&lt;/h2&gt;

&lt;p&gt;VS Code profiles let you build isolated setups for different workflows. This solves a common problem. When you install extensions or change layout settings for one project, everything else gets affected. A dedicated &lt;em&gt;Productivity&lt;/em&gt; profile keeps your focused environment clean and consistent.&lt;/p&gt;

&lt;p&gt;I use this profile only for work sessions. For the training session I usually have, of course I still use the Default profile, otherwise the people are confused and lost.&lt;/p&gt;

&lt;p&gt;Creating the new profile takes a minute:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Command Palette.&lt;/li&gt;
&lt;li&gt;Run &lt;strong&gt;Profiles: Create Profile&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Empty&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name it &lt;strong&gt;Productivity&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Customize settings only for this profile.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also click on the &lt;strong&gt;Gear&lt;/strong&gt; icon on the bottom left and select "Profiles" from the menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjlckxu0kf9gwem00ny2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjlckxu0kf9gwem00ny2.png" alt="Create a new profile" width="528" height="332"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving the Primary Sidebar to the Right
&lt;/h2&gt;

&lt;p&gt;By default, VS Code puts the sidebar on the left. This works, but it also competes with your natural reading flow. Having the file tree on the left constantly pulls the eye away from the editor.&lt;br&gt;
Also, when you close the sidebar, the code moves a little bit on the left, because the sidebar is not present anymore.&lt;/p&gt;

&lt;p&gt;Moving the sidebar to the right reduces this tension. It keeps the editor centered and makes the coding area the first thing your eyes land on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.sideBar.location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"right"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can also click with the right button on the sidebar and select "Move Primary Sidebar Right".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd8dwljxzizkerijyrk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd8dwljxzizkerijyrk5.png" alt="Move Primary Sidebar Right" width="307" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple switch makes the layout feel more balanced and less cluttered.&lt;/p&gt;


&lt;h2&gt;
  
  
  Activity Bar at the Top
&lt;/h2&gt;

&lt;p&gt;The Activity Bar is highly visible. Keeping it on the left (or right, if the primary sidebar is on the right) creates unnecessary vertical columns. Moving it to the top uses horizontal space instead of eating into the editor.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.activityBar.location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"top"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It's possible to change the same settings, even by clicking on the top of the sidebar and choose &lt;strong&gt;Top&lt;/strong&gt; from the &lt;strong&gt;Activity Bar Position&lt;/strong&gt; menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov7dptqftxgdsl1bzxhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov7dptqftxgdsl1bzxhq.png" alt="Activity Bar Position" width="487" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This change pairs well with the right-aligned sidebar and creates a cleaner overall layout.&lt;/p&gt;


&lt;h2&gt;
  
  
  Centering Quick Input for Better Focus
&lt;/h2&gt;

&lt;p&gt;The Command Palette and file switcher usually appear at the top. This forces a constant eye shift upward. Centering Quick Input keeps everything in your immediate focus area.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.quickInput.location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is especially useful if you use the keyboard heavily.&lt;/p&gt;


&lt;h2&gt;
  
  
  Hiding the Command Center
&lt;/h2&gt;

&lt;p&gt;If you already use keyboard shortcuts and the centered Quick Input, the Command Center becomes redundant. It adds noise without adding value.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"window.commandCenter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Hiding it cleans up the top UI and keeps attention on the code.&lt;/p&gt;


&lt;h2&gt;
  
  
  Move the Menu bar
&lt;/h2&gt;

&lt;p&gt;How often do you use the Menu? I think not so much, so, you can use that space for something else by changing the position of the menu, on the top of the Activity Bar.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"window.menuBarVisibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"compact"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you want to use the UI to change this settings, click on the &lt;strong&gt;Customize Layout&lt;/strong&gt; on the top right corner of VS Code window and change the Visibility of the Menu Bar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukui96lv23b2mmlgk0xy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukui96lv23b2mmlgk0xy.png" alt="Menu Bar" width="609" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One more row is saved but first of all you are not distracted by the menu items on the top.&lt;/p&gt;


&lt;h2&gt;
  
  
  Automatic Light/Dark Theme Switching With PowerToys LightSwitch
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/powertoys/" rel="noopener noreferrer"&gt;PowerToys LightSwitch&lt;/a&gt; changes your Windows theme based on sunrise and sunset. VS Code can detect this automatically and switch between your preferred light and dark themes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.preferredDarkColorTheme"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JetBrains Rider Dark Theme"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"workbench.preferredLightColorTheme"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Default Light+"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"window.autoDetectColorScheme"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I use the JetBrains Rider Dark theme because I also use it on Rider, and it helps me stay focused when switching between IDEs.&lt;/p&gt;

&lt;p&gt;This keeps the editor comfortable throughout the day with zero manual work.&lt;/p&gt;


&lt;h2&gt;
  
  
  Improving Cursor Visibility With “Expand” Blinking
&lt;/h2&gt;

&lt;p&gt;The default cursor blink is subtle. In a busy file, it is easy to lose track of it. The “expand” style is more visible without being distracting.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"editor.cursorBlinking"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expand"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A small tweak, but surprisingly helpful.&lt;/p&gt;


&lt;h2&gt;
  
  
  Bonus: A Bit of Fun With VS Code Pets
&lt;/h2&gt;

&lt;p&gt;A cozy environment should be enjoyable, not just efficient. The &lt;strong&gt;VS Code Pets&lt;/strong&gt; extension adds a small animated pet to your workspace. It keeps you company during long sessions and adds a bit of charm without affecting focus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q65fseydgmjk0ug12gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q65fseydgmjk0ug12gk.png" alt="VS Code Pets" width="432" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is optional, but it makes the environment feel more human.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;A cozy development environment is not about adding more tools. It is about removing friction. By focusing only on VS Code's layout settings, you can reclaim space, reduce noise, and make the editor feel purpose-built for deep work.&lt;/p&gt;

&lt;p&gt;In the screenshot below, you can see the final result after all these easy changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjny7tun8120fq5lx4ya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjny7tun8120fq5lx4ya.png" alt="Final Result" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to spend time changing all the settings manually, you can find all my settings in the following repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/kasuken" rel="noopener noreferrer"&gt;
        kasuken
      &lt;/a&gt; / &lt;a href="https://github.com/kasuken/Windows11-Setup" rel="noopener noreferrer"&gt;
        Windows11-Setup
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      My settings for Windows 11 and other tools I use everyday.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/cc903eb49e41de41b53fed3cf9f34b74d76eff26cfd8cc00307d7aa129f25301/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f57696e646f777325323031312d53657475702d626c75653f6c6f676f3d77696e646f7773"&gt;&lt;img src="https://camo.githubusercontent.com/cc903eb49e41de41b53fed3cf9f34b74d76eff26cfd8cc00307d7aa129f25301/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f57696e646f777325323031312d53657475702d626c75653f6c6f676f3d77696e646f7773" alt="Windows 11 Setup" height="32"&gt;&lt;/a&gt;
  &lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Windows 11 Setup &amp;amp; Automation&lt;/h1&gt;
&lt;/div&gt;


&lt;p&gt;&lt;b&gt;Automate, configure, and optimize your Windows 11 environment with ease.&lt;/b&gt;&lt;/p&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Overview&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;This repository provides a &lt;strong&gt;comprehensive, automated, and customizable setup&lt;/strong&gt; for Windows 11. It includes PowerShell scripts, terminal and VS Code configurations, and best practices to help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up a new Windows 11 machine in minutes&lt;/li&gt;
&lt;li&gt;Apply productivity-boosting tweaks&lt;/li&gt;
&lt;li&gt;Install essential tools and extensions&lt;/li&gt;
&lt;li&gt;Maintain a consistent, portable dev environment&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📦 Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PowerShell Automation&lt;/strong&gt;: Scripts for system tweaks, package installs, and profile management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal Customization&lt;/strong&gt;: Pre-configured settings for Windows Terminal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code Setup&lt;/strong&gt;: Recommended extensions and settings for a modern dev workflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular Structure&lt;/strong&gt;: Use only what you need—easy to extend and adapt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: Clear instructions for every step&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🗂️ Repository Structure&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;Windows11-Setup/
├── PowerShell/         # PowerShell scripts and user profile
│   └── profile.ps1
├── Terminal/           # Windows Terminal settings
│   └── settings.json
├── VSCode/             # VS Code&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kasuken/Windows11-Setup" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;This layout turned VS Code into a cleaner and more intentional workspace for me. If you try it or customize it, share your version. Every developer ends up with their own definition of cozy.&lt;/p&gt;




&lt;p&gt;📘 &lt;strong&gt;Get the Book with 50% Off!&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;I turned my beginner programming mistakes into a guide so you don’t have to repeat them.&lt;br&gt;&lt;br&gt;
Grab &lt;strong&gt;The Mistakes I Made as a Beginner Programmer&lt;/strong&gt; today with a special discount.  &lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://emanuelebartolesi.gumroad.com/l/mistakesasdeveloper/MISTAKESDEVTO50" rel="noopener noreferrer"&gt;Get it on Gumroad&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💸 Use code &lt;strong&gt;MISTAKESDEVTO50&lt;/strong&gt; at checkout for &lt;strong&gt;50% off&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>development</category>
      <category>githubcopilot</category>
    </item>
  </channel>
</rss>
