<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Barak on Code]]></title><description><![CDATA[Detailed technical articles for all categories of software developers.]]></description><link>https://blog.barakimam.me</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1575107508943/gVWKv2y6n.png</url><title>Barak on Code</title><link>https://blog.barakimam.me</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 06:53:16 GMT</lastBuildDate><atom:link href="https://blog.barakimam.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Running VS Code Devcontainers with X86_64 Runtime on Apple Silicon]]></title><description><![CDATA[This article will guide you through the steps required to run X86_64 containers on Apple Silicon machines. Although Docker Desktop for Mac added beta support for X86_64 emulation via Rosetta in version 4.16.0, it doesn’t work for some X86_64 containe...]]></description><link>https://blog.barakimam.me/running-vs-code-devcontainers-with-x8664-runtime-on-apple-silicon</link><guid isPermaLink="true">https://blog.barakimam.me/running-vs-code-devcontainers-with-x8664-runtime-on-apple-silicon</guid><category><![CDATA[virtualization]]></category><category><![CDATA[QEMU]]></category><category><![CDATA[colima]]></category><category><![CDATA[Docker]]></category><category><![CDATA[devcontainer]]></category><dc:creator><![CDATA['Barak Imam]]></dc:creator><pubDate>Tue, 18 Apr 2023 10:19:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681813175368/8f9a9702-99b6-4bf7-a1b2-cf7700d41c89.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article will guide you through the steps required to run <code>X86_64</code> containers on Apple Silicon machines. Although Docker Desktop for Mac added beta support for <code>X86_64</code> emulation via Rosetta in version <a target="_blank" href="https://docs.docker.com/desktop/release-notes/#4160">4.16.0</a>, it doesn’t work for some <code>X86_64</code> containers, such as oracle-xe container images. A unique issue with VS Code Devcontainers is that it selects its container runtime based on the docker runtime. This means that it will always try to use <code>ARM64</code> images, regardless of whether you have Rosetta emulation enabled or not.</p>
<h2 id="heading-background">Background</h2>
<p>Recently, I had to work on a Python project that depended on some libraries which appear to only work on <code>X86_64</code> machines, I came across Colima during my struggles with getting <code>oracle-xe</code> containers to work on my machine and settled completely with it after this episode of failing to run <code>X86_64</code> dev containers with Docker Desktop.</p>
<h2 id="heading-hello-colima">Hello Colima,</h2>
<p><a target="_blank" href="https://github.com/abiosoft/colima">Colima</a>, literally meaning <strong>Co</strong>ntainers in <strong>Li</strong>nux on <strong>ma</strong>cOS is a container runtime with minimal setup. it boasts several awesome features, including the ability to run multiple Linux instances, support for both docker and container runtimes and lightweight Kubernetes clusters powered by <a target="_blank" href="https://k3s.io/">k3s</a>.</p>
<p>I settled for Colima due to the following reasons;</p>
<ol>
<li><p>Support for everything I get from Docker Desktop (I don't use Docker extensions, although I got the lead from <code>oracle-xe</code> from a Docker desktop plugin)</p>
</li>
<li><p>QEMU-powered <code>X86_64</code> emulation for the <code>X86_64</code> runtime (may be slow, but has better compatibility than the Rosetta-based emulation in Docker Desktop).</p>
</li>
<li><p>Run two or more docker runtimes at the same time (I prefer to continue running my arm native tools in an arm-based docker instance).</p>
</li>
<li><p>Spin up a <code>k3s</code> Kubernetes cluster the easiest way.</p>
</li>
</ol>
<h2 id="heading-docker-contexts">Docker Contexts</h2>
<p><a target="_blank" href="https://docs.docker.com/engine/context/working-with-contexts/#introduction">Docker Contexts</a> is a Docker CLI feature that enables a single Docker CLI installation to manage multiple Docker hosts, swarm clusters, and even Kubernetes clusters.</p>
<p>Colima rides on this feature to provide great features like running multiple Linux instances on a single machine and using docker context, you can easily switch, and manage container deployments across several docker instances, including instances not managed by Colima (e.g Docker Desktop).</p>
<h2 id="heading-vs-code-dev-containers">VS Code Dev Containers</h2>
<p>For developers who do not like clogging their dev machines with all the tools, <a target="_blank" href="https://containers.dev/">Development Container (or Dev Container for short)</a> allows you to use a container as a full-featured development environment. It can be used to run an application, to separate tools, libraries, or runtimes needed for working with a codebase, and to aid in continuous integration and testing. Dev containers can be run locally or remotely, in a private or public cloud.</p>
<p>Visual Studio Code has the VS Code Dev Container plugin that simplifies the process to spin up development containers right within the editor. While it has support for most CPU architecture, it derives the instantiated container architecture based on the OS architecture of the active Docker context.</p>
<p>This means that to run an <code>X86_64</code> devcontainer, you need to ensure that the active Docker context is based on the <code>X86_64</code> architecture. This can be verified by doing the following:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># start X86_64 container in colima (skip if you already have an X86_64 docker instance)</span>
colima start --arch x86_64 -p qemu

<span class="hljs-comment"># review available docker contexts</span>
docker context list

<span class="hljs-comment"># switch active docker context to an X86_64 instance (colima instances are always prefixed with 'colima-'</span>
docker context use colima-qemu
</code></pre>
<p>You can easily switch back to any other context, once the devcontainer is running.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Using this approach, we can successfully run X86_64 (aka AMD64) development workloads on Apple Silicon without spinning up a full-fledged virtual machine.</p>
<p>Maybe this approach can be used to achieve the reverse (ARM64 workloads on X86_64 machines), I am not sure, but it may one day be worth the try for me.</p>
]]></content:encoded></item><item><title><![CDATA[Introducing TinySaas: a library for building multitenant applications in ASP.NET Core]]></title><description><![CDATA[Some years back, I used to maintain a SaaS application built on ASP.NET WebForms. Many organizations are aiming to migrate existing applications built on the ASP.NET Framework to the amazing .NET Core.
TinySaas culminated from my work in migrating an...]]></description><link>https://blog.barakimam.me/introducing-tinysaas-a-library-for-building-multitenant-applications-in-aspnet-core</link><guid isPermaLink="true">https://blog.barakimam.me/introducing-tinysaas-a-library-for-building-multitenant-applications-in-aspnet-core</guid><category><![CDATA[asp.net core]]></category><category><![CDATA[SaaS]]></category><category><![CDATA[dependency injection]]></category><dc:creator><![CDATA['Barak Imam]]></dc:creator><pubDate>Mon, 13 Jul 2020 23:43:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1594683708670/-_0xoiZgw.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Some years back, I used to maintain a SaaS application built on ASP.NET WebForms. Many organizations are aiming to migrate existing applications built on the ASP.NET Framework to the amazing .NET Core.</p>
<p>TinySaas culminated from my work in migrating an ASP.NET legacy application to ASP.NET Core.</p>
<hr />
<h1 id="why-tinysaas">Why TinySaas?</h1>
<p>There abound on the internet several frameworks that aim to allow developers to build multitenant applications using the .NET Core Framework, but the keyword (<strong>Framework</strong>).</p>
<p>TinySaas is a library that aims to add multitenancy support to new and existing ASP.NET Core applications without forcing the adoption of a new framework.</p>
<p>The credit for this library goes to <a target="_blank" href="https://gunnarpeipman.com/">Gunnar</a> and <a target="_blank" href="https://michael-mckenna.com/">Michael</a>, two great authors whose several blog articles on this topic served as the foundation for this simple library.</p>
<hr />
<h2 id="getting-started">Getting Started</h2>
<p>Multitenancy support should not require a rewrite nor massive changes. With TinyTenant, you can now add multitenancy support to both new and existing projects in simple steps.</p>
<ol>
<li>Add <code>CodEaisy.TinySaas.AspNetCore</code> to your application via Nuget or the .NET CLI</li>
</ol>
<pre><code class="lang-bash">dotnet add package CodEaisy.TinySaas.AspNetCore --version 1.0.0
</code></pre>
<ol>
<li><p>In <code>Startup.cs</code>, add the following inside the <code>ConfigureServices</code> method.</p>
<pre><code class="lang-csharp"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureServices</span>(<span class="hljs-params">IServiceCollection services</span>)</span>
 {
     <span class="hljs-comment">// register all global singleton services here, and also dependencies for your TenantStore and ResolutionStrategy if any</span>

     <span class="hljs-comment">// ...</span>

     <span class="hljs-comment">// OPTION 1</span>
     services.AddMultiTenancy&lt;Tenant, TenantStore&lt;Tenant&gt;, TenantResolutionStrategy&gt;();

     <span class="hljs-comment">// OPTION 2</span>
     <span class="hljs-comment">// uses default `CodEaisy.TinySaas.Model.TinyTenant` as tenant model</span>
     services.AddMultiTenancy&lt;TenantStore&lt;TinyTenant&gt;, TenantResolutionStrategy&gt;();

     <span class="hljs-comment">// ...</span>

     <span class="hljs-comment">// services.AddControllers();</span>
 }
</code></pre>
<p>Then, add the following in the <code>Configure</code> method.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Configure</span>(<span class="hljs-params">IApplicationBuilder app, IWebHostEnvironment env</span>)</span>
{
   <span class="hljs-keyword">if</span> (env.IsDevelopment())
   {
       app.UseDeveloperExceptionPage();
   }

   <span class="hljs-comment">// enable multitenant support, with missing tenant handler and tenant container</span>

   <span class="hljs-comment">// OPTION 1</span>
   <span class="hljs-comment">// missing tenant handler has a dependency that can be provided immediately</span>
   app.UseMultitenancy&lt;Tenant, MissingTenantHandler, MissingTenantOptions&gt;(missingTenantOptions);

   <span class="hljs-comment">// OPTION 2</span>
   <span class="hljs-comment">// missing tenant handler does not have a dependency or dependency is already registered in services</span>
   app.UseMultitenancy&lt;Tenant, MissingTenantHandler&gt;();

   <span class="hljs-comment">// OPTION 3</span>
   <span class="hljs-comment">// Use `SimpleTenant` as tenant model, and missing tenant handler does not have a dependency or dependency is already registered in the services</span>

   app.UseMultitenancy&lt;TMissingTenantHandler&gt;()

   <span class="hljs-comment">// ...</span>
}
</code></pre>
</li>
<li><p>In <code>Program.cs</code>, add the following in the <code>CreateHostBuilder</code> method.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IHostBuilder <span class="hljs-title">CreateHostBuilder</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span> =&gt;
     Host.CreateDefaultBuilder(args)
         .ConfigureWebHostDefaults(webBuilder =&gt;
         {
             webBuilder.UseStartup&lt;Startup&gt;();
         })
         <span class="hljs-comment">// OPTION 1: add multitenant support via TenantStartup class</span>
         .ConfigureMultiTenancy&lt;TenantStartup, Tenant&gt;();
         <span class="hljs-comment">// OPTION 2: add multitenant support via static method</span>
         .ConfigureMultiTenancy&lt;Tenant&gt;(ClassName.StaticMethodName);
</code></pre>
</li>
</ol>
<p><strong>NOTE</strong>:</p>
<ul>
<li><code>Tenant</code> must implement <code>CodEaisy.TinySaas.Interface</code>  <code>ITenant</code>.</li>
<li><code>TenantStore</code> must implement <code>CodEaisy.TinySaas.Interface.ITenantStore</code>.</li>
<li><code>TenantResolutionStrategy</code> must implement <code>CodEaisy.TinySaas.Interface.ITenantResolutionStrategy</code> respectively.</li>
<li><code>TenantStartup</code> must implement <code>IMultiTenantStartup</code></li>
<li><code>ClassName.StaticMethodName</code> must be of type <code>System.Action&lt;TTenant, Autofac.ContainerBuilder&gt;</code> where <code>TTenant</code> implements <code>ITenant</code></li>
</ul>
<hr />
<h2 id="use-cases">Use Cases</h2>
<p>TinySaas supports the most common use cases for multitenant development, and below are some examples.</p>
<h3 id="global-services">Global Services</h3>
<p>Global Services are services that do not have a core dependency on the tenant information, and they can be registered just the same way you have been used to in .NET Core, in the <code>Startup.ConfigureServices</code> method.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureServices</span>(<span class="hljs-params">IServiceCollection services</span>)</span>
    {
        <span class="hljs-comment">// ...</span>
        services.AddSingleton&lt;IGlobalSingletonService, GlobalSingletonService&gt;();

services.AddScoped&lt;IGlobalScopedService, GlobalScopedService&gt;();

services.AddTransient&lt;IGlobalTransientService, GlobalTransientService&gt;();

        <span class="hljs-comment">// add multitenancy support here</span>

        services.AddControllers();
    }
</code></pre>
<h3 id="tenant-services">Tenant Services</h3>
<p>Tenant Services are services that have core dependencies on the tenant information. TinySaas allows you to register these services like every other .NET Core service but in a tenant aware location.</p>
<p>Usually, tenant services will be registered either in the <code>ConfigureServices</code> method of your <code>TenantStartup</code> class or in the delegate passed to the <code>IHostBuilder.ConfigureMultiTenancy</code> in the <code>Program.cs</code> file.</p>
<pre><code class="lang-csharp">    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureTenantServices</span>(<span class="hljs-params">Tenant tenant, ContainerBuilder container</span>)</span>
    {
        <span class="hljs-comment">// you can either register services using the provided container builder</span>

        <span class="hljs-comment">// tenant singleton</span>
        container.RegisterType&lt;TenantSingletonService&gt;().SingleInstance();

        <span class="hljs-comment">// tenant scoped</span>
        container.RegisterType&lt;TenantScopedService&gt;().InstancePerRequest();

        <span class="hljs-comment">// tenant transient</span>
        container.RegisterType&lt;TenantTransient&gt;().InstancePerDependency();

        <span class="hljs-comment">// basically, you can use all the dependency injection features provided by Autofac on the container.</span>

        <span class="hljs-meta">#<span class="hljs-meta-keyword">region</span> .NET Core DI way</span>
        <span class="hljs-comment">// you can also do it in the well-known .NET Core default DI way</span>

        <span class="hljs-keyword">var</span> services = <span class="hljs-keyword">new</span> ServiceCollection();

        <span class="hljs-comment">// tenant singleton</span>
        services.AddSingleton&lt;ITenantSingletonService, TenantSingletonService&gt;();

        <span class="hljs-comment">// tenant scoped</span>
        services.AddScoped&lt;ITenantScopedService, TenantScopedService&gt;();

        <span class="hljs-comment">// tenant transient</span>
        services.AddTransient&lt;ITenantTransientService, TenantTransientService&gt;();

        <span class="hljs-comment">// THIS IS VERY IMPORTANT IF YOU USE THE SERVICE COLLECTION TO REGISTER ANY SERVICES HERE.</span>
        container.Populate(services);

        <span class="hljs-meta">#<span class="hljs-meta-keyword">endregion</span></span>

    }
</code></pre>
<h3 id="databases">Databases</h3>
<p>Multitenancy is not complete without databases, and TinySaas has an answer to all your needs.</p>
<h4 id="shared-database-single-schema-and-schema-per-tenant">Shared Database (Single Schema and Schema per Tenant)</h4>
<p>Register your <code>DbContext</code> the old way and inject <code>IHttpContextAccessor</code> via your DbContext constructor.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Startup.cs class</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureService</span>(<span class="hljs-params">IServiceCollection services</span>)</span>
{
    <span class="hljs-comment">//....</span>
    services.AddDbContext&lt;AppDbContext&gt;(...);
    <span class="hljs-comment">//...</span>
}

<span class="hljs-comment">// AppDbContext.cs</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AppDbContext</span> : <span class="hljs-title">DbContext</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AppDbContext</span>(<span class="hljs-params">DbContextOptions&lt;AppDbContext&gt; options, IHttpContextAccessor httpContextAccessor</span>)</span>
    {
        _httpContextAccessor = httpContextAccessor;

        <span class="hljs-comment">// to get the tenant information in any method</span>
        <span class="hljs-comment">// var tenant = _httpContextAccessor.HttpContext.GetCurrentTenant&lt;TTenant&gt;();</span>
    }
}
`
</code></pre>
<h4 id="database-per-tenant">Database Per Tenant</h4>
<p>Simply move the <code>DbContext</code> registration to the multitenant service configuration method.</p>
<pre><code class="lang-csharp">    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureTenantServices</span>(<span class="hljs-params">Tenant tenant, ContainerBuilder container</span>)</span>
    {
         <span class="hljs-comment">// assume you had connectionString as a property on the tenant, you can easily do</span>
        <span class="hljs-keyword">var</span> services = <span class="hljs-keyword">new</span> ServiceCollection();
        services.AddDbContext&lt;AppDbContext&gt;(tenant.ConnectionString);

        container.Populate(services);
    }
</code></pre>
<h3 id="other-concerns">Other Concerns</h3>
<p><code>Options</code> can also be registered the same way as discussed for services and databases.</p>
<p>You can check out the source repo for TinySaas on Github, and give feedback via the issues tab.</p>
<h2 id="thank-you-for-reading">Thank you for reading 🍾.</h2>
]]></content:encoded></item><item><title><![CDATA[VS Code 101 for Remote Developers]]></title><description><![CDATA[I started using Visual Studio Code around 2016, while it was not a smooth experience at first, VS Code has managed to endear itself to the heart of developers, especially the polyglots.
Top VS Code Extensions for Remote Teams:
Irrespective of what te...]]></description><link>https://blog.barakimam.me/vs-code-101-for-remote-developers</link><guid isPermaLink="true">https://blog.barakimam.me/vs-code-101-for-remote-developers</guid><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[remote]]></category><category><![CDATA[dev tools]]></category><category><![CDATA[Collaboration]]></category><category><![CDATA[pair programming]]></category><dc:creator><![CDATA['Barak Imam]]></dc:creator><pubDate>Wed, 11 Dec 2019 06:32:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1576045906004/PrD3lq2G8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I started using Visual Studio Code around 2016, while it was not a smooth experience at first, VS Code has managed to endear itself to the heart of developers, especially the polyglots.</p>
<h2 id="top-vs-code-extensions-for-remote-teams-">Top VS Code Extensions for Remote Teams:</h2>
<p>Irrespective of what technologies your remote team uses, there are numerous VS Code plugins you will find useful, but this article will only cover those I have used extensively.</p>
<h3 id="-live-share-extension-pack-https-marketplace-visualstudio-com-items-itemname-ms-vsliveshare-vsliveshare-pack-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack">Live Share Extension Pack</a></h3>
<p>Live Share Extension Pack is a suite of four awesome extensions which include the following;</p>
<h4 id="-live-share-https-marketplace-visualstudio-com-items-itemname-ms-vsliveshare-vsliveshare-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare">Live Share</a></h4>
<p><img src="https://visualstudio.microsoft.com/wp-content/uploads/2018/11/liveshare-hero-optimized.jpg" alt="Live Share"></p>
<p>LiveShare is Microsoft&#39;s solution to enable a truly collaborative development experience. It supports real-time collaborative editing for multiple users in a single workspace (I have had up to six users on a session before).
Being an early adopter of Live Share, the stability and improvements we have witnessed are quite impressive.
LiveShare has given me that privilege to have memorable remote pair programming sessions with many members of my team spread across the continent with unbelievable ease.</p>
<p>Some amazing feature of Live Share that makes it so awesome include</p>
<ul>
<li>Shared Terminal</li>
<li>Shared Localhost</li>
<li>and even a shared debugging experience.</li>
</ul>
<h4 id="-live-share-chat-https-marketplace-visualstudio-com-items-itemname-karigari-chat-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=karigari.chat">Live Share Chat</a></h4>
<p>Communication is key, especially for distributed teams.
How do you provide immediate feedback on the function your colleague just refactored. Here comes Live Share Chat</p>
<p><img src="https://raw.githubusercontent.com/karigari/vscode-chat/master/readme/Live%20Share%20Chat.gif" alt="Live Share Chat"></p>
<p>Live Share Chat provides you with a chat interface that allows you to have realtime communication will all connected users in a Live Share session.</p>
<h4 id="-live-share-audio-https-marketplace-visualstudio-com-items-itemname-ms-vsliveshare-vsliveshare-audio-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-audio">Live Share Audio</a></h4>
<p>Live Share Audio gives you the capability to make a conference call with every user in a session. It comes with exciting features like the ability to mute and unmute yourself. With Live Share Audio, Guests who join your session are automatically prompted to join the call, and right in the extension tab, you can see a list of all the people in the call, their mute status, and a button icon to mute yourself or otherwise.</p>
<p><img src="https://user-images.githubusercontent.com/116461/49332032-0c2e7380-f55b-11e8-8e77-a53013f689e3.png" alt="Live Share Audio"></p>
<h3 id="-live-share-whiteboard-https-marketplace-visualstudio-com-items-itemname-lostintangent-vsls-whiteboard-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=lostintangent.vsls-whiteboard">Live Share WhiteBoard</a></h3>
<p>Sometimes during pair programming sessions, you feel the need to sketch some things, maybe to provide more clarity to your partner.</p>
<p>Live Share has got you covered with this extension.</p>
<p><img src="https://user-images.githubusercontent.com/116461/50567457-dddaba00-0cf9-11e9-840b-1b0a984d5ad9.gif" alt="Live Share WhiteBoard"></p>
<h3 id="-github-pull-request-https-marketplace-visualstudio-com-items-itemname-github-vscode-pull-request-github-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github">Github Pull Request</a></h3>
<p>GitHub pull-request has been around for a long time but recently received massive support after Microsoft acquired Github. This extension is a great productivity hack as it allows you to review PRs right inside your favorite code editor.</p>
<p>GitHub PR brings the entire Github web experience into VS Code, you can do basically everything, except the new multi-line comments which is being tracked <a target='_blank' rel='noopener noreferrer'  href="https://github.com/microsoft/vscode-pull-request-github/issues/1376">here</a>.</p>
<p>We have been using Github web for years without this feature, so I don&#39;t believe it would be a blocker to adopting this extension</p>
<p><img src="https://github.com/Microsoft/vscode-pull-request-github/raw/master/.readme/demo.gif" alt="GitHub PR"></p>
<h3 id="-jira-and-bitbucket-official-https-marketplace-visualstudio-com-items-itemname-atlassian-atlascode-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=Atlassian.atlascode">JIRA and Bitbucket (Official)</a></h3>
<p>If your team is covered by an Atlassian subscription, and you are using any of JIRA cloud and/or BitBucket cloud, this extension has got you covered.</p>
<p>The JIRA part provides you with a lot of features to manage your tasks from inside VS Code, the powerful JQL language also provides you the opportunity to create a near web experience for yourself.</p>
<p><img src="https://bitbucket.org/atlassianlabs/atlascode/raw/master/.readme/dev-workflow.gif" alt="JIRA and BitBucket Official"></p>
<p>The BicBucket part, on the other hand, provides functionalities similar to what is obtainable on the GitHub PR extensions, and even more. One of the notable additional features is an opportunity to monitor your BitBucket pipeline right inside VS Code.</p>
<h3 id="-browser-preview-https-marketplace-visualstudio-com-items-itemname-auchenberg-vscode-browser-preview-"><a target='_blank' rel='noopener noreferrer'  href="https://marketplace.visualstudio.com/items?itemName=auchenberg.vscode-browser-preview">Browser Preview</a></h3>
<p>Built on top of the same Headless Chrome that powers Cypress, Browser Preview gives you an almost full browser right inside VS Code, it comes handy when you need to get immediate feedback from front-end code changes.
With recent updates, it brings debugging support.</p>
<p><img src="https://github.com/auchenberg/vscode-browser-preview/raw/master/resources/demo.gif" alt="Browser Preview"></p>
<h2 id="best-practices-for-a-great-vs-code-experience">Best Practices for a great VS Code Experience</h2>
<p>One of the issues developers often face with VS Code is high memory usage, this is due to the fact that VS Code is built on Electron, this can often make VS Code unusable and sometimes your entire machine may be impacted. Here are ways I have been able to avoid sad experiences with VS Code.</p>
<h3 id="use-workspaces">Use Workspaces</h3>
<p>Workspaces give you the opportunity to customize your VS Code experience, for a particular project, or set of projects. It gives you the opportunity to set workspace specific settings and even extensions.</p>
<p>If you had ever experience memory issues, and extension conflict, workspace gives you the flexibility to enable just the extensions you want.</p>
<h3 id="disable-unused-extensions">Disable Unused Extensions</h3>
<p>Many developers work with different technologies, and may usually have some technology particular extensions.
You can improve your VS Code experience by disabling all extensions that do not relate to any project in your current workspace and/or folder. One method I employed to achieve this is by disabling all extensions by default, and only enable those extensions that are usable in the current project.</p>
<h3 id="one-extension-per-feature">One Extension Per Feature</h3>
<p>Have you ever run into a scenario where ESLint removed the brackets around an anonymous function, and prettier added it back immediately. This is what happens when you have multiple extensions for the same set of needs.</p>
<blockquote>
<p>Work on your team&#39;s workflow, decide which set of rules you are adopting, and get the extensions necessary to enforce those rules.</p>
</blockquote>
<p>VS Code was created to be lightweight, but installing too many extensions without proper separation of concern may bring you close to a Visual Studio experience.</p>
<p>It is almost a year I have incorporated these practices into my workflow, and I am pretty happy with this experience.</p>
<p>Thank you for reading, and kindly share if you feel the need.</p>
<p>Thanks.</p>
]]></content:encoded></item></channel></rss>