<?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: Raúl Pedro Fernandes Santos</title>
    <description>The latest articles on DEV Community by Raúl Pedro Fernandes Santos (@borfast).</description>
    <link>https://dev.to/borfast</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F454762%2F0ad548ec-63dd-4917-b81e-1e47ecaf61e9.jpeg</url>
      <title>DEV Community: Raúl Pedro Fernandes Santos</title>
      <link>https://dev.to/borfast</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/borfast"/>
    <language>en</language>
    <item>
      <title>Job boards for remote work</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Wed, 24 Jul 2024 11:11:47 +0000</pubDate>
      <link>https://dev.to/borfast/job-boards-for-remote-work-2heb</link>
      <guid>https://dev.to/borfast/job-boards-for-remote-work-2heb</guid>
      <description>&lt;p&gt;One of the biggest perks of working in software development is the ability to work from anywhere in the world. A lot of people tell me they don't know how to find a remote job or project, though. Since I have worked remotely for the vast majority of my career, I figured I'd share some of the websites I use to find remote full-time or part-time jobs, as well as freelance projects.&lt;/p&gt;

&lt;p&gt;Unfortunately, the two best websites I knew, Stack Overflow Jobs and Github Jobs, have been closed down in 2022 and 2021, respectively. :(&lt;/p&gt;

&lt;p&gt;Luckily for us, there are many others!&lt;/p&gt;

&lt;h2&gt;
  
  
  Top three recommendations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://climatebase.org/" rel="noopener noreferrer"&gt;Climatebase&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;My current top recommendation is Climatebase.&lt;/p&gt;

&lt;p&gt;It's not the job board where you will find the most jobs but I believe it is where you will more easily find jobs that will allow you to put your skills to good use.&lt;/p&gt;

&lt;p&gt;Climate change is by far the single most urgent challenge humanity is facing, and I believe we should all try to do what we can to fight it. If we can get a remote job in the software engineering world that also happens to be doing something positive about this, I'd say we should do it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;a href="https://www.keyvalues.com/" rel="noopener noreferrer"&gt;Key Values&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The second place goes to Key Values.&lt;/p&gt;

&lt;p&gt;It is also not the place with the most jobs but it has a unique approach to job searching that helps you find jobs that share your values. It makes me wonder why this isn't the standard in every job board. I find the idea of finding a job by matching values to be absolutely genius.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;a href="https://wellfound.com/" rel="noopener noreferrer"&gt;Wellfound (formerly AngelList Talent)&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Probably the best job board after Stack Overflow Jobs and Github Jobs in terms of the amount of jobs posted. Lots of young startups and most of them are in the VC game, which might be something you want to take into account, since the ultimate goal of the game is to sell the company, at which point, all the promises that were previously made are tossed out the window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remote-focused job boards
&lt;/h2&gt;

&lt;p&gt;These websites are focused on remote work. They may also have other types of jobs but their bread and butter is remote.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://remoteok.com" rel="noopener noreferrer"&gt;https://remoteok.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://remotive.com" rel="noopener noreferrer"&gt;https://remotive.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://weworkremotely.com" rel="noopener noreferrer"&gt;https://weworkremotely.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dailyremote.com/" rel="noopener noreferrer"&gt;https://dailyremote.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://justremote.co" rel="noopener noreferrer"&gt;https://justremote.co&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jobspresso.co/" rel="noopener noreferrer"&gt;https://jobspresso.co/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Non-remote-focused job boards
&lt;/h2&gt;

&lt;p&gt;These are not focused on remote work (they do have ads for remote work) but are still quite good.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://otta.com/" rel="noopener noreferrer"&gt;https://otta.com/&lt;/a&gt; - Very interesting job board with a very nice way to filter the things that matter the most to you. They also send out regular alerts for jobs that match your preferences.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://portfolio.joinef.com" rel="noopener noreferrer"&gt;https://portfolio.joinef.com&lt;/a&gt; - There are usually a lot of very interesting positions on this one.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hnhiring.com/" rel="noopener noreferrer"&gt;https://hnhiring.com/&lt;/a&gt; - An aggregator of job posts from Hacker News "&lt;a href="https://news.ycombinator.com/user?id=whoishiring" rel="noopener noreferrer"&gt;whoishiring&lt;/a&gt;" account&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://airtable.com/app53PsYpHxJW61l3/shr303f0nPKns4n45/tbl8QszTVi0TT7ur8" rel="noopener noreferrer"&gt;https://airtable.com/app53PsYpHxJW61l3/shr303f0nPKns4n45/tbl8QszTVi0TT7ur8&lt;/a&gt; - A list of other interesting job boards.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hired.com" rel="noopener noreferrer"&gt;https://hired.com&lt;/a&gt; - You create a profile and companies can find you and request an interview.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.honeypot.io" rel="noopener noreferrer"&gt;https://www.honeypot.io&lt;/a&gt; - Similar to Hired.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://landing.jobs" rel="noopener noreferrer"&gt;https://landing.jobs&lt;/a&gt; - Similar to Hired but to be completely honest, I've had nothing but bad experiences with them, both as a job seeker and as an employer. And they focus a lot on the Portuguese market, which means lower rates.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://authenticjobs.com" rel="noopener noreferrer"&gt;https://authenticjobs.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://relocateme.eu" rel="noopener noreferrer"&gt;https://relocateme.eu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.monster.co.uk" rel="noopener noreferrer"&gt;https://www.monster.co.uk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.simplyhired.co.uk" rel="noopener noreferrer"&gt;https://www.simplyhired.co.uk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Talent matching
&lt;/h2&gt;

&lt;p&gt;These sites actively find projects and match them with developers after a pre-selection process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.toptal.com" rel="noopener noreferrer"&gt;https://www.toptal.com&lt;/a&gt; - Great culture and work-life balance&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://x-team.com" rel="noopener noreferrer"&gt;https://x-team.com&lt;/a&gt; - Great culture and work-life balance&lt;/li&gt;
&lt;li&gt;&lt;a href="https://turing.com" rel="noopener noreferrer"&gt;https://turing.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gun.io" rel="noopener noreferrer"&gt;https://www.gun.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.vettery.com" rel="noopener noreferrer"&gt;https://www.vettery.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Freelance work
&lt;/h2&gt;

&lt;p&gt;A good way to get some more income with some side projects, or if you're getting started it can also be a good way to find simple projects to gain some experience with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.upwork.com" rel="noopener noreferrer"&gt;https://www.upwork.com&lt;/a&gt; - One important thing to keep in mind is that some employers demand that the worker installs Upwork's software, which is basically spyware: every 5 minutes or so, it takes a screenshot of your screen(s) and a picture through your webcam.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.guru.com" rel="noopener noreferrer"&gt;https://www.guru.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tips and articles about salary negotiation and interviewing:
&lt;/h2&gt;

&lt;p&gt;These are great articles to read with lots of super valuable insights. If you want the most valuable ones, here are three basic rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Never, &lt;em&gt;ever&lt;/em&gt; tell a recruiter how much you want as a salary; let them give you a number, otherwise you will probably leave lots of money on the table.&lt;/li&gt;
&lt;li&gt;Always try to negotiate the salary. No one will give up on you if you ask them if they are willing to pay a little more. If they are that close-minded, you probably don't want to work with them anyway.&lt;/li&gt;
&lt;li&gt;Never sign an NDA or non-compete agreement.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@bayareabelletrist/how-i-negotiated-a-software-engineer-offer-in-silicon-valley-f11590f5c656" rel="noopener noreferrer"&gt;How I negotiated a $300,000 job offer in Silicon Valley&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kalzumeus.com/2012/01/23/salary-negotiation/" rel="noopener noreferrer"&gt;Salary Negotiation: Make More Money, Be More Valued&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://daedtech.com/deploying-guerrilla-tactics-combat-stupid-tech-interviews/" rel="noopener noreferrer"&gt;Deploying Guerrilla Tactics to Combat Stupid Tech Interviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.borfast.com/blog/2020/07/28/8-reasons-why-i-rarely-sign-an-nda/" rel="noopener noreferrer"&gt;8 reasons why I rarely sign an NDA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://haseebq.com/my-ten-rules-for-negotiating-a-job-offer/" rel="noopener noreferrer"&gt;Ten Rules for Negotiating a Job Offer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://interviewing.io/blog/sabotage-salary-negotiation-before-even-start" rel="noopener noreferrer"&gt;How to sabotage your salary negotiations efforts before you even start&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;small&gt;Header photo by &lt;a href="https://unsplash.com/@kristinwilson?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Kristin Wilson&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/z3htkdHUh5w?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>remote</category>
    </item>
    <item>
      <title>Why we chose Elixir</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Tue, 02 Jul 2024 08:03:00 +0000</pubDate>
      <link>https://dev.to/borfast/why-we-chose-elixir-49n4</link>
      <guid>https://dev.to/borfast/why-we-chose-elixir-49n4</guid>
      <description>&lt;p&gt;Some time ago, I worked with a team to rebuild a company's internal web application, which was based on a very outdated version of &lt;a href="https://symfony.com/"&gt;Symfony&lt;/a&gt;, and was no longer salvageable for several reasons.&lt;/p&gt;

&lt;p&gt;After some time debating which technologies we should use, we decided to go with &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt; and &lt;a href="https://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt;. In short, these tools gave us the productivity, stability, safety, and scalability (the company was planning on opening up the application to the public, with a new API added to the mix, so future performance was a bit of a concern) that seemed appropriate for the company's plans.&lt;/p&gt;

&lt;p&gt;A not-so-technical external consultant that was helping out with other parts of the business asked us to explain this choice, since he had never even heard of Elixir, so we wrote down a few of the reasons that led us to the decision, in a way that anyone with just a little bit of technical background could understand.&lt;/p&gt;

&lt;p&gt;I haven't been writing much here lately, and I thought it could make a good blog post for anyone else considering these tools. This was not edited or made more readable for the web, it is just a bullet-list dump of the reasons we wanted to convey at that time, so here you go.&lt;/p&gt;




&lt;p&gt;It is hard to distill in a condensed version several months of conversations and research about a technology, ultimately leading up to the decision of using it for a project. I tried to summarise everything here but it's still a long read.&lt;/p&gt;

&lt;p&gt;Elixir has rock solid stability, which it gains from the BEAM VM (the Erlang underlying platform). Erlang was created by Ericsson for its telecommunications platforms, and to this date is still a very popular choices for mission critical software. Elixir inherits not only the BEAM VM's stability, it also has all of Erlang's &lt;a href="https://www.erlang.org/faq/introduction#idm24"&gt;OTP&lt;/a&gt; libraries and middleware available to it (in the same manner that languages that run on the Java VM usually have access to Java packages).&lt;/p&gt;

&lt;p&gt;The fact that it is a functional language with immutable principles, along with its pattern matching capabilities and error handling mechanics, means that the resulting code is typically much simpler, easier to reason about, and more robust than the typical result from an object-oriented or imperative language. In turn, this means less bugs, easier maintenance, easier onboarding, etc.&lt;/p&gt;

&lt;p&gt;Being a functional language also makes it less popular than other languages. But also because of that, it attracts more people who actually know how to write good software, instead of folks who did a 6-week "bootcamp" and were tricked into thinking they now know everything they need to be good software engineers. This also has an effect on the ecosystem around the language: the quality of Elixir packages is significantly higher than what is found in other more popular languages. In other words, even though there's a smaller pool of people to hire from and libraries to use, the average quality is significantly higher. We don't get as many low-quality developers, or libraries that are inneficient and riddled with bugs and security holes. On top of it, the Elixir community is well known for its friendliness and support, something we have experienced first-hand over the past year.&lt;/p&gt;

&lt;p&gt;Elixir has amazing asynchronous and parallel processing capabilities (in its default configuration, the BEAM VM automatically uses all available CPU cores, so we get true parallelism, not just concurreny), granted by very lightweight processes (you can easily have millions of them running in a single simple machine) and associated functionalities that are very useful. These processes are completely isolated, share no variables / memory, and communicate with each other only through message passing. This allows for safe and easy concurrency and parallelism because there are no locks and no race conditions.&lt;/p&gt;

&lt;p&gt;These processes are also meant to be discardable: "let it crash" is a guiding principle for writing good software, meaning that if something goes wrong, it should not fail silently while everything keeps running seemingly without a problem. The BEAM VM makes this super easy and transparent because it takes care of automatically restarting a process that terminates abnormally, while still generating logs, warnings, or whatever we need to detect the problem. In other words, Elixir is highly fault-tolerant by default.&lt;/p&gt;

&lt;p&gt;An example of why these processes are useful: we don't need separate infrastructure (message broker, task queue, task workers) to run asynchronous tasks as we would traditionally do, along with all the monitoring necessary to keep it running. Elixir's processes and supervision trees make it very easy and very efficient to have background tasks, like what we would use cron jobs for, or task queues (for example, for sending emails, or periodically fetching data from third-party services). This is simple to do with Elixir alone and works just fine but if we want to go further, there is a package called &lt;a href="https://github.com/sorentwo/oban"&gt;Oban&lt;/a&gt; which can use the same database as our app (no external broker required), and implements a lot of functionality, like scheduled tasks similar to cron jobs, automatically retrying failed tasks with backoff algorithms, a dashboard with metrics and controls for the queues and tasks, and many other niceties.&lt;/p&gt;

&lt;p&gt;The BEAM VM is also extremely efficient in computing resource usage, which means we spend less on infrastructure and, perhaps more importantly, reduce our environmental impact.&lt;/p&gt;

&lt;p&gt;Though not as extensive as in other more popular languages, Elixir has many libraries available, the number of which grows by an order of magnitude or two when you consider OTP as well. You'd be surprised by how much is covered by the available packages. Due to not being one of the most popular languages, libraries for specific third-party services may not be available but we've found that for these, we usually only want a very limited subset of its functionality, and we can easily implement something ourselves. For example, there is no official library for accessing OpenAI's API but the only thing their official libraries do is make a few HTTP requests. I would even argue that I'd rather not add yet another dependency to my projects if all it gives me is a way to make HTTP requests.&lt;/p&gt;

&lt;p&gt;Elixir and Phoenix are known for low latency when handling requests, which is critical for providing good UX.&lt;/p&gt;

&lt;p&gt;On top of that, Phoenix has built-in support for web sockets, which it uses in its Liveview library. It's hard to describe how amazing Liveview is to someone who hasn't used it yet. One of the best things about it is how easy it makes it to implement an application that behaves like an SPA without requiring the &lt;a href="https://www.borfast.com/blog/2023/08/01/please-dont-use-react/"&gt;insanity of a full blown frontend framework&lt;/a&gt;. It is able to load data in the background (including loading data asynchronously after loading the basic structure of the page, a.k.a. hydration for a fast "first contentful paint") and maintaining a bi-directional communication channel with the backend to modify data, get real-time notifications of any changes, and modify the DOM in a super efficient way (it's so efficient that other frameworks are copying the methods used by Phoenix). This would allow us to create a web app that could be used as a PWA, saving us a ton of time and money until the need for a native mobile app would arise.&lt;/p&gt;

&lt;p&gt;Phoenix uses a component-based approach for building web UIs, similar to what React and other popular frontend frameworks do, allowing for good code organisation and reuse.&lt;/p&gt;

&lt;p&gt;Phoenix promotes a project structure that separates business logic from data access logic, and from web or API logic. As we talked about before, it is trivial to add API logic to a project that was started with only a web layer that renders HTML.&lt;/p&gt;

&lt;p&gt;Both Elixir and Phoenix provide good telemetry and observability capabilities. Phoenix has a built-in dashboard that provides invaluable information and metrics about not only the application performance and health, but also the underlying BEAM VM.&lt;/p&gt;

&lt;p&gt;Phoenix is well known for contributing significantly to productivity and developer happiness.&lt;/p&gt;




&lt;p&gt;Bonus: &lt;a href="https://www.reddit.com/r/elixir/comments/11ljydy/would_you_still_choose_elixirphoenixliveview_if/"&gt;This thread on Reddit&lt;/a&gt; is chock-full of goodness about Elixir and Phoenix.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Please don't use React</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Mon, 06 Nov 2023 08:52:57 +0000</pubDate>
      <link>https://dev.to/borfast/please-dont-use-react-16m4</link>
      <guid>https://dev.to/borfast/please-dont-use-react-16m4</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second post of my "&lt;a href="https://dev.to/blog/2023/06/19/software-engineering-is-broken"&gt;Software Engineering is broken&lt;/a&gt;" series. In the introduction post, I described a friend's medical appointments platform where an agency proposed using React - a perfect example of how our industry often makes poor technological choices based on hype rather than actual needs. Today's post expands on why React was a poor choice for that project, and examines the broader issue of React's overuse in web development.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You should stop using React. In fact, you probably should have never used React in any of the projects you used it on. But before you pull out your sawed-off shotgun and shoot me, hear me out. Also, what I'll say here also applies to other tools like Vue and Single Page Applications in general, not just React.&lt;/p&gt;

&lt;p&gt;React is an impressive piece of technology and it helped push forward the concept of components for web UIs, which is great. Or at least that's what lots of people will say.&lt;/p&gt;

&lt;p&gt;But components are far from having been invented by React. Nothing ever stood in the way of organising our server-rendered HTML in a similar manner (most of the &lt;em&gt;good&lt;/em&gt; projects I saw during my career did something along those lines) and the manipulation of DOM elements has been possible since anyone cares to remember.&lt;/p&gt;

&lt;p&gt;The true revolution from React was the &lt;em&gt;scale&lt;/em&gt;. The virtual DOM allowed &lt;em&gt;complex&lt;/em&gt; manipulations of the DOM to be done more efficiently at a time when doing them directly was slow. I'll emphasise that again: &lt;strong&gt;&lt;em&gt;scale&lt;/em&gt;&lt;/strong&gt;. This is what eludes most people who use React. It was never meant to be used in blogs and static websites, it was meant for frontends that did &lt;em&gt;very heavy&lt;/em&gt; DOM manipulations, either in number of operations, number of nodes manipulated, or even both. Frontends that would have been unthinkable became achievable.&lt;/p&gt;

&lt;p&gt;So yes, React is impressive and inspired a lot of improvements in web technology we've seen since its release.&lt;/p&gt;

&lt;p&gt;Unfortunately, React is also bloated, slow, complex, ignores and reinvents foundational web technologies, it completely negates search engine indexing (and, consequently, SEO), and it duplicates the effort to build a web application because it forces you to have two full software development projects - frontend and backend - with all the costs (not only financial) that come along with each one.&lt;/p&gt;

&lt;p&gt;More importantly, the vast majority of projects are much simpler than the scenarios React was designed for, and choosing it ends up causing more harm than good.&lt;/p&gt;

&lt;p&gt;So why do so many people swear by React?&lt;/p&gt;

&lt;p&gt;React probably became popular due to a combination of a great idea and the usual eagerness to adopt technologies from Big &amp;amp; Cool companies, as if these tools were made to solve the same type of problems small companies have. A lot of people also say that React is "easy," which is a distorted interpretation of the concept of "easy", but probably still influenced a lot of junior developers to get into it.&lt;/p&gt;

&lt;p&gt;Interestingly, whenever I ask someone about their motives to use React, they don't really have a concrete reason. Some people are humble enough to admit that "it's what everyone else was using and I just went with it." But more often, people adopt a defensive stance and shield themselves behind flawed arguments.&lt;/p&gt;

&lt;p&gt;After reading the agency's proposal for my friend's project, I replied suggesting some alternatives that would be better choices, including telling them to not build a Single Page Application. I proposed that instead of React, they could use simpler tools, like plain HTML and Javascript, and enhance it with something like &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;HTMX&lt;/a&gt; and/or &lt;a href="https://alpinejs.dev/" rel="noopener noreferrer"&gt;Alpine.js&lt;/a&gt;. After all, the UI for the application was very simple and had no need for React or to be an SPA at all. If they really wanted to use that type of framework and build an SPA, then they could at least go for something like &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; or &lt;a href="https://www.solidjs.com/" rel="noopener noreferrer"&gt;Solid&lt;/a&gt;. Or even better, use Phoenix Liveview, Ruby on Rails and Hotwire, or even (forgive me) Laravel's Livewire.&lt;/p&gt;

&lt;p&gt;As expected, the agency replied in a &lt;em&gt;very&lt;/em&gt; defensive manner and stood by their proposal of using React. Also not surprisingly, they used flawed arguments to defend their choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Popularity
&lt;/h2&gt;

&lt;p&gt;They said, and I quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because we're talking about the most popular and most used technologies in the market, versus libraries with no expression and no community. This point is important to guarantee that you can find people who can work on the product, even after we deliver it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This point is actually based on a valid concern and it is indeed something that should usually be taken into consideration when picking a software tool. The idea is that by using something that is popular, there will be more resources available for that tool. Namely, people to hire and community for support. It was one of my main concerns for my friend's project, because I knew it was not something he had thought about.&lt;/p&gt;

&lt;p&gt;But here's the thing: HTMX, Alpine and Svelte are not libraries "with no expression and no community" - quite the contrary!&lt;/p&gt;

&lt;p&gt;Let's look at Svelte as an example. According to the &lt;a href="https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/" rel="noopener noreferrer"&gt;State of JS survey&lt;/a&gt;, Svelte is in the fourth place for awareness and usage (only the three behemoths, React, Angular and Vue ranked higher, which is to be expected). But it comes first in terms of interest, while React comes in fifth place. And Svelte comes in second place in terms of retention, with only 1% point difference from Solid in the first place, while React is in the fourth place.&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%2Fwthq1pjpwkfn79ywc91o.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%2Fwthq1pjpwkfn79ywc91o.png" alt="Svelte statistics from https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTMX may not be as popular as Svelte but anyone who pays attention to the web development world knows that &lt;a href="https://trends.builtwith.com/javascript/Htmx" rel="noopener noreferrer"&gt;it has been gaining some serious popularity&lt;/a&gt; over the past couple of years and &lt;a href="https://news.ycombinator.com/item?id=36648817" rel="noopener noreferrer"&gt;people are saying very good things about it&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%2F5j27iy4vlbz7g4mh4frz.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%2F5j27iy4vlbz7g4mh4frz.png" alt="HTMX Usage Statistics from https://trends.builtwith.com/javascript/Htmx" width="769" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I obviously didn't have these numbers in my head when I proposed the alternatives for my friend's project, and I am not a front-end developer, but I still knew these "facts" - so how come an agency that works in this world every single day, did not?&lt;/p&gt;

&lt;p&gt;But that's not all. Sure, there are more people who know React than people who know HTMX and even Svelte. And if HTMX was a complex beast that required a lot of time to master, I would agree that it would not be a good choice. But as it turns out, HTMX is super simple to use and would have given them everything they needed to build the project.&lt;/p&gt;

&lt;p&gt;More importantly, HTMX does not reinvent the wheel or add a ton of new concepts and techniques with subtle exceptions that need to be mastered and remembered; it reuses foundational web technologies, and because of that, anyone who knows HTML and Javascript will be fully up and running with HTMX in a matter of minutes - much, &lt;em&gt;much&lt;/em&gt; less than it would take anyone to learn React.&lt;/p&gt;

&lt;p&gt;The big difference here is: in order to work with React, you also have to know HTML &amp;amp; JS, but just because you know HTML &amp;amp; JS, it doesn't mean you know React.&lt;/p&gt;

&lt;p&gt;Think about it as a Venn diagram:&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%2F826bagmfyfvb8xajmh68.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%2F826bagmfyfvb8xajmh68.png" alt="A Venn diagram illustrating the relation between the amount of HTML &amp;amp; JS developers, and React developers" width="373" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if the concern here is about being able to hire people to continue working on the project, it would make more sense to use HTMX than React, because surely, there are more developers who know HTML and Javascript than those who know React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity
&lt;/h2&gt;

&lt;p&gt;Another popular argument for React, and one that the agency did not forget to include, is that it is very simple.&lt;/p&gt;

&lt;p&gt;In my arguments, I said React was too complex for the project. Here's what they responded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;About complexity, it is dangerous to interpret it that way. In reality, React helps you structure a project in a more robust way that avoids that same complexity. Otherwise, we'll have a chaotic project without rules for the code structure, and even though it may seem "simpler and lighter," it will become harder to manage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They misunderstood my point and were mixing a couple of different topics: code structure, and complexity.&lt;/p&gt;

&lt;p&gt;React doesn't provide any standard code structure. There may be popular ways to organise source code in a React project but that's by common agreement from the community, not something we can or should attribute to React, and even less something imposed or required by it. A robust code structure will depend, first and foremost, on the developer and good programming principles. React will not do anything for the project structure if the developer doesn't know what they're doing. The question is: what is "well structure code?" If we ask this question to 10 developers, we may get 11 different answers - even within the React world. The main point is to follow good principles, and that does not depend on the tools you use.&lt;/p&gt;

&lt;p&gt;As for the complexity that I mentioned, that's not related to the structure of the code but with the concepts and subtleties that React introduces beyond the foundational web technologies, and that one must master in order to use it properly: routing, virtual DOM, JSX, hooks, class-based components versus function-based components, component life-cycle and all its events that you must understand, state management (there are full courses and several libraries for this part alone), among other things. None of this exists on the foundational web technologies and they are all extra things any developer has to learn if they want to work with React, even if they already know HTML and Javascript. And I'm not even going into the insanity that is brought in by the constantly-changing React and Javascript world, as well as things like Webpack, Babel, Parcel, etc. The real complexity comes from these things, not the code structure.&lt;/p&gt;

&lt;p&gt;I fully agree that sometimes it is necessary to add complexity to a project because the benefits justify it. However, it is necessary to keep in mind that the introduction of any tool is always a trade-off between simplicity and functionality: to add the latter, we lose some of the former. This is valid for any line of code, even our own. For this reason, it is only justifiable to add tools to a project when there is a concrete problem for which a given tool is the best solution and brings benefits that outweigh the cost. If the agency could show me concrete problems that React was going to solve in my friend's project, problems that could not be solved in a simpler way, I'd be the first to tell them to use React - but of course they couldn't show me any.&lt;/p&gt;

&lt;p&gt;Sure, React is simple - if you never work on a serious production-ready project with it. Anyone who has worked seriously with React for some time will have the same opinion: it quickly becomes a headache.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time and cost
&lt;/h2&gt;

&lt;p&gt;One of the last points the agency made in favour of React was that by not using React, the whole project would take much longer and cost much more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update on February, 2024: after more than a year, the agency still has not finished the project, which they initially estimated to take 3-4 months, and already cost 4 times the initial agreed upon budget.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was probably the most obvious point showing that they had no clue about what they were doing.&lt;/p&gt;

&lt;p&gt;It was also one of the reasons why I mentioned the complexity issue, and why I defend simpler solutions. Any project that involves React will automatically take more time and be more expensive because of the points I mention in this article.&lt;/p&gt;

&lt;p&gt;It's a fallacy to say that React saves time because the reality is exactly the opposite. React may seem simple for what it proposes and in its basic idea, but it's not simple at all when compared with well-written Javascript or TypeScript, or even something like HTMX.&lt;/p&gt;

&lt;p&gt;There's also the not-so-subtle detail of backwards compatibility. Most React releases introduced breaking changes, forcing people to make deep changes or even rewrite their frontend projects. This sounds like the exact opposite of saving time. Compare that to foundational web technologies that were created dozens of years ago and still work unchanged to this date.&lt;/p&gt;

&lt;p&gt;Unfortunately, in the Javascript world, hype is everything, and the mass hysteria in favour of React made it a sort of self-fulfilling prophecy. It is very hard to convince its fans that, even though it's technically impressive, it is a bad choice for the majority of projects people work on.&lt;/p&gt;

&lt;p&gt;But, as discussed above, if you have a much larger pool of developers potentially available to continue a project that uses HTMX than you would have for a project that uses React; if there's no "React tax" caused by all the hype surrounding it; and if you'll have a much simpler project that will also be much easier to maintain - doesn't it stand to reason that it will cost much less to &lt;em&gt;not&lt;/em&gt; use React?&lt;/p&gt;

&lt;p&gt;Having examined the organizational and development costs, let's look at perhaps the most direct impact on users:&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance &amp;amp; Size
&lt;/h2&gt;

&lt;p&gt;React invented the virtual DOM, which was revolutionary for its time. But it can also lead to very slow performance. Not only that, it is like a full application running in your browser.&lt;/p&gt;

&lt;p&gt;The library size alone and how much JS code you have to write for your frontend, along with all the stuff you have to include for browser compatibility, polyfills, and  even CSS-in-JS. Holy hell, you simply wanted to serve a blog page and suddenly you're forcing your users to download &lt;em&gt;megabytes&lt;/em&gt; of code! And this is considered normal? How did we get here?&lt;/p&gt;

&lt;p&gt;When you're a developer working on a beefy machine, sure, you don't notice it, but when you're a user on a mobile phone or less powerful device, it can easily become apparent how sluggish it is.&lt;/p&gt;

&lt;p&gt;Look at GMail and Reddit. The "rich" versions of their UIs, though containing more features than the plain HTML versions, are so much "heavier" and sluggish, especially in older machines. Is it really worth it?&lt;/p&gt;

&lt;p&gt;To put this in perspective, let's look at some numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A typical React application starts with a base bundle size of ~120KB (minified + gzipped)&lt;/li&gt;
&lt;li&gt;Add React Router: +20KB&lt;/li&gt;
&lt;li&gt;Add a state management solution like Redux: +15KB&lt;/li&gt;
&lt;li&gt;Common UI component libraries: +30-100KB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare this to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alpine.js: ~15KB total&lt;/li&gt;
&lt;li&gt;HTMX: ~10KB total&lt;/li&gt;
&lt;li&gt;A basic HTML/CSS/JS solution: ~0KB additional weight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These differences become especially significant on mobile networks or in regions with limited bandwidth.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about when Javascript is unavailable?
&lt;/h2&gt;

&lt;p&gt;Because websites built with React are rendered on the browser, and thus require Javascript code to be executed, if JS is unavailable for some reason, you'll have a few problems on your hands.&lt;/p&gt;

&lt;p&gt;First, your SEO will suffer because search engines don't do so well with Javascript, meaning your website won't be properly indexed and thus, your ranking will drop significantly.&lt;/p&gt;

&lt;p&gt;Lastly, there are other scenarios where JS may not be available - either by choice, or necessity. And there are &lt;a href="https://piccalil.li/blog/a-handful-of-reasons-javascript-wont-be-available/" rel="noopener noreferrer"&gt;perfectly valid reasons for this to happen&lt;/a&gt;, like if you're a journalist covering dangerous news and want to do all you can to secure your browser; or when you're using a computer that forcefully configured your browser to disable Javascript; or perhaps you live in a remote location in a third-world country and only have a low-powered device of which you need to conserve the battery; or maybe you simply can and choose to live in a world without JS and disable it altogether because you don't want to be tracked (yeah, it's not enough to fully block tracking but it's something).&lt;/p&gt;

&lt;p&gt;If you can and know how to set up a Node server, you can use server side rendering to somewhat mitigate this with server side rendering (something that has existed and has been the default since the dawn of the web, by the way; it is not exclusive to JS frameworks) but at that point React loses a lot of its appeal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The future
&lt;/h2&gt;

&lt;p&gt;I started writing this article back in 2020 (yes, I'm a very slow writer), and fortunately, since then, the frontend world seems to have gained some sense and more and more people are speaking up against the insanity of React and SPAs. Some examples (which I will update as I find more supporting articles):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://infrequently.org/2023/02/the-market-for-lemons/" rel="noopener noreferrer"&gt;The Market for Lemons&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.spicyweb.dev/the-great-gaslighting-of-the-js-age/" rel="noopener noreferrer"&gt;The Great Gaslighting of the JavaScript Era&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://world.hey.com/dhh/we-tried-that-didn-t-work-d9c42fe1" rel="noopener noreferrer"&gt;We tried that, didn’t work&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.baldurbjarnason.com/2023/web-dev-untalented/" rel="noopener noreferrer"&gt;Web developers: remarkably untalented and careless?&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://joshcollinsworth.com/blog/antiquated-react" rel="noopener noreferrer"&gt;Things you forgot (or never knew) because of React&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.zachleat.com/web/react-criticism/" rel="noopener noreferrer"&gt;A Historical Reference of React Criticism&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/oxharris/rethinking-the-modern-web-5cn1"&gt;Rethinking the Modern Web&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.reddit.com/r/laravel/comments/kkzdkw/taylor_otwell_avoid_separate_spas_consuming/" rel="noopener noreferrer"&gt;Taylor Otwell: Avoid Separate SPAs consuming Laravel API. Use Livewire/Inertia.&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://joshcollinsworth.com/blog/self-fulfilling-prophecy-of-react" rel="noopener noreferrer"&gt;The self-fulfilling prophecy of React&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/what-got-me-writing-vanilla-js-again-2c53756c8a4c" rel="noopener noreferrer"&gt;What Got Me Writing Vanilla JavaScript again&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ahastack.dev/" rel="noopener noreferrer"&gt;The AHA Stack&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://begin.com/blog/posts/2024-01-26-removing-react-is-just-weakness-leaving-your-codebase" rel="noopener noreferrer"&gt;Removing React is just weakness leaving your codebase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.cassidoo.co/post/annoyed-at-react/" rel="noopener noreferrer"&gt;Kind of annoyed at React&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/matfrana/react-where-are-you-going-5284"&gt;React, where are you going?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gomakethings.com/the-decline-of-react/" rel="noopener noreferrer"&gt;The deciline of React&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://johan.hal.se/wrote/2024/01/24/concatenating-text/" rel="noopener noreferrer"&gt;Concatenating text&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://andy-bell.co.uk/the-extremely-loud-minority/" rel="noopener noreferrer"&gt;The (extremely) loud minority&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.frankmtaylor.com/2024/06/20/a-rant-about-front-end-development/" rel="noopener noreferrer"&gt;A Rant about Front-end Development&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://piccalil.li/blog/a-handful-of-reasons-javascript-wont-be-available/" rel="noopener noreferrer"&gt;A handful of reasons JavaScript won’t be available&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://lackofimagination.org/2024/04/back-to-basics-in-web-apps/" rel="noopener noreferrer"&gt;Back to Basics in Web Apps&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://polotek.net/posts/the-frontend-treadmill/" rel="noopener noreferrer"&gt;The Frontend Treadmill&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://htmx.org/essays/you-cant/" rel="noopener noreferrer"&gt;You Can't Build Interactive Web Apps Except as Single Page Applications... And Other Myths&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://infrequently.org/2024/11/if-not-react-then-what/#fnref-the-devils-computer-2" rel="noopener noreferrer"&gt;If Not React, Then What?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kellysutton.com/2024/01/15/moving-on-from-react.html" rel="noopener noreferrer"&gt;Moving on from React&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kellysutton.com/2025/01/18/moving-on-from-react-a-year-later.html" rel="noopener noreferrer"&gt;Moving on from React, a Year Later&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I mentioned before, the &lt;em&gt;idea&lt;/em&gt; of components is a good one. Fortunately, we now have many other, better options to use similar components, including in languages other than Javascript.&lt;/p&gt;

&lt;p&gt;In fact, you might not even need components at all. If you feel the need to organise your code that way, sure, go for it. If you are working on a complex application and will need to reuse components in lots of places, absolutely, go for it. Need to share components with other projects or teams? Go for it. But if you don't have a problem that components would solve, you can save yourself some time and pain.&lt;/p&gt;

&lt;p&gt;My first suggestion would be to go back to foundational web technologies and the web platform: HTML, CSS, and lightly sprinkle some plain Javascript to add interactivity where the web platform doesn't provide what you need. There are libraries - not full-fledged frameworks - that can easily add all the functionality you probably need for the vast majority of the projects you will work on.&lt;/p&gt;

&lt;p&gt;Start by taking a look at &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;HTMX&lt;/a&gt; and &lt;a href="https://alpinejs.dev/" rel="noopener noreferrer"&gt;Alpine.js&lt;/a&gt;. They both allow you to build web applications that are rendered on the server, while still being able to easily modify the UI in reaction to user actions, load data in the background, use websockets and Server Sent Events, etc. And all of this with simple augmentations to the HTML language - no bloated and complex framework required.&lt;/p&gt;

&lt;p&gt;If you can use Elixir, Ruby, or even PHP on the backend, try &lt;a href="https://phoenixframework.org/" rel="noopener noreferrer"&gt;Phoenix Liveview&lt;/a&gt; (by far my favourite), Rails and &lt;a href="https://hotwired.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt;, or Laravel and &lt;a href="https://laravel-livewire.com/" rel="noopener noreferrer"&gt;Livewire&lt;/a&gt;. These tools allow you to build a reactive frontend, with bi-directional real-time state synchronisation, without having to pay a huge complexity price. Unfortunately, I don't know of an equivalent for Django. There are a few things but they're not part of the framework, require a lot of manual wiring, and are just not as mature as the other ones.&lt;/p&gt;

&lt;p&gt;If for some reason you still want to use a more complex JS framework, then try &lt;a href="https://www.solidjs.com/" rel="noopener noreferrer"&gt;Solid&lt;/a&gt; or &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt;. They are much simpler and much more performant than React, Vue, or Angular. There's also &lt;a href="https://stenciljs.com/" rel="noopener noreferrer"&gt;Stencil&lt;/a&gt; and &lt;a href="https://lit.dev/" rel="noopener noreferrer"&gt;Lit&lt;/a&gt;, which are quite interesting due to being both based on Web Components standards, meaning they work on all modern browsers and are probably more future-proof than other options (then again, who am I kidding? This is the Javascript world, nothing lasts more than two weeks).&lt;/p&gt;

&lt;p&gt;React can be an acceptable choice for &lt;em&gt;some&lt;/em&gt; scenarios but people should learn to evaluate the specific needs of the project and weigh the trade-offs before jumping onto the cool kids train. If it solves a specific problem you have that can't be better solved by another tool, go for it. Otherwise, you'll be better off with something simpler.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Header photo by &lt;a href="https://unsplash.com/@lautaroandreani?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Lautaro Andreani&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/xkBaqlcqeb4?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Software engineering is broken</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Tue, 20 Jun 2023 07:00:00 +0000</pubDate>
      <link>https://dev.to/borfast/software-engineering-is-broken-8o8</link>
      <guid>https://dev.to/borfast/software-engineering-is-broken-8o8</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;A little over a year ago, a friend of mine hired an agency to build a web application for his business. The application is basically a simple online platform for medical appointments and consultations via video calls using Twilio. Since my friend doesn't have that much technical knowledge, he asked me to help him validate what the agency was proposing. When I read the proposal, I was shocked. Not only because of the value they were asking but even more so due to the technological choices. It was clear to me right away that they were the typical agency where no one knew anything other than Javascript and MongoDB (thanks, Freecodecamp! 😠) - in other words, they know very little about proper software engineering.&lt;/p&gt;

&lt;p&gt;They mentioned React, Strapi, MongoDB and GraphQL as the foundational technologies for the application. This made absolutely no sense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strapi is a framework to build CMS, not a framework or library to build a full-fledged web application.&lt;/li&gt;
&lt;li&gt;MongoDB is a document store but this type of application will obviously be based on relational data and thus, it needs a relational database.&lt;/li&gt;
&lt;li&gt;GraphQL is meant for scenarios where you have &lt;em&gt;a lot&lt;/em&gt; of scattered data and you need to easily be able to fetch random pieces of data from random places.&lt;/li&gt;
&lt;li&gt;React might be a good fit for large teams building very large and very complex frontends but this is a fairly simple application and the agency building it is very small.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, none of the tools they chose were meant to solve the problem at hand, which was building a very specific and very well-defined type of web application. Sure, any of those tools could be used to build the application, just as you can also use a spoon to cut your potatoes and a fork to eat your soup - but does it make sense? Just because you can doesn't mean you should.&lt;/p&gt;

&lt;p&gt;All of those choices added unnecessary complexity, which meant unnecessary time spent building the application, unnecessary electricity spent and the accompanying carbon footprint, unnecessary money spent by my friend, and ultimately even unnecessary frustration for the developers who are working on it. Yes, "working", not "worked", because they still haven't finished it and are way beyond their original estimation of three to four months.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Software engineering is broken. We, as an industry, have distorted it so much that what used to be serious work but still possible to enjoy, is now a source of pain, frustration and burnout. A pale shadow of the proper discipline it used to be.&lt;/p&gt;

&lt;p&gt;It has become the norm to over-engineer any project from its inception, applying tools and solutions for problems we don't have and probably never will. Even the simplest things have become convoluted. For example, I cannot remember the last time I worked at a company that did not require an insane amount of effort or had an excessive level of complexity simply to get a local environment ready for me to work, let alone doing the actual work.&lt;/p&gt;

&lt;p&gt;The saddest part about this is that we seem to glorify this unnecessary complexity. Somehow we convinced ourselves that we need design patterns everywhere. That gigantic dependency trees are normal. That overly complex infrastructure is acceptable. And that to build a simple blog it is necessary to use libraries and / or frameworks that add several megabytes of code to what the visitors' browser has to download. That's what passes for good software engineering in these strange times.&lt;/p&gt;

&lt;p&gt;There are way too many "software engineers" who should not work writing code because they contribute negatively to the ecosystem they're in. And let's not forget the end result of their work, &lt;a href="https://pointersgonewild.com/2023/05/29/software-bugs-that-cause-real-world-harm/" rel="noopener noreferrer"&gt;which can negatively affect the world&lt;/a&gt;. Think "emergency response systems," or "hospital patient management." But they think they are great at it because some tools made it too easy for them to write a "hello, world!" What's worse, these pseudo-programmers became so large in numbers, that they now &lt;a href="https://en.wikipedia.org/wiki/Argumentum_ad_populum" rel="noopener noreferrer"&gt;think they are the ones who are right&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It didn't help that the whole world has settled on the erroneous idea that "anyone and everyone can learn to 'code'." This is true to some point but not everyone will make a good software engineer. Unfortunately, in this post-modern era, we are forced to accept that every opinion is as valid as any other, no matter how ridiculous or unfounded. So we end up with tons of people who write spaghetti code, making a mess of the world.&lt;/p&gt;

&lt;p&gt;More shockingly, many of those are able to write spaghetti code in a beautiful way, so we take what they build and put it on a pedestal - simply because it's complex and hard to understand. To me, complex code is a sign of bad code. Nowadays it seems to be a sign of glory. Maybe I'm getting old.&lt;/p&gt;

&lt;p&gt;I'm not sure exactly how we got here but I think it's a combination of at least three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The "anyone can code" culture, which led to too many pseudo-programmers contributing negatively to the ecosystems.&lt;/li&gt;
&lt;li&gt;Marketing folks pushing buzzwords to everyone's mind.&lt;/li&gt;
&lt;li&gt;Script kiddies wanting to use the cool tools from the big guys because they all want to be the next Zuckerberg, without understanding the problems these tools were designed to solve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These things combined led to the problems I mention above, among other things.&lt;/p&gt;

&lt;p&gt;To be fair, there are lots of other people out there who, like me, think this has become ridiculous and are doing what is in their power to fix it and go back to a simpler and happier life. In the frontend world alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are many projects trying to create a "better React" from scratch to make it simpler and more light-weight.&lt;/li&gt;
&lt;li&gt;The most loved frontend framework is Svelte which tries to massively simplify how frontends are built.&lt;/li&gt;
&lt;li&gt;Several well-established communities tried to get rid of the insanity that are SPAs by creating a saner approach to modernizing web applications:

&lt;ul&gt;
&lt;li&gt;Ruby on Rails -&amp;gt; &lt;a href="https://hotwired.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Phoenix/Elixir -&amp;gt; &lt;a href="https://github.com/phoenixframework/phoenix_live_view" rel="noopener noreferrer"&gt;LiveView&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Laravel/PHP -&amp;gt; &lt;a href="https://laravel-livewire.com/" rel="noopener noreferrer"&gt;Livewire&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Django/Python -&amp;gt; &lt;a href="https://www.django-unicorn.com/" rel="noopener noreferrer"&gt;Unicorn&lt;/a&gt; and &lt;a href="https://www.tetraframework.com" rel="noopener noreferrer"&gt;Tetra&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Even the React world came up with &lt;a href="https://nextjs.org/docs/getting-started/react-essentials#server-components" rel="noopener noreferrer"&gt;Server Components&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;But other parts of the "stack" are not roses, either. Complex design patterns for object-oriented languages have become the norm. Kubernetes and micro-services are used everywhere. People are learning (wrongly) that MongoDB should be used as the database for everything. AWS/GCP/Azure is being used when something like Linode or Digital Ocean would be enough. Everyone is shooting themselves in the foot at every opportunity.&lt;/p&gt;

&lt;p&gt;The vast majority of companies are small. Your company is most likely a small company. What huge companies like Google and Facebook do does not apply to you. Not only does it not apply, trying to replicate what they do on your smaller company is actually detrimental. You do not have the same problems they do, and certainly not at the same scale. And even if you did, you don't have the amount of money or people to absorb the complexity of the systems and tools they use. It's incredibly counter-productive to adopt, for example, micro-services and Kubernetes in a company that has 6 or 7 engineers. Such a company does not have the type of problem these tools solve, nor do they have the capacity to absorb the complexity that comes with said tools. And yet, this is exactly what many small companies do.&lt;/p&gt;

&lt;p&gt;Returning to my friend's project: over a year later, what started as a simple medical appointments platform has become a cautionary tale of modern software development gone wrong. The unnecessary complexity introduced by poor technological choices has led to delays, increased costs, and frustrated developers - exactly the problems I've outlined above. Through this series of posts, I hope to show that there's a better way: one that focuses on choosing the right tools for the job, embracing simplicity where possible, and remembering that our goal is to solve real problems, not to chase the latest trends. Perhaps by examining these issues one at a time, we can start shifting our industry back towards more sensible, maintainable, and enjoyable software engineering.&lt;/p&gt;

&lt;p&gt;I'll link each new post in this series as they're published:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.borfast.com/blog/2023/08/01/please-dont-use-react/" rel="noopener noreferrer"&gt;Please don't use React&lt;/a&gt; - how the frontend world became unnecessarily complicated&lt;/li&gt;
&lt;li&gt;MongoDB everywhere and not knowing relational databases - exploring how NoSQL became the default choice regardless of data needs&lt;/li&gt;
&lt;li&gt;Micro-services and Kubernetes - when splitting your monolith creates more problems than it solves&lt;/li&gt;
&lt;li&gt;AWS/GCP/Azure when Linode or Digital Ocean would be enough - the hidden costs of over-engineering your infrastructure&lt;/li&gt;
&lt;li&gt;DevOps - how a culture of collaboration became a buzzword for complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;small&gt;Header photo by &lt;a href="https://unsplash.com/@hasanalmasi?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Hasan Almasi&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/fbnqS9b_rdM?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The best desktop for programming in 2022</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Mon, 21 Nov 2022 23:04:57 +0000</pubDate>
      <link>https://dev.to/borfast/the-best-desktop-for-programming-in-2022-4c5l</link>
      <guid>https://dev.to/borfast/the-best-desktop-for-programming-in-2022-4c5l</guid>
      <description>&lt;p&gt;A friend recently asked me for some tips to buy a new desktop computer for programming and what I think would be the best choice for components. I started typing away a few things but quickly found myself deep in the proverbial rabbit hole, and since this is a question I am asked fairly frequently, I figured I'd expand a little on what I wrote him and create a blog post.&lt;/p&gt;

&lt;p&gt;Besides, black friday 2022 is almost upon us, and even though I find the concept abslutely abhorrent (that's a &lt;a href="https://www.irishexaminer.com/lifestyle/people/arid-40744539.html"&gt;long topic&lt;/a&gt; for another day), many people may find it a good time to get some of this stuff. Also, it helps with SEO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
What and why

&lt;ul&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
CPU

&lt;ul&gt;
&lt;li&gt;CPU cooler&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Motherboard

&lt;ul&gt;
&lt;li&gt;Chipset&lt;/li&gt;
&lt;li&gt;The actual motherboard&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;RAM&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Graphics card&lt;/li&gt;
&lt;li&gt;Power supply&lt;/li&gt;
&lt;li&gt;Case&lt;/li&gt;
&lt;li&gt;The end!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What and why
&lt;/h2&gt;

&lt;p&gt;Why a desktop instead of a laptop, you ask? When it comes to work, laptops are more common than desktops nowadays but even though I love the mobility a laptop grants me, I still want to have a desktop as my main machine. It just makes more sense to me because I can individually upgrade or replace any part as I want or need, drastically reducing my environmental impact and not having to pay for an entire new machine.&lt;/p&gt;

&lt;p&gt;And since this is a work machine, I always try to avoid the flashy "gaming" stuff with ridiculous LED lights and absurd price tags. Also, I never go for the high-end stuff because it's too expensive and I just don't need it. On the other hand, I don't want to get the cheaper stuff, since that would make the machine slow and it wouldn't last much.&lt;/p&gt;

&lt;p&gt;Currently, my main desktop has these parts in it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AMD Ryzen 5 2600 CPU with 6 cores and max clock of 3.4 GHz&lt;/li&gt;
&lt;li&gt;Gigabyte AB350 3 motherboard&lt;/li&gt;
&lt;li&gt;32 GB of RAM DDR4 Kingston HyperX Fury&lt;/li&gt;
&lt;li&gt;Asus Radeon RX580 graphics card with 8GB of RAM&lt;/li&gt;
&lt;li&gt;Around 5 TB of storage in multiple Samsung SSDs (one 840 EVO, three 870 EVO)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All components except for the three 870 EVO SSDs are a few years old but it's still a very solid machine. The graphics card was launched in 2017 and I bought mine in 2018. It's a good card and I still play games with it without any problem. The CPU is also from 2018 but I honestly don't feel the need to upgrade.&lt;/p&gt;

&lt;p&gt;What I suggest next is what I would buy for myself if I were building a new machine from scratch right now, November 2022. Keep in mind that my main focus is software development, not "gaming" (whatever that degenerate verb means). I do play some games from time to time but they're not as heavy on the GPU as the big AAA titles. My main concern is having plenty of RAM and a decent CPU that can easily run multiple processes without choking.&lt;/p&gt;

&lt;p&gt;I also suggest that you check &lt;a href="https://www.userbenchmark.com/"&gt;UserBenchmark&lt;/a&gt; to see for yourself what's out there and find your sweet spot between price and power.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;You will find links to Amazon for the products I suggest. If you buy it from them, I'll get a small fee at no cost to you.&lt;/p&gt;

&lt;p&gt;I never used affiliate links on this website and I actually removed the ads I used to have here many years ago but I decided to give this a try and see if I can earn a few €€ from it.&lt;/p&gt;

&lt;p&gt;That said, I would strongly suggest you support a local shop and buy from them instead, if you can (they're usually more expensive).&lt;/p&gt;

&lt;h2&gt;
  
  
  CPU
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yJ52ZbZQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ut9gyqrf6mbrfztynfsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yJ52ZbZQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ut9gyqrf6mbrfztynfsa.png" alt="AMD Ryzen 7" width="264" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My recommendation would be AMD, since it tends to be slightly cheaper than Intel for the same power and have more cores for the same price-point.&lt;/p&gt;

&lt;p&gt;They recently announced their new Ryzen 7000 lineup of CPUs along with a new socket AM5, and while this means the CPUs and motherboards will be more expensive due to the novelty factor, I still recommend them because if I'm building a new machine, I want it to last as much as possible.&lt;/p&gt;

&lt;p&gt;That said, I'd probably go for the &lt;a href="https://www.amd.com/en/product/12166"&gt;Ryzen 5 7600X&lt;/a&gt; (buy it on &lt;a href="https://amzn.to/3USOWEN"&gt;Amazon&lt;/a&gt;), based on their "Zen 4" architecture. It's one of the more affordable ones at around €350 but still packs 6 cores / 12 threads, and a clock speed of 4.7 GHz which can be boosted up to 5.3 GHz. My current one also has 6 cores but a lower clock speed and like I said, it's more than enough for what I do.&lt;/p&gt;

&lt;p&gt;If you don't mind paying an extra €100 for a couple more cores, slightly more speed, and a tiny bit more L1 and L2 cache, you can go for the &lt;a href="https://www.amd.com/en/product/12161"&gt;Ryzen 7 7700X&lt;/a&gt; (buy it on &lt;a href="https://amzn.to/3tu1NBu"&gt;Amazon&lt;/a&gt;). Depending on how heavy your CPU usage is, or if you're not planning to get a graphics card (all Ryzen 7000 CPUs have graphics capabilities integrated) it may be worth the extra cost.&lt;/p&gt;

&lt;p&gt;Yes, you could even go for a Ryzen 9 7900X or 7950X but frankly, I don't think the extra cost is worth it, and it has the added negative point of spending more energy, which in turn means more money spent on electricity and the equivalent added environmental impact. It also requires more cooling, and though the cooler I suggest is enough, it will probably be more noisy.&lt;/p&gt;

&lt;h3&gt;
  
  
  CPU cooler
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iVJhvpfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8046ubozcxjp2m2cuthn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iVJhvpfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8046ubozcxjp2m2cuthn.png" alt="Noctua NH-D15" width="274" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Ryzen 7000 series don't come with a cooler, so you need to get one separately. Both the Ryzen 5 7600X and the Ryzen 7 7700X have a TDP (&lt;a href="https://www.computerhope.com/jargon/t/tdp.htm"&gt;Thermal Design Power&lt;/a&gt;) of 105W, so you need a cooler designed to handle at least that much. If you decide to get a more powerful CPU, you need to check that the cooler you get is enough for it.&lt;/p&gt;

&lt;p&gt;We want coolers to be silent, especially when building a machine for work. Usually, larger fans can displace more air and thus need to rotate less to cool down their targe. This also makes is tricky, though, because coolers nowadays are huge beasts that take up some considerable real-estate inside the computer case and can even interfere with other components, more commonly the RAM modules.&lt;/p&gt;

&lt;p&gt;The two coolers I mention should fit any of the motherboards I suggest without any issues but keep this in mind if you pick different components and always check the cooler's dimensions to make sure you have enough clearing for whatever is around the CPU socket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://noctua.at/"&gt;Noctua&lt;/a&gt; has been one of my favourite brands for coolers for a long time because they haven't fallen prey to the "gaming" BS, so their parts are sober, focus on quality, and don't have any unnecessary RGB lights or fancy designs. Their website also doesn't look like it was designed for 5-year olds, and you can actually get useful information on it. But more importantly, their coolers are really good, they are silent and last a very long time.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://noctua.at/en/products/cpu-cooler-retail/nh-d15"&gt;NH-D15&lt;/a&gt; (&lt;a href="https://amzn.to/3UTExJs"&gt;Amazon&lt;/a&gt;) is a good one for the setup I'm proposing and should even give you enough room to upgrade to a Ryzen 9, if you want.&lt;/p&gt;

&lt;p&gt;Another good option would be the &lt;a href="https://www.bequiet.com/en/cpucooler/1378"&gt;bequiet! Dark Rock Pro 4&lt;/a&gt; (&lt;a href="https://amzn.to/3EgoYUQ"&gt;Amazon&lt;/a&gt;) and, surprisingly, is actually cheaper than the Noctua.&lt;/p&gt;

&lt;p&gt;In case you're wondering, no, you don't need a water cooler for these CPUs. Maybe if you want to overclock them, but even then, the two coolers I suggested should be able to handle it - but I don't recommend overclocking, so do it at your own risk. In any case, if you want to splurge on a fancy toy, the &lt;a href="https://www.bequiet.com/en/watercooler/1959"&gt;be quiet! Pure Loop&lt;/a&gt; (&lt;a href="https://amzn.to/3ATAUvd"&gt;Amazon&lt;/a&gt;) or the &lt;a href="https://www.bequiet.com/en/watercooler/2260"&gt;be quiet! Silent Loop 2&lt;/a&gt; (&lt;a href="https://amzn.to/3On2Woc"&gt;Amazon&lt;/a&gt;) seem like good choices. I'd save the money for something else, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motherboard
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_wNR61aC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiddovmmepop0bqqdujl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_wNR61aC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiddovmmepop0bqqdujl.png" alt="MSI MPG B650 CARBON WIFI" width="245" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The motherboard you get needs to take the CPU into account, of course. Not just the brand, though - the socket type (AM5, AM4, etc), the chipset and RAM type also have to be considered.&lt;/p&gt;

&lt;p&gt;The socket is just the physical socket where you insert the CPU. The chipset is what controls the flow of data between all the components, like the CPU, the GPU, drives, RAM, etc. Different chipsets have different characteristics. For example, some may support more SATA ports than others.&lt;/p&gt;

&lt;p&gt;Ryzen 7000 supports DDR5 RAM and socket AM5. DDR5 is pretty new, and the Zen 4 and socket AM5 are the latest architectures from AMD, so if you buy a motherboard that supports them, it means it's more "future-proof" and a machine based on them will last longer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chipset
&lt;/h3&gt;

&lt;p&gt;The Ryzen 7000 works with &lt;a href="https://www.amd.com/en/chipsets/am5"&gt;these 4 chipsets&lt;/a&gt;: X670E, X670, B650E and B650.&lt;/p&gt;

&lt;p&gt;The main difference between the X670(E) and the B650(E) is that the X670(E) has more PCIe lanes, and it also supports more USB and SATA ports.&lt;/p&gt;

&lt;p&gt;The difference between the ones with E at the end and the ones without, is that the "E" version supports PCI-Express 5.0 for both the graphics (x16 socket) and NVMe drives, while the non-E version only supports PCIe 4.0 for the graphics card and it is optional for the NVMe drive (the board manufacturer decides, I guess?).&lt;/p&gt;

&lt;p&gt;See the table below, which is a simplified version of the full table from AMD's page linked above:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chipset&lt;/th&gt;
&lt;th&gt;Graphics&lt;/th&gt;
&lt;th&gt;NVMe&lt;/th&gt;
&lt;th&gt;USB 10 GBps&lt;/th&gt;
&lt;th&gt;USB 20 GBps&lt;/th&gt;
&lt;th&gt;Max SATA ports&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;X670E&lt;/td&gt;
&lt;td&gt;1x16 or 2x8 PCIe 5.0&lt;/td&gt;
&lt;td&gt;1x4 PCIe® 5.0 plus 4x PCIe® GPP&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X670&lt;/td&gt;
&lt;td&gt;1x16 or 2x8 PCIe 4.0&lt;/td&gt;
&lt;td&gt;1x4 PCIe® 5.0 plus 4x PCIe® GPP&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B650E&lt;/td&gt;
&lt;td&gt;1x16 or 2x8 PCIe 5.0&lt;/td&gt;
&lt;td&gt;1x4 PCIe® 5.0 plus 4x PCIe® GPP&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B650&lt;/td&gt;
&lt;td&gt;1x16 or 2x8 PCIe 4.0&lt;/td&gt;
&lt;td&gt;1x4 PCIe® 4.0 (PCIe® 5.0 Optional)&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I would go for the B650 because I don't think I'll need more than 4 SATA ports and the fast USB ports are not that important, but again, I'd like to future-proof my machine as much as possible, so broader PCIe 5.0 support would be nice. The B650E it is, then.&lt;/p&gt;

&lt;h3&gt;
  
  
  The actual motherboard
&lt;/h3&gt;

&lt;p&gt;After looking at MSI, Gigabyte, Asus and ASRock, I think the best value for money would be an &lt;a href="https://us.msi.com/Motherboard/MPG-B650-EDGE-WIFI/"&gt;MSI MPG B650 EDGE WIFI&lt;/a&gt; (&lt;a href="https://amzn.to/3V8n7bE"&gt;Amazon&lt;/a&gt;). For a little bit more (~€50) you can also get the &lt;a href="https://www.msi.com/Motherboard/MPG-B650-CARBON-WIFI"&gt;MSI MPG B650 CARBON WIFI&lt;/a&gt; (&lt;a href="https://amzn.to/3UY3YcE"&gt;Amazon&lt;/a&gt;) which, compared to the EDGE, supports 2 PCIe x16 slots (as opposed to only 1), 4 M.2 slots (only 3 on the EDGE), and a few more USB ports.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.asrock.com/mb/AMD/B650E%20PG%20Riptide%20WiFi/index.asp#Specification"&gt;ASRock B650E PG Riptide WiFi&lt;/a&gt; (&lt;a href="https://amzn.to/3URuQKX"&gt;Amazon&lt;/a&gt;) is also a nice choice. If you want to throw some money out the window, the &lt;a href="https://www.gigabyte.com/Motherboard/B650E-AORUS-MASTER-rev-10/sp#sp"&gt;Gigabyte B650E AORUS MASTER&lt;/a&gt; (&lt;a href="https://amzn.to/3Tx6HID"&gt;Amazon&lt;/a&gt;) is also good but it costs &lt;em&gt;a lot&lt;/em&gt; more than the other two.&lt;/p&gt;

&lt;p&gt;All of these include bluetooth 5.2, audio and wireless networking, so you won't need to buy additional parts for those.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAM
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7NupD60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztla7cwlcphf7680w1p0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7NupD60--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztla7cwlcphf7680w1p0.png" alt="Kingston FURY Beast DDR5" width="469" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AMD Zen 4 architecture only supports DDR5. All Zen 4 / AM5 motherboards support it, so that's one less concern. Other than that, you have to pay attention to two numbers: data rate and CAS latency.&lt;/p&gt;

&lt;p&gt;In very simple terms, the data rate is the memory "speed" in MHz, and it is usually represented as a number after the DDR designation, such as DDR4-3600 or DDR5-6200. Usually, higher is better but your motherboard and CPU have to support it.&lt;/p&gt;

&lt;p&gt;The CAS latency, sometimes abbreviated as CL, is basically the amount of time it takes for the memory circuit to initiate an operation. Obviously, you want this to be as low as possible.&lt;/p&gt;

&lt;p&gt;The motherboards I suggested support dual-channel (meaning you should install RAM modules in pairs), non-ECC, un-buffered memory, up to DDR5-6600.&lt;/p&gt;

&lt;p&gt;With that in mind, I'd get a set of 2x16 GB &lt;a href="https://www.kingston.com/en/memory/gaming/kingston-fury-beast-ddr5-memory"&gt;Kingston FURY Beast DDR5-4800 CL38&lt;/a&gt; (&lt;a href="https://amzn.to/3UW9k8a"&gt;Amazon&lt;/a&gt;) or 2x16 &lt;a href="https://www.corsair.com/pt/pt/Categorias/Produtos/Mem%C3%B3ria/VENGEANCE-DDR5-Memory---Optimized-for-AMD/p/CMK32GX5M2B5200Z40"&gt;GB Corsair Vengeance DDR5-5200 CL40&lt;/a&gt; (&lt;a href="https://amzn.to/3tv4keV"&gt;Amazon&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;With the current prices, 32 GB is probably the sweet spot. More or less than that and you'll probably be paying more per GB than it's worth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k3Ic_pqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zg56mhliavyfmjpvjiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k3Ic_pqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zg56mhliavyfmjpvjiq.png" alt="Samsung 990 PRO NVMe M.2 SSD" width="597" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The choice for this part is easy. For years now, Samsung's EVO line has been the best value for money with really good performance that outshines pretty much all competition.&lt;/p&gt;

&lt;p&gt;Just grab a 1 TB &lt;a href="https://semiconductor.samsung.com/emea/consumer-storage/internal-ssd/970evoplus/"&gt;Samsung 970 EVO Plus NVMe M.2&lt;/a&gt; (&lt;a href="https://amzn.to/3X1pxue"&gt;Amazon&lt;/a&gt;) - don't go for the 980, despite the higher number, it's actually slower than the 970 EVO Plus.&lt;/p&gt;

&lt;p&gt;They're both PCIe 3.0, though, which is a shame since the motherboard supports PCIe 5.0, which is 4 times faster - from 32 GB/s to 128 GB/s. Samsung has the &lt;a href="https://semiconductor.samsung.com/consumer-storage/internal-ssd/990-pro/"&gt;990 PRO&lt;/a&gt; (&lt;a href="https://amzn.to/3Xjbdxq"&gt;Amazon&lt;/a&gt;), which is PCIe 4.0 at 64 GB/s, already double the speed of PCIe 3.0 - but also double the price. Might be worth it, if you have the spare budget.&lt;/p&gt;

&lt;p&gt;PCIe 5.0 drives are still not available for mere mortals but once they are, you'll be able to upgrade, if you really want to squeeze all the juice from your machine.&lt;/p&gt;

&lt;p&gt;If you'd rather have a more traditional SATA drive, the 1 TB &lt;a href="https://semiconductor.samsung.com/emea/consumer-storage/internal-ssd/870evo/"&gt;Samsung 870 EVO&lt;/a&gt; (&lt;a href="https://amzn.to/3XaHtTA"&gt;Amazon&lt;/a&gt;) is your choice. The QVO should have similar performance but it's supposed to last less due to the inferior storage cell technology. Keep in mind these will be significantly slower, though, typically less than 1 GB/s.&lt;/p&gt;

&lt;p&gt;One note about speed: I'm mentioning the maximum supported speeds of the PCIe bus but the actual speed of the SSDs will certainly be lower. For example, according to &lt;a href="https://ssd.userbenchmark.com/Compare/Samsung-970-Evo-Plus-NVMe-PCIe-M2-1TB-vs-Samsung-870-EVO-1TB/m693540vsm1445454"&gt;UserBenchmark&lt;/a&gt;, the 970 EVO Plus' sequential read speed goes up to 2.3 GB/s, while the 870 EVO only goes up to 468 MB/s.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graphics card
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I7sAXtZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/umm20mfrrrqjjuskk8n5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I7sAXtZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/umm20mfrrrqjjuskk8n5.png" alt="ASUS Dual Radeon RX 6600 8GB" width="349" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't want to use the integrated GPU from the CPU, you can get a dedicated (or "discrete", as they're called nowadays) graphics card. I never go for the high end ones because they're ridiculously expensive (thanks again, "gaming").&lt;/p&gt;

&lt;p&gt;I tend to prefer AMD's GPUs because they have officially supported open source drivers in the Linux kernel. Many people say they have terrible experiences with the open source Radeon drivers but so do many others with NVidia's drivers. My experience is that AMD's open source drivers have worked much better for me than NVidia's ever did (or even AMD's closed-source drivers, for that matter).&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.asus.com/us/motherboards-components/graphics-cards/dual/dual-rx6600-8g/"&gt;Asus Dual Radeon RX 6600 8 GB&lt;/a&gt; (&lt;a href="https://amzn.to/3tsEXuk"&gt;Amazon&lt;/a&gt;) is probably a good choice, as is the &lt;a href="https://www.powercolor.com/product?id=1623918331"&gt;Powercolor Fighter AMD Radeon™ RX 6600 8GB&lt;/a&gt; (&lt;a href="https://amzn.to/3Et7Zjy"&gt;Amazon&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Keep in mind, though, my benchmark is not AAA games, since I don't find most of them interesting at all. For those, you would probably be better served with a more powerful GPU, like the &lt;a href="https://www.gigabyte.com/Graphics-Card/GV-R66XTGAMING-OC-8GD#kf"&gt;Gigabyte Radeon RX 6600-XT Gaming OC 8GB&lt;/a&gt; (Amazon)&lt;/p&gt;

&lt;h2&gt;
  
  
  Power supply
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zpk1jnsa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ok2g3ntn2lg71ohvz5uz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zpk1jnsa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ok2g3ntn2lg71ohvz5uz.png" alt="be quiet! STRAIGHT POWER 11 750W Platinum" width="325" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You power supply unit (PSU) needs to be able to cope with the demands of the rest of your hardware. Without a dedicated graphics card and one of the CPUs I suggested, a 450 W PSU would probably be enough. That said, I would recommend getting a beefier PSU because eventually, you may want to upgrade to a more powerful CPU or add a dedicated graphics card, and in that case, 450 W simply won't be enough, so I'd go for at least 650 W, which definitely covers all the components I suggest here.&lt;/p&gt;

&lt;p&gt;You can also use a &lt;a href="https://outervision.com/power-supply-calculator"&gt;power supply calculator&lt;/a&gt; to have an idea of how much power you'll need for your components.&lt;/p&gt;

&lt;p&gt;Another thing to keep in mind is cable management. A modular or semi-modular PSU helps tremendously in this because it allows you to disconnect the cables you don't use. This has more advantages than it seems at first: better airflow and thus, better cooling; less cluttered inside of the case, which makes handling the innards of your machine easier; more room for other parts; in the unlikely event that you want to temporarily remove the PSU, you don't have to disconnect and then reconnect the cables from all the components, you just need to do it directly on the PSU, which is a lot easier.&lt;/p&gt;

&lt;p&gt;With that in mind, my suggestion goes to the &lt;a href="https://www.bequiet.com/en/powersupply/1768"&gt;be quiet! Straight Power 11 750W Platinum&lt;/a&gt; (&lt;a href="https://amzn.to/3i3ZF1a"&gt;Amazon&lt;/a&gt;). This should give you more than enough power even for a better dedicated graphics card than the ones I suggested but if you think that in the future you may want a more powerful graphics card or a beefier CPU, you can go for the &lt;a href="https://www.bequiet.com/en/powersupply/1767"&gt;850 W version&lt;/a&gt; (&lt;a href="https://amzn.to/3hXaYIg"&gt;Amazon&lt;/a&gt;) or even the &lt;a href="https://www.bequiet.com/en/powersupply/1766"&gt;1000 W one&lt;/a&gt; (&lt;a href="https://amzn.to/3TVAFGz"&gt;Amazon&lt;/a&gt;). The price difference between the 750W and the 1000W is "only" ~€50, so if you're not sure, perhaps it's worth spending a little bit more but ensuring you won't have to switch the PSU after a few months or a year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6G6mbS7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmrc8qmah9m24wpcs8f6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6G6mbS7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmrc8qmah9m24wpcs8f6.png" alt="be quiet!  SILENT BASE 802 Black" width="265" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since this is a work machine and not a toy, I recommend simple cases that prioritize silent operation and good air flow, and do away with the useless RGB lights and transparent panels that only make it more expensive without adding any real value.&lt;/p&gt;

&lt;p&gt;With that in mind, the &lt;a href="https://www.bequiet.com/en/case/921"&gt;be quiet! Pure Base 600 Black&lt;/a&gt; (&lt;a href="https://amzn.to/3gjEibq"&gt;Amazon&lt;/a&gt;) is a really nice case without costing a fortune. &lt;/p&gt;

&lt;p&gt;If you want an even more silent case and with a USB-C port, the &lt;a href="https://www.bequiet.com/en/case/2049"&gt;be quiet! Silent Base 802&lt;/a&gt; (&lt;a href="https://amzn.to/3tJNjxs"&gt;Amazon&lt;/a&gt;) is a greant choice.&lt;/p&gt;

&lt;p&gt;And if you don't mind spending a bit more for what I think is probably the best case around, get the &lt;a href="https://www.fractal-design.com/products/cases/define/define-7/"&gt;Fractal Design Define 7&lt;/a&gt; (&lt;a href="https://amzn.to/3Eq7VzM"&gt;Amazon in white&lt;/a&gt;, &lt;a href="https://amzn.to/3i0NH8t"&gt;and in black&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The end!
&lt;/h2&gt;

&lt;p&gt;That's it, you have all the necessary components to assemble your machine. Would you do anything differently? Let me know in the comments. If not, then it's time to grab those parts and have fun building your new desktop computer!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>hardware</category>
    </item>
    <item>
      <title>How to fix Code42 / Crashplan "Unable to sign in. Unknown error." on Linux (missing libuaw.so)</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Sat, 16 Jul 2022 22:49:14 +0000</pubDate>
      <link>https://dev.to/borfast/how-to-fix-code42-crashplan-unable-to-sign-in-unknown-error-on-linux-missing-libuawso-350a</link>
      <guid>https://dev.to/borfast/how-to-fix-code42-crashplan-unable-to-sign-in-unknown-error-on-linux-missing-libuawso-350a</guid>
      <description>&lt;p&gt;Crashplan, Code42's backup utility, was recently upgraded to version 10.0.0 on Linux and as soon as I upgraded it, it stopped working.&lt;/p&gt;

&lt;p&gt;I use Crashplan for some backups and recently, the GUI app said there was an upgrade available. It looked like it automatically downloaded the newer version, upgraded itself, and then it shut down. When I opened it again (the GUI), it would sit there for a minute or two and then complain it couldn't connect to the local service. I tried restarting the service manually but it kept crashing.&lt;/p&gt;

&lt;p&gt;I tried upgrading manually but was still spitting out the same error.&lt;/p&gt;

&lt;p&gt;Finally I uninstalled and reinstalled it, which seemed to finally allow the service to run and the app seemed to be able to connect to it but then the login was failing with a "Unable to sign in. Unknown error." message.&lt;/p&gt;

&lt;p&gt;Digging into the logs, I found that it seems to be missing a native library:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Native library (linux-x86-64/libuaw.so) not found in resource path (lib/com.backup42.desktop.jar:lang)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, I couldn't find anything about this library anywhere, which led me to think it's a proprietary library, meaning they released this new version without it. Great job! :P&lt;/p&gt;

&lt;p&gt;Asking Code42 for help only resulted in a generic response saying my version of Linux (Linux Mint) is not supported.&lt;/p&gt;

&lt;p&gt;It took me some time to find a &lt;a href="https://www.reddit.com/r/Crashplan/comments/upjjk3/fix_v10_fix_login_issue_missing_libuawso/"&gt;solution&lt;/a&gt; and since the problem recently happened again when it automatically upgraded from 10.0.0 to 10.2.0, I decided to document it here so I don't have to search for it again.&lt;/p&gt;

&lt;p&gt;Apparently Code42's Crashplan doesn't bother to detect other Linux distributions other than Red Hat Enterprise and Ubuntu, even if it's a distribution based on one of those, like CentOS or Linux Mint. It should install a specific library file depending on the detected operating system. Maybe I'm missing something here but I'd say that logic dictates if it needs to detect the OS in order to install the right file, if it can't detect the OS, the installation should fail, or maybe ask the user to manually select which distro they want to be considered.&lt;/p&gt;

&lt;p&gt;I've been meaning to switch to &lt;a href="https://kopia.io/"&gt;Kopia&lt;/a&gt; for a while now, so maybe this is the final push I need to finally move away from Crashplan, which is a shame. I used to love the service back in the "Crashplan for Home" days.&lt;/p&gt;

&lt;p&gt;Until then, here's how to fix this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.us2.crashplanpro.com/app/#/console/app-downloads"&gt;Download&lt;/a&gt; the tarball containing the installation files and decompress it - it should create a directory named "code42-install". Then open a shell in that directory and follow these guidelines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Extract the installation files so we can access the missing file.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-dc&lt;/span&gt; CrashPlanSmb_10.2.0.cpi | cpio &lt;span class="nt"&gt;-i&lt;/span&gt;

&lt;span class="c"&gt;# Stop the Crashplan service&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; /usr/local/crashplan/bin/service.sh stop

&lt;span class="c"&gt;# Copy the missing library file. The actual file path depends on your Linux version. For me it's ubuntu20 but you may need to replace it depending on which Linux version your system is based on. Look inside the nlib directory to see what other distributions are supported.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;nlib/ubuntu20/libuaw.so /usr/local/crashplan/nlib
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;u+x /usr/local/crashplan/nlib/libuaw.so

&lt;span class="c"&gt;# Restart the Crashplan service&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; /usr/local/crashplan/bin/service.sh start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Maybe my next article will be on how to do backups with &lt;a href="https://kopia.io/"&gt;Kopia&lt;/a&gt;...&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Header photo by &lt;a href="https://unsplash.com/@benjaminlehman?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;benjamin lehman&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>backups</category>
      <category>linux</category>
    </item>
    <item>
      <title>How to override and share git configuration options between multiple directories</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Sun, 28 Feb 2021 14:12:03 +0000</pubDate>
      <link>https://dev.to/borfast/how-to-override-and-share-git-configuration-options-between-multiple-directories-29kd</link>
      <guid>https://dev.to/borfast/how-to-override-and-share-git-configuration-options-between-multiple-directories-29kd</guid>
      <description>&lt;p&gt;Sometimes I have a set of projects for which I want to override a few git configuration options. For example, I have a directory with all the git repositories for my work projects. For those work repositories, I want to use my company's email address and GPG signing key instead of my personal ones.&lt;/p&gt;

&lt;p&gt;The obvious way to do it is to set the relevant git configuration options in each of the directories but if there are many projects, it becomes a tedious process. And if I ever want to change something, I'll have to do it all over again.&lt;/p&gt;

&lt;p&gt;Luckily, there's a better way: Git &lt;a href="https://git-scm.com/docs/git-config#_conditional_includes"&gt;Conditional Includes&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;This allows us to add configuration files &lt;em&gt;conditionally&lt;/em&gt;,  depending on the folder in use. In other words, we can tell git to use different configuration options depending on the repository path.&lt;/p&gt;

&lt;p&gt;For example, let's say I keep all my work projects under &lt;code&gt;~/myworkprojects&lt;/code&gt;. All I need to do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edit my global git configuration in &lt;code&gt;~/.gitconfig&lt;/code&gt; and add:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[includeIf "gitdir:~/myworkprojects/"]&lt;/span&gt;
    &lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;~/myworkprojects/.gitconfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Edit &lt;code&gt;~/myworkprojects/.gitconfig&lt;/code&gt; and add all the work-specific configurations I want. For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[user]&lt;/span&gt;
    &lt;span class="py"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;myemail@mycompany.com&lt;/span&gt;
    &lt;span class="py"&gt;signingkey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ABC123DEF456...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it!&lt;/p&gt;

&lt;p&gt;Now all the repositories inside &lt;code&gt;~/myworkprojects&lt;/code&gt; will use my work email and signing key, while anything outside that folder will retain the default configuration. And if we have other folders with multiple repositories for which we want to override configuration options, we can add more &lt;code&gt;includeIf&lt;/code&gt; settings in &lt;code&gt;~/.gitconfig&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can even define paths that match any directory that ends with our give pattern. An example from the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] the pattern &lt;code&gt;foo/bar&lt;/code&gt; becomes &lt;code&gt;**/foo/bar&lt;/code&gt; and would match &lt;code&gt;/any/path/to/foo/bar&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the other hand, if we don't add a trailing slash to the &lt;code&gt;gitdir&lt;/code&gt; keyword, it will not match sub-folders recursively. For example: &lt;code&gt;[includeIf "gitdir:/foo/bar/"]&lt;/code&gt; would match &lt;code&gt;/foo/bar/baz&lt;/code&gt; and &lt;code&gt;/foo/bar/boo&lt;/code&gt; but &lt;code&gt;[includeIf "gitdir:/foo/bar"]&lt;/code&gt; would only match &lt;code&gt;/foo/bar&lt;/code&gt; and nothing else inside it.&lt;/p&gt;

&lt;p&gt;One other detail to keep in mind is: &lt;code&gt;includeIf&lt;/code&gt; &lt;em&gt;includes&lt;/em&gt; the file we specify as if we copied and pasted its contents. This means it should be set &lt;em&gt;after&lt;/em&gt; the option(s) we want to override in &lt;code&gt;~/.gitconfig&lt;/code&gt;. Otherwise, they will be overridden again.&lt;/p&gt;

&lt;p&gt;For example, if our &lt;code&gt;.gitconfig&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[includeIf "gitdir:~/myworkprojects/"]&lt;/span&gt;
    &lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;~/myworkprojects/.gitconfig&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="nn"&gt;[user]&lt;/span&gt;
    &lt;span class="py"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;myemail@mycompany.com&lt;/span&gt;
    &lt;span class="py"&gt;signingkey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ABC123DEF456...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;[user]&lt;/code&gt; options in &lt;code&gt;~/myworkprojects/.gitconfig&lt;/code&gt; will not take effect because they would be overridden later in &lt;code&gt;~/.gitconfig&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the other hand, if we do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[user]&lt;/span&gt;
    &lt;span class="py"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;myemail@mycompany.com&lt;/span&gt;
    &lt;span class="py"&gt;signingkey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ABC123DEF456...&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="nn"&gt;[includeIf "gitdir:~/myworkprojects/"]&lt;/span&gt;
    &lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;~/myworkprojects/.gitconfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will be doing the exact opposite: we first specify the &lt;code&gt;[user]&lt;/code&gt; options and then we override them with the values from the included file.&lt;/p&gt;

&lt;p&gt;Since the goal is to override the options set in the global config, I just pop the &lt;code&gt;includeIf&lt;/code&gt; at the end of &lt;code&gt;~/.gitconfig&lt;/code&gt; to make sure nothing else will get in the way.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Basic rules for software deployment</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Tue, 22 Sep 2020 14:35:25 +0000</pubDate>
      <link>https://dev.to/borfast/basic-rules-for-software-deployment-3abf</link>
      <guid>https://dev.to/borfast/basic-rules-for-software-deployment-3abf</guid>
      <description>&lt;p&gt;Now and then someone asks my opinion on what is the best way to deploy code to a server. There's a lot to be said about this subject, so I usually end up disappointing the inquirer because I rarely have a simple answer for them. Like so many other things in life, the best way to do it depends on the exact situation. The scale you're operating at, the type of servers you use, the type of application you're deploying, the level of security required, the infrastructure you're using, etc.&lt;/p&gt;

&lt;p&gt;What I usually do is convey a few basic rules that I always follow in every scenario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated testing
&lt;/h3&gt;

&lt;p&gt;The first rule is also the one that most people overlook or outright ignore but it's also probably the most important: there has to be some sort of automated testing that runs before anything else and stops the deployment process if anything goes wrong.&lt;/p&gt;

&lt;p&gt;Unit testing, integration testing, functional testing - do whatever you want but &lt;em&gt;never&lt;/em&gt;, &lt;strong&gt;ever&lt;/strong&gt; deploy code that isn't tested in an automated way.&lt;/p&gt;

&lt;p&gt;I can't stress enough how important this is. It gives you peace of mind because you know that if a bug is introduced somewhere, there's a very good chance it will get caught before reaching production (assuming you're doing your tests correctly).&lt;/p&gt;

&lt;p&gt;Most people think this is the biggest benefit of testing and it is a huge benefit - but there's something else I consider an even greater benefit, even though it's a much more subtle one.&lt;/p&gt;

&lt;p&gt;Not being burdened with the worry of breaking something on the live servers gives developers people peace of mind. By removing this weight from the developers' shoulders, they can be more productive because they can manipulate their code freely without (as much) fear of breaking everything.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We don't write tests (only) to catch bugs before they hit production - we write tests so we can refactor and iterate faster.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There's a lot more to be said about automated testing but the bottom line is: do it, no excuses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automate all the things
&lt;/h3&gt;

&lt;p&gt;This is another very common mistake: updating production code by logging into a server and running &lt;code&gt;git pull&lt;/code&gt;. That's a bit like playing Russian roulette with more than one bullet in the pistol chamber.&lt;/p&gt;

&lt;p&gt;Automating everything means that &lt;strong&gt;at most&lt;/strong&gt; you push a button to trigger a deployment. From that point on, everything has to happen automatically. A very common setup is to have a hook of some sort on the code repository and when code is pushed, a deployment is triggered and a script is executed.&lt;/p&gt;

&lt;p&gt;Why is this important? For a very simple reason: we are humans. Humans make mistakes whereas a deployment script is deterministic: it will run the same way every single time. If your deployment consists only of getting a few changed files from your code repository, it's not a big deal. But as you add more steps to this, the probability of making a mistake, even on something simple, gets higher.&lt;/p&gt;

&lt;p&gt;For example, a long time ago I worked on a project where the project lead insisted that we manually deployed our code. He said that way we would feel more responsible and would be more careful. I didn't want to take any chances, so I wrote a script to do it for me but most of my colleagues were doing it manually. They did it dozens of times without a problem but one time one of them forgot to run the database migrations and several hours passed before anyone noticed there was a problem. By then there was a ton of corrupted data and we all had a super fun time recovering from the event.&lt;/p&gt;

&lt;p&gt;So do yourself a favour and resist the temptation of doing things manually. It's far too easy to mess it up even in simple scenarios. Write a script to automate your deployment from the start of your project, even if it's just a simple &lt;code&gt;git pull&lt;/code&gt;. It will eventually grow and if you do it, you will never realise how thankful you should be that you did it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying the code
&lt;/h3&gt;

&lt;p&gt;This is where things get murky because it depends on what you are developing. For example, if you're deploying a piece of Python or Ruby, you can have a simple script that runs &lt;code&gt;git pull&lt;/code&gt; or something similar and restarts your web server or long-lived processes. But if you're building a Java application, it's a bit more involved, because a new &lt;code&gt;.jar&lt;/code&gt; file has to be built and whatnot. If you're using a database you may need to run some database migrations. You probably need to compile and publish some static files. There are a lot of variables.&lt;/p&gt;

&lt;p&gt;I used to have a &lt;a href="http://www.fabfile.org/"&gt;Fabric&lt;/a&gt; or &lt;a href="http://capistranorb.com/"&gt;Capistrano&lt;/a&gt; script that contains all the steps I would do if I were manually deploying the code. That script is triggered by &lt;a href="https://travis-ci.com/"&gt;TravisCI&lt;/a&gt;, &lt;a href="https://circleci.com/"&gt;CircleCI &lt;/a&gt;, &lt;a href="https://drone.io/"&gt;Drone.io&lt;/a&gt;, &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt; or whatever Continuous Integration tool I'm using when I push code to my repository (usually to a specific branch, like &lt;code&gt;master&lt;/code&gt;). It connects to the servers and executes a series of pre-programmed steps to fetch the new code from the repository, publish static assets, run database migrations, restart servers, rotate DNS for multiple server redundancy, etc.&lt;/p&gt;

&lt;p&gt;A lot of people do a simple &lt;code&gt;git pull&lt;/code&gt; but the way I used to do it was running&lt;br&gt;
&lt;code&gt;git fetch origin&lt;/code&gt; first followed by &lt;code&gt;git reset --hard HEAD&lt;/code&gt;. This way I guarantee that if anyone committed the capital sin of manually going into the server and changing live code, those changes are gone.&lt;/p&gt;

&lt;p&gt;Nowadays I prefer to use Docker instead of scripts that change things on servers. The CI tool does the job of building a container image and pushing it to a repository. Then it takes care of updating the running services on the servers or a hosted service like &lt;a href="https://cloud.google.com/run/"&gt;Google Cloud Run&lt;/a&gt;, &lt;a href="https://cloud.google.com/kubernetes-engine"&gt;Google Kubernetes Engine&lt;/a&gt;, &lt;a href="https://aws.amazon.com/ecs/"&gt;AWS ECS&lt;/a&gt;, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single source of truth
&lt;/h3&gt;

&lt;p&gt;There should be a single "source of truth" for your code. This means that anything coming from outside the repository should be ignored, discarded and not permitted on the production servers.&lt;/p&gt;

&lt;p&gt;If someone decides to patch a bug directly in the live code, they should get 5 lashes for each line of changed code. If they do that and then don't apply the same changes on the repository, then that's another 20 lashes :-)&lt;/p&gt;

&lt;p&gt;That's because the next time the code is deployed, the patch will be overwritten and the bug will be back. Or if you use the plain &lt;code&gt;git pull&lt;/code&gt; method, the deployment may crash because there are untracked changes in the server's copy of the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final thoughts
&lt;/h3&gt;

&lt;p&gt;I hope this gives you a few ideas. Again, there's a lot to be said&lt;br&gt;
about this topic and it entirely depends on your specific situation,&lt;br&gt;
so it's impossible to come up with "the best way" to deploy software.&lt;/p&gt;

&lt;p&gt;If this is a topic that interests you, I strongly recommend you read Zach Holman's post titled &lt;a href="https://zachholman.com/posts/deploying-software"&gt;"How to deploy software"&lt;/a&gt;. It's one of the best articles I ever read about it. It's long but worth every minute.&lt;/p&gt;

&lt;p&gt;What about you, how do you deploy software? What are your basic rules?&lt;/p&gt;

</description>
      <category>devops</category>
    </item>
    <item>
      <title>8 reasons why I rarely sign an NDA</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Wed, 02 Sep 2020 22:08:30 +0000</pubDate>
      <link>https://dev.to/borfast/8-reasons-why-i-rarely-sign-an-nda-3l8p</link>
      <guid>https://dev.to/borfast/8-reasons-why-i-rarely-sign-an-nda-3l8p</guid>
      <description>&lt;p&gt;Now and then, somewhere along the recruitment process for a job, the recruiter will hit me with an NDA. In case you don't know what it is, NDA stands for Non-Disclosure Agreement. It's an agreement between two parties meant to protect confidential information they wish to share.&lt;/p&gt;

&lt;p&gt;The first problem I have with this is that some recruiters don't mention an NDA from the start. They just assume I'll sign it. If I don't want to sign it, the recruiter and I will have wasted all our time up to that point. For this reason, it only gets worse the later in the process this detail is brought to light.&lt;/p&gt;

&lt;p&gt;A job interview should be a friendly conversation about if and how the employer and I can enter a mutually beneficial professional relationship. An NDA makes things less than friendly and mostly only gets in the way. The following are the reasons why I rarely sign one.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Legal jargon
&lt;/h4&gt;

&lt;p&gt;The language used in most NDAs is meant for lawyers. I'm sure you've seen the sort of text: inscrutably dense and full of legal mumbo jumbo that sometimes not even lawyers understand.&lt;/p&gt;

&lt;p&gt;I'm not a lawyer, so this means that even if I &lt;em&gt;think&lt;/em&gt; I understand what's written, I may well be making a costly mistake. I never sign anything that I'm not 100% sure I fully understand.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Too much liability
&lt;/h4&gt;

&lt;p&gt;Some NDAs almost feel like a threat instead of an agreement. They have clauses that say I will have to pay tens or hundreds of thousands of Euros in damages in case of a breach. Sometimes it's a tiny startup that doesn't even have a product yet and thus have no market value. Some say they will be the sole arbiters of how much damage I have caused. Some say things I'm not even sure how to describe or interpret. For example (emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Parties expressly agree that that any breach or &lt;strong&gt;threatened&lt;/strong&gt; breach of this Agreement will cause not only financial harm to the Disclosing Party but also &lt;strong&gt;irreparable harm for which monetary damages would not be sufficient remedy&lt;/strong&gt; for any breach of this Agreement, and that in addition to all other remedies, the Disclosing Party shall be entitled to specific performance and injunctive and other equitable relief as a remedy for any such breach, and the Receiving Party further agrees to waive any requirement for the securing or posting of any bond in connection with such remedy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How can a mere threat of breach cause as much harm as an actual breach of confidentiality? And keep in mind how easy it can be for someone to twist what someone else says and make it sound like a threat.&lt;/p&gt;

&lt;p&gt;This is ripe for abuse and I don't want to feel that I almost have to fear for my life if I were to accidentally reveal something.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Too broad
&lt;/h4&gt;

&lt;p&gt;Some NDAs are too broad in what they try to cover, both in scope and reach. To start  (emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The term “Proprietary Information” means, to the extent &lt;strong&gt;previously&lt;/strong&gt;, presently or subsequently disclosed by or for Discloser to Recipient [...]"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They want to punish me if I reveal things &lt;em&gt;they already told me&lt;/em&gt;, and they want my consent for this. If they fear I divulge their secrets, how about not telling me anything until I sign the document?&lt;/p&gt;

&lt;p&gt;But the real problem is usually the endless list of generic things they don't want me to disclose. I wouldn't find it odd if it included my own name as something they didn't want me to disclose.&lt;/p&gt;

&lt;p&gt;For example (again, emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] all financial, business, legal and technical information of Discloser or any of its affiliates, suppliers,&lt;br&gt;
customers and employees (including information about research, development, operations, &lt;strong&gt;marketing&lt;/strong&gt;, transactions, regulatory&lt;br&gt;
affairs, discoveries, inventions, methods, processes, &lt;strong&gt;articles&lt;/strong&gt;, materials, algorithms, software, specifications, designs, drawings,&lt;br&gt;
data, strategies, plans, prospects, know-how and ideas, whether tangible or intangible, and including all copies, abstracts,&lt;br&gt;
summaries, analyses and other derivatives thereof), that is marked or otherwise identified as proprietary or confidential at the&lt;br&gt;
time of disclosure, or that by its nature would be understood &lt;strong&gt;by a reasonable person&lt;/strong&gt; to be proprietary or confidential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wow, I wonder if they could have included anything else in there. This particular one is even bold enough to include marketing and articles. In theory, those are things meant to be public but they are concerned that I may disclose them.&lt;/p&gt;

&lt;p&gt;And who decides what a "reasonable person is" when the time comes to decide whether something is proprietary or confidential?&lt;/p&gt;

&lt;p&gt;I usually take this as two possible signs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the company doesn't know what they're doing and are trying to look more professional, or perhaps they are genuinely trying to protect their value but shooting themselves in the foot in the process, or;&lt;/li&gt;
&lt;li&gt;they want a weapon they can use against me in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In any case, I don't want to sign something like this. I don't want to fear to sneeze and get sued because the droplets I expelled may contain some sort of secret.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Non-compete clauses
&lt;/h4&gt;

&lt;p&gt;These clauses usually state that I will not work for a competitor during a period of X years (I've seen it go up to 10!)&lt;/p&gt;

&lt;p&gt;First of all, what is a competitor? Let's imagine I sign such an agreement with Google or Microsoft. Those companies do business in almost any area you can imagine. This means I would be preventing myself from working in software engineering for that amount of time. Why would I want to do that to myself?&lt;/p&gt;

&lt;p&gt;But this doesn't make sense even with smaller companies. Let's say a small startup approaches me. They want to hire me, so we sign an NDA for a job interview. In the end, we conclude we're not a good fit and we part ways amicably, wishing each other good luck. Later, another company shows interest in hiring me. We're a match made in heaven but they happen to have a project that may be considered a competitor to the first company. I wouldn't be able to accept a job there.&lt;/p&gt;

&lt;p&gt;They want to protect their ideas, I guess, but the value is in execution, not in the idea. Barring something exceptionally novel, ideas are a dime a dozen. Anyone could come up with a ton of great ideas but only a few companies are actually able to bring them to fruition. That's not because they ferociously protected their ideas with draconian agreements. It's because they executed them better than everyone else.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Non-solicitation clauses
&lt;/h4&gt;

&lt;p&gt;These usually say that I will not be hired by, or try to hire any of the company's current employees for a period of Y years (typically from 1 to 5 years).&lt;/p&gt;

&lt;p&gt;If their employees are so dissatisfied working there that they want to leave, they should consider changing something. Companies should retain their employees by making them feel valued, not by using legal shackles. Some say it's a way for a company to protect the investment they made in that person. I can understand that but again, they shouldn't do it by shackling their employees. Instead, offer them retention bonuses, give them better working conditions, listen to them and make them feel valued. It's not my fault they're not doing these things.&lt;/p&gt;

&lt;p&gt;As for not being hired, how am I supposed to know that someone I never met and is trying to hire me, used to work at that company I signed an NDA with? I don't meet everyone from the company at a job interview. Sure, I can stalk them and try to find out but I don't want to keep track of all the NDAs I sign (see more on that below). Besides, concealing that information is trivial.&lt;/p&gt;

&lt;p&gt;But above all, I don't want to skip a great job opportunity because of a 30-minute conversation from years before, which didn't even lead to anything, but for which I was forced to sign an NDA.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. I don't want the burden
&lt;/h4&gt;

&lt;p&gt;If I start signing all NDAs people ask me to, I will soon lose track of what I signed. If I wanted to make sure I wasn't in violation any of them, I would have to keep track of every detail of every NDA I signed and keep it in mind during every conversation I had.&lt;/p&gt;

&lt;p&gt;I don't have time for that and even if I did, I would never want to spend it that way. Besides, it's obviously not going to work because no one can remember that much detail.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. There's usually no big secret
&lt;/h4&gt;

&lt;p&gt;In most job interviews, the information shared by the interviewer is not a big secret - nor should it be. The interviewer should tell me &lt;em&gt;what&lt;/em&gt; the company does, not &lt;em&gt;how&lt;/em&gt; they do it. I don't need to know their secret sauce to decide whether I want to work there. Granted, sometimes it is useful or even necessary but most of the time, it's not.&lt;/p&gt;

&lt;p&gt;Something even more common is that there's no secret at all. The interviewer does not reveal any secret or does not have anything secret to tell me because whatever the company does is not a secret.&lt;/p&gt;

&lt;p&gt;This means that for most cases, there should be nothing to protect and an NDA is unnecessary. Still, they require it of me. It becomes a barrier to dialogue rather than something useful. A thorn in our newly formed relationship.&lt;/p&gt;

&lt;h4&gt;
  
  
  8. Unenforceable
&lt;/h4&gt;

&lt;p&gt;It is my belief that a lot of NDAs are simply unenforceable, especially when they are overly broad.&lt;/p&gt;

&lt;p&gt;Proving that I divulged confidential information can also be tricky, to say the least. I can think of dozens of ways in which I could spread that information or use it to my advantage without it ever being traced back to me.&lt;/p&gt;

&lt;p&gt;Finally, unless a company has a legal presence in my country, it's going to be extra hard for them to sue me if I breach the agreement, so why do they even bother?&lt;/p&gt;

&lt;p&gt;That said, I never breached an NDA and thus, never faced legal action for doing so. This means I may be completely wrong about all this. Lots of people seem to agree with me, though. If you search the web for this topic, you will find many blog posts and articles saying the same thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 6 reasons why I will consider signing an NDA:
&lt;/h3&gt;

&lt;p&gt;I believe most people have good intentions when asking me to sign an NDA but are inexperienced or haven't thought it thoroughly. Because of this and all the points above, I won't sign most NDAs. Usually, the potential for negative consequences for me far outweighs the positive things that can come out of it.&lt;/p&gt;

&lt;p&gt;That said, sometimes I will sign an NDA, depending on a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The job is of special interest to me. If it's not something special, I won't even bother.&lt;/li&gt;
&lt;li&gt;I am told upfront that there will be an NDA for me to sign.&lt;/li&gt;
&lt;li&gt;The information considered confidential is defined and scoped in a very clear and unambiguous way.&lt;/li&gt;
&lt;li&gt;The clause that specifies remedies and damages does not feel like a threat to bankrupt me or ruin my life.&lt;/li&gt;
&lt;li&gt;There are no restrictive clauses on my future work.&lt;/li&gt;
&lt;li&gt;There are no restrictive clauses on me hiring, or being hired by people who work at the company.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all these check out, I will &lt;em&gt;consider&lt;/em&gt; signing the NDA. Otherwise, it's going to be a "thanks, but no thanks."&lt;/p&gt;

&lt;h3&gt;
  
  
  Others who also oppose NDAs
&lt;/h3&gt;

&lt;p&gt;As I mentioned before, many other people share this opinion that most NDAs are unnecessary, unfair, and even dangerous. Here are a few of them, in no particular order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.joelonsoftware.com/2000/03/28/ndas-and-contracts-that-you-should-never-sign/"&gt;NDAs and Contracts That You Should Never Sign&lt;/a&gt; by Joel Spolsky&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.huffpost.com/entry/ndas-are-stupid-mostly_b_5234108"&gt;NDAs Are Stupid (Mostly)&lt;/a&gt; by Matt Douglas&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cinematlmagazine.com/stories/2014/8/12/no-i-wont-sign-your-nda-why-non-disclosure-agreements-are-usually-mostly-useless-bunk"&gt;No I Won't Sign Your NDA: Why Non-Disclosure Agreements Are (Usually, Mostly) Useless Bunk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://insights.dice.com/2013/01/29/dont-sign-that-nda-until-you-read-this/"&gt;Don’t Sign That NDA Until You Read This&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.markwelchblog.com/2009/08/26/why-i-dont-sign-ndas/"&gt;Why I Don’t Sign NDAs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.masonpelt.com/why-i-dont-sign-ndas-mostly/"&gt;Why I Don’t Sign NDAs, Mostly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How about you? Do you sign NDAs? What do you think about them? Leave your thoughts and comments below.&lt;/p&gt;

</description>
      <category>career</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Invalid HTTP_HOST header errors in Django and Nginx</title>
      <dc:creator>Raúl Pedro Fernandes Santos</dc:creator>
      <pubDate>Wed, 19 Aug 2020 00:38:17 +0000</pubDate>
      <link>https://dev.to/borfast/invalid-httphost-header-errors-in-django-and-nginx-j1a</link>
      <guid>https://dev.to/borfast/invalid-httphost-header-errors-in-django-and-nginx-j1a</guid>
      <description>&lt;p&gt;Do you have a Django application running behind Nginx and getting lots of &lt;code&gt;Invalid HTTP_HOST header&lt;/code&gt; errors, even though you already configured &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; correctly?&lt;/p&gt;

&lt;p&gt;It's a fairly common problem but it's also simple to fix.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TL;DR&lt;/em&gt;: remove the &lt;code&gt;default_server&lt;/code&gt; option from your &lt;code&gt;server&lt;/code&gt; configuration block so that Nginx doesn't reply to all HTTP requests for any Host header, and place a new &lt;code&gt;server&lt;/code&gt; block with &lt;code&gt;default_server&lt;/code&gt; returning a &lt;a href="https://httpstatuses.com/444"&gt;&lt;code&gt;444&lt;/code&gt;&lt;/a&gt; status (or, if you're not using Nginx, a &lt;a href="https://httpstatuses.com/422"&gt;&lt;code&gt;422&lt;/code&gt;&lt;/a&gt; status).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does it happen?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: my explanation assumes you already configured &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; correctly. If you haven't, &lt;a href="https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-ALLOWED_HOSTS"&gt;do it&lt;/a&gt; and then check back here to make sure you're doing the Nginx part correctly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To put it simply, Nginx is proxying to your Django application requests that should be either denied (or maybe proxied elsewhere, if, for example, you have multiple backends).&lt;/p&gt;

&lt;p&gt;Many people tend to think this is a problem in their Django application, maybe because Django has an &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; setting that determines for which domain names it should accept requests, but in reality, it is most likely due to a misconfiguration of the Nginx &lt;code&gt;server&lt;/code&gt; block that proxies requests to your Django backend.&lt;/p&gt;

&lt;h4&gt;
  
  
  Some background
&lt;/h4&gt;

&lt;p&gt;Computers communicate on the internet via IP addresses, not domain names. When a piece of software in a computer tries to communicate with another computer via a domain name, like your browser trying to open a website for you, it first needs to translate the domain name to an IP address. This is what the Domain Name System, or DNS, does. For example, if you point your browser to &lt;a href="http://www.borfast.com"&gt;www.borfast.com&lt;/a&gt;, it will first ask the DNS what IP address is serving that domain name, will get back a response like 151.101.1.195, and then it will be able to communicate with that IP address.&lt;/p&gt;

&lt;p&gt;Very old HTTP servers could only serve a single domain from each IP address. In other words, there was a one-to-one match between domain names and IP addresses. Obviously, this wouldn't scale well, as it would require a separate network interface for each domain, drastically increasing the cost of hosting multiple sites, as well as other problems. To overcome this, a way to serve multiple domains from the same IP address was devised: &lt;a href="https://en.wikipedia.org/wiki/Virtual_hosting#Name-based"&gt;name-based virtual hosts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Multiple domains could now be served from a single IP address but the server would need to be explicitly told which domain was being requested. This required HTTP clients, like browsers, to specify exactly which domain name they were trying to reach and thus, the &lt;code&gt;Host&lt;/code&gt; HTTP header was born.&lt;/p&gt;

&lt;p&gt;Using this header, which became required in HTTP/1.1, the HTTP client would still communicate via the IP address but would also send that extra bit of information with the request, so that the server knew which domain to serve.&lt;/p&gt;

&lt;h4&gt;
  
  
  "What does this have to do with the error I'm seeing?"
&lt;/h4&gt;

&lt;p&gt;Glad you asked!&lt;/p&gt;

&lt;p&gt;This is the part that may be confusing for some people: your server may get HTTP requests that are not meant for your domain name because the header is set by the client and can be set to whatever the client wants.&lt;/p&gt;

&lt;p&gt;The simplest explanation is that someone is testing your server or application to see if they can gain unauthorized access or cause some other issues, so they send HTTP requests with specially crafted &lt;code&gt;Host&lt;/code&gt; headers to see what they can do. This is a very deep topic, so I won't get much into it but &lt;a href="https://duckduckgo.com/?q=host+header+attack"&gt;keep in mind it could be a problem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another possible explanation is that somehow, someone got a wrong or stale DNS response for a domain and now is trying to reach that domain via your server's IP address, when that domain is actually hosted elsewhere, on another server, with another IP address.&lt;/p&gt;

&lt;h4&gt;
  
  
  "OK, but I configured Django's &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; to only serve my domain; why is it still causing problems?"
&lt;/h4&gt;

&lt;p&gt;Going back to what was said above, this is not a problem with Django but Nginx.&lt;/p&gt;

&lt;p&gt;Your Nginx configuration probably looks like this or its equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream django_app {
    server unix:///path/to/yoursite/uwsgi.sock;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name yourdomain.com;
    ...

    location / {
        uwsgi_pass  django_app;
        include     /path/to/yoursite/uwsgi_params;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many ways to proxy requests from Nginx to Django and this is just one of them. Yours will probably look different, hopefully with HTTPS thrown into the mix, but the key part is the &lt;code&gt;default_server&lt;/code&gt; bit. If you don't have the &lt;code&gt;default_server&lt;/code&gt; option, then the &lt;code&gt;server&lt;/code&gt; block is probably the only one (or at least the first one) in your Nginx configuration, and Nginx considers it the default.&lt;/p&gt;

&lt;p&gt;When Nginx receives a request, it has to determine which &lt;code&gt;server&lt;/code&gt; block to use to &lt;a href="https://nginx.org/en/docs/http/request_processing.html"&gt;process the request&lt;/a&gt;. It uses the &lt;code&gt;Host&lt;/code&gt; header for this and it tries to match it with the &lt;code&gt;server_name&lt;/code&gt; option. If the &lt;code&gt;Host&lt;/code&gt; header does not match any &lt;code&gt;server_name&lt;/code&gt;, or if the header isn't present in the request, nginx will use the default server to process the request.&lt;/p&gt;

&lt;p&gt;This means that any request without a &lt;code&gt;Host&lt;/code&gt; header or with a header that doesn't match the &lt;code&gt;server_name&lt;/code&gt; will be served by this default &lt;code&gt;server&lt;/code&gt; block and proxied to the Django backend (in this case, via the uWSGI socket declared in the &lt;code&gt;upstream django_app&lt;/code&gt; block).&lt;/p&gt;

&lt;p&gt;The header is then passed from Nginx to Django and Django checks it againts the &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; setting. When it's not there, Django throws the &lt;code&gt;Invalid HTTP_HOST header&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;By the way, I imagine this may also be a problem with name-based virtual hosts in Apache, though I never faced this problem with Apache nor have I ever had to fix it, so I don't know for sure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you actually fix it?
&lt;/h2&gt;

&lt;p&gt;Since a lot of people tend to look at the problem from a Django-based perspective, they also try to fix the problem there, sometimes doing things that can even be dangerous, like suppressing Django's security warnings or setting &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; to accept any host or domain name.&lt;/p&gt;

&lt;p&gt;Unless you know very well what you are doing, you should absolutely &lt;strong&gt;not&lt;/strong&gt; do either of these things. Warnings in logs are telling you that something is wrong. Suppressing them is rarely a good idea. For example, if someone is trying to hack your server using a host header attack, you may not know about it until it's too late, and you may not have any information for a forensics investigation. The &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; setting in Django ensures that if the value of the Host header doesn't match what you're expecting, Django will not process it, so this should also be set appropriately.&lt;/p&gt;

&lt;p&gt;As explained above, your problem is actually the Nginx default server proxying requests to Django that should not be allowed through, so what you need to fix is Nginx's configuration.&lt;/p&gt;

&lt;p&gt;Taking the example configuration from before, fixing it is quite simple and has actually been &lt;a href="https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/#environment-specific-settings"&gt;documented in Django's docs&lt;/a&gt; for quite some time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream django_app {
    server unix:///path/to/yoursite/uwsgi.sock;
}

server {
    listen 80; // &amp;lt;--- Remove the default_server
    listen [::]:80; // &amp;lt;--- Remove the default_server
    server_name yourdomain.com;
    ...

    location / {
        uwsgi_pass  django_app;
        include     /path/to/yoursite/uwsgi_params;
    }
}

// Add this server block
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    return 444;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have now declared a default server that does nothing and should catch any requests that are not meant for your domain.&lt;/p&gt;

&lt;p&gt;Instead of declaring a "catch all" default server, some people prefer to explicitly match the desired domain inside the server block and only serve the requests meant for that specific domain. Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream django_app {
    server unix:///path/to/yoursite/uwsgi.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;
    ...

    if ($host !~* ^(yourdomain.com)$ ) {
        return 444;
    }

    location / {
        uwsgi_pass  django_app;
        include     /path/to/yoursite/uwsgi_params;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach means more configuration text in each server block but if you don’t want to be dependent on a single default server for some reason, it's a better alternative.&lt;/p&gt;

&lt;p&gt;In either case, you're all done! You should now stop seeing those pesky errors in your logs and/or emails.&lt;/p&gt;

</description>
      <category>django</category>
      <category>devops</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
