<?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: Brandon Bayer</title>
    <description>The latest articles on DEV Community by Brandon Bayer (@flybayer).</description>
    <link>https://dev.to/flybayer</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%2F348030%2Feb660919-3cf4-40e6-930f-5eeae0fda24f.jpeg</url>
      <title>DEV Community: Brandon Bayer</title>
      <link>https://dev.to/flybayer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flybayer"/>
    <language>en</language>
    <item>
      <title>9 ways to improve how you ship software</title>
      <dc:creator>Brandon Bayer</dc:creator>
      <pubDate>Tue, 16 Jan 2024 23:58:12 +0000</pubDate>
      <link>https://dev.to/flybayer/9-ways-to-improve-how-you-ship-software-1pb9</link>
      <guid>https://dev.to/flybayer/9-ways-to-improve-how-you-ship-software-1pb9</guid>
      <description>&lt;p&gt;10x developers are real, and there’s more than one way to be a 10x developer. &lt;/p&gt;

&lt;p&gt;Perhaps the most approachable is to make 10 other people 10% more productive.&lt;/p&gt;

&lt;p&gt;In this article, I cover things to improve your individual and team productivity. This is valuable to your company, so it will likely help level up your career.&lt;/p&gt;

&lt;p&gt;First, we’ll cover 7 principles and then 9 tactics.&lt;/p&gt;

&lt;h2&gt;
  
  
  7 principles for shipping software
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Speed
&lt;/h3&gt;

&lt;p&gt;Let’s face it. As developers, we are speed junkies. If we find a tool that’s 10 ms faster, we’re inclined to immediately rewrite our entire application. &lt;/p&gt;

&lt;p&gt;But when it comes to how often we deploy our code, we tend to be much more cautious. We’d rather deploy tomorrow or next week, so we don’t have to stay late today to fix whatever problems might happen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T8oJszIp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1ni0flrjnj0h11veq29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T8oJszIp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1ni0flrjnj0h11veq29.png" alt="Image description" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like Charity says, it is a deep seated biological impulse to slow down when we feel cautious. For humans, slow is safety.&lt;/p&gt;

&lt;p&gt;But software physics is different. It's more like riding a bicycle. The slower you go, the more dangerously you wobble.&lt;/p&gt;

&lt;h4&gt;
  
  
  Speed is safety. Small is speed.
&lt;/h4&gt;

&lt;p&gt;When it comes to deploys &lt;strong&gt;speed is safety, and small is speed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The speed of shipping has massive compounding effects. If your deploy takes hours, you’re going to want to make damn sure there are no bugs, because if you find a critical bug right after a deploy goes live, then you have to wait another couple hours for your fix to go live. &lt;/p&gt;

&lt;p&gt;We must aim for speed in every part of the software lifecycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast feedback loops&lt;/li&gt;
&lt;li&gt;Fast builds&lt;/li&gt;
&lt;li&gt;Fast tests&lt;/li&gt;
&lt;li&gt;Fast deploys&lt;/li&gt;
&lt;li&gt;Fast fixes&lt;/li&gt;
&lt;li&gt;Fast rollbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Reliability
&lt;/h3&gt;

&lt;p&gt;The second principle is reliability. Our systems must be dependable. &lt;/p&gt;

&lt;p&gt;Flaky CI/CD issues have to be one of the worst possible things in the universe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HGsgfVLQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anu918gftlcr5rqnp7e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HGsgfVLQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anu918gftlcr5rqnp7e6.png" alt="Image description" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We must avoid flakiness at all costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Reproducibility
&lt;/h3&gt;

&lt;p&gt;In order to build and maintain complex systems, we need to know that if we do X, we get Y every time. If one time you do X, you get Y, but another time you get Z, you will lose confidence in your systems.&lt;/p&gt;

&lt;p&gt;Basically, we want to use scripts and code to control everything we do instead of manual clicking, manual commands, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Calm on-call rotations
&lt;/h3&gt;

&lt;p&gt;Somewhat self-explanatory, no one wants to dread on-call rotations. If they are hectic, it will degrade morale and cause all sorts of issues. So it’s something we should explicitly prioritize. It can serve as a backstop of sorts to make sure what we’re doing is truly working well.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Easy to debug
&lt;/h3&gt;

&lt;p&gt;Everyone causes bugs. Even seniors. Even when you have tests. Even when you have 100% test coverage. You will ship bugs to production.&lt;/p&gt;

&lt;p&gt;So you must be prepared to fix production bugs. This is an area where speed is important. And as part of that, it must be easy to debug.&lt;/p&gt;

&lt;p&gt;If it’s hard to debug and slow to deploy fixes, it’s going to slow you down because you are going to add lengthy QA processes, and before you know it, you’ll be deploying code only once every few weeks. &lt;/p&gt;

&lt;p&gt;But even with lots of QA, you’ll still have production bugs. &lt;br&gt;
Production is the only tried-and-true way to find all the bugs.&lt;/p&gt;

&lt;p&gt;Our systems must be easy to debug.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Self-serve infrastructure and deployments
&lt;/h3&gt;

&lt;p&gt;In the old way of doing infrastructure and code deployments you had two separate teams. Devs and Ops. If devs needed a new database, they filed a ticket with ops. If they need a new service, file a ticket with ops. Need to deploy your code? File a ticket with ops.&lt;/p&gt;

&lt;p&gt;Naturally, this has several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Devs are often blocked, waiting on ops to get to some ticket.&lt;/li&gt;
&lt;li&gt;Devs aren’t monitoring infrastructure, and likely won’t get feedback on whether their code is fast or slow, efficient or inefficient.&lt;/li&gt;
&lt;li&gt;The whole organization is slowed down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We, as an industry, figured out it’s much better for devs to deploy and run their own code. This is more efficient, with fewer blockages and less communication overhead, and devs get more feedback from the real world on how their code is performing.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Ship on Fridays
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wAMsTeef--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc0493nwokwt1b7rwae7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wAMsTeef--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc0493nwokwt1b7rwae7.jpg" alt="Image description" width="620" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Healthy engineering organizations deploy multiple times per day, including on Friday!&lt;/p&gt;

&lt;p&gt;If you are afraid to deploy on Friday, it’s likely from one or more of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t have reliable deploys.&lt;/li&gt;
&lt;li&gt;You have slow deploys.&lt;/li&gt;
&lt;li&gt;You don’t have good monitoring and alerting.&lt;/li&gt;
&lt;li&gt;Your app is hard to debug.&lt;/li&gt;
&lt;li&gt;You don’t have tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are all things you must fix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--StXhFkE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zipetdewfweobj9ur22i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--StXhFkE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zipetdewfweobj9ur22i.png" alt="Image description" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9 tactics to improve how you ship software
&lt;/h2&gt;

&lt;p&gt;With the above principles in place, let’s look at 9 specific tactics to implement them in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Decouple deploys from releases
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Deploying software is a terrible, horrible, no good, very bad way to go about the process of changing user-facing code. \&lt;br&gt;
—&lt;a href="https://www.honeycomb.io/blog/deploys-wrong-way-change-user-experience"&gt;Charity Majors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fundamentally, there are two possible actions for changing code in production: deploys and releases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Releasing&lt;/em&gt; refers to the process of changing the user experience in a meaningful way. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deploying&lt;/em&gt; refers to the process of building, testing, and rolling out changes to your production software. &lt;/p&gt;

&lt;p&gt;The traditional process is that you change the code on a branch, and when it’s ready, you merge and deploy it. Once it’s deployed, users will see the new code.&lt;/p&gt;

&lt;p&gt;But today’s modern engineering organizations use feature flags. &lt;/p&gt;

&lt;p&gt;What is a feature flag?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DKNPXY7N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dtogzpmcses9gnefpdhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DKNPXY7N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dtogzpmcses9gnefpdhk.png" alt="Image description" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It allows you to write new code alongside the old code, and then, based on a runtime feature flag, your app decides whether to run the old or new code.&lt;/p&gt;

&lt;p&gt;This is huge! Remember how speed is one of the key principles? Separating deploys from releases speeds up both. It speeds up deploys because engineers can deploy their code as soon as it’s ready without waiting for product management to be ready to release it. And it speeds up releases because now you can release a feature instantly. And rollback a feature instantly. Without needing a deploy. Product managers can do releases on their own schedule.&lt;/p&gt;

&lt;p&gt;Furthermore, it unlocks advanced methods like progressive rollout, where you enable the feature flag for a percentage of your users. You could start out with 5% of users. If everything is working, then increase to 10%, 20%, etc. This is the best way to roll out changes at scale because if there are problems, only a subset of your users will experience them instead of all.&lt;/p&gt;

&lt;p&gt;And feature flags are superior to long-lived feature branches for development flow. You have fewer merge conflicts, less stale code, more team momentum, better team morale, and more flexibility for testing things with real users.&lt;/p&gt;

&lt;p&gt;I encourage you to introduce this idea at work. And next time someone has a long-lived feature branch instead of a feature flag, use this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WVQ_Q203--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ido3r0pc63pt62oxape.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WVQ_Q203--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ido3r0pc63pt62oxape.jpg" alt="Image description" width="599" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Continuous deployment (CD)
&lt;/h3&gt;

&lt;p&gt;Deployments are the heartbeat of your engineering organization. And like a human heart, you want a steady rhythm of simple heartbeats. And with this steady rhythm of deployments, you get momentum. And momentum is life for organizations.&lt;/p&gt;

&lt;p&gt;Along with momentum, you get efficiency, being able to deliver code to production as quickly as possible after it’s written.&lt;/p&gt;

&lt;p&gt;You want to deploy as often as possible, like multiple times per day. Every commit should be deployed. Small, understandable changes mean you have debuggable and understandable deploys. The engineer who writes the code should merge their own PR and then monitor production for any unexpected issues.&lt;/p&gt;

&lt;p&gt;Feature flags are basically a prerequisite for this because they allow your team to ship small changes continuously instead of having long-lived feature branches. &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Set up alerts
&lt;/h3&gt;

&lt;p&gt;Make sure you set up alert notifications for the following anomalies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Failed builds&lt;/li&gt;
&lt;li&gt;Failed deploys&lt;/li&gt;
&lt;li&gt;Service downtime&lt;/li&gt;
&lt;li&gt;Unhealthy servers &lt;/li&gt;
&lt;li&gt;Unexpected errors&lt;/li&gt;
&lt;li&gt;Unusual amount of traffic&lt;/li&gt;
&lt;li&gt;Statuses of third-party services (many have a status page that you can subscribe to in Slack)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benefit is relatively obvious, but it does take at least a bit of effort to set them up, so this is something many teams can do as a quick win.&lt;/p&gt;

&lt;p&gt;And if you already have alerts, you should audit them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are they useful? &lt;/li&gt;
&lt;li&gt;Are you getting too many false alerts so that you ignore them?&lt;/li&gt;
&lt;li&gt;Are there things you should add new alerts for?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Optimize deploy speed — 15 minutes or bust
&lt;/h3&gt;

&lt;p&gt;Your target for a happy team is 15 minute deploys or less.&lt;br&gt;
Of course, we want them to be as fast as possible, but the neighborhood of 15 minutes is the baseline target. Significantly longer than this is significantly painful. But significantly faster than this could take more work than it’s worth, depending on your circumstances.&lt;/p&gt;

&lt;p&gt;There are a number of ways to improve your speed of deploys.&lt;/p&gt;

&lt;h4&gt;
  
  
  a. Track and measure your current deploy times
&lt;/h4&gt;

&lt;p&gt;You want to understand your starting point and which parts of the process are taking a long time. That’s where you want to focus initially.&lt;/p&gt;

&lt;h4&gt;
  
  
  b. Speed up dependency installation
&lt;/h4&gt;

&lt;p&gt;Dependency installation is often time consuming, so it can be a good first step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switch to a faster package manager.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If using javascript, switch to pnpm. It’s a drop-in replacement for npm and yarn that has significant performance and caching improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache the entire install step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use your build system to cache this entire step, so this step doesn’t even run if your dependencies haven’t changed.&lt;/p&gt;

&lt;p&gt;Example with Docker:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gyyHksJQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fansmfpbo7wmc85sp6u3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gyyHksJQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fansmfpbo7wmc85sp6u3.png" alt="Image description" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example with &lt;a href="https://nixpacks.com"&gt;Nixpacks&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CfodACJL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33kzuvz53it4uw7x1rnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CfodACJL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33kzuvz53it4uw7x1rnx.png" alt="Image description" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  c. Improve your build speed
&lt;/h4&gt;

&lt;p&gt;The main way to improve your build speed is to switch to a faster bundler. &lt;/p&gt;

&lt;p&gt;For example if you are using create-react-app which uses webpack, you can &lt;strong&gt;switch to Vite&lt;/strong&gt; which is way faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If using Next.js&lt;/strong&gt;, upgrade to the latest and make sure you don’t have a &lt;code&gt;.babelrc&lt;/code&gt; file; this will use SWC instead of babel which is a lot faster.&lt;/p&gt;

&lt;p&gt;If you like living on the edge, you can try Turbopack by passing the &lt;code&gt;--turbo&lt;/code&gt; flag to the &lt;code&gt;next&lt;/code&gt; commands, but it’s still experimental and doesn’t work for all setups.&lt;/p&gt;

&lt;h4&gt;
  
  
  d. Set up build caching
&lt;/h4&gt;

&lt;p&gt;If you are using Docker, there are several ways to improve caching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize your build layers.&lt;/li&gt;
&lt;li&gt;Use multi-stage builds.&lt;/li&gt;
&lt;li&gt;Set up remote caching.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When building locally, Docker caches by default and is fast, but in CI you usually don't have a permanent machine. You have to manually set up remote caching. Refer to &lt;a href="https://docs.docker.com/build/cache/"&gt;the Docker documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h4&gt;
  
  
  e. Globally cache everything
&lt;/h4&gt;

&lt;p&gt;If you want to really live with your hair on fire, in a good or maybe bad way, there is another style of caching that can give you big wins, as long as you have a javascript project.&lt;/p&gt;

&lt;p&gt;This caching style works by having a single shared cache between your entire team &lt;strong&gt;and&lt;/strong&gt; also CI.&lt;/p&gt;

&lt;p&gt;This means if you build a commit locally and then push that commit to CI, the CI build will download the previous cached build from your local machine and be done in mere seconds. Or if someone else on your team already built a commit, and then you run the build locally, it will again download the cache and be done in mere seconds instead of building from scratch again.&lt;/p&gt;

&lt;p&gt;You might be thinking, “ok Brandon that’s cool and all, but usually we’re changing code so it won’t be cached”. But the trick is that this caching works on a &lt;strong&gt;package&lt;/strong&gt; level, so assuming you have a monorepo, you are likely only working in one package at a time. So this enables you to iterate faster and not have to build things you aren’t working on.&lt;/p&gt;

&lt;p&gt;There are two tools that do this: &lt;a href="https://nx.dev/"&gt;NX&lt;/a&gt; and &lt;a href="https://turbo.build/repo"&gt;Turborepo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is a gotcha. You must be careful with how you handle environment variables. I’ve seen numerous people have production issues because a dev ran the production build locally but with dev or staging environment variables. And then CI uses the cached build with incorrect environment variables. Make sure you set up different commands for dev, staging, and production.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Replace staging with preview environments
&lt;/h3&gt;

&lt;p&gt;Preview environments are temporary environments, tied to the lifecycle of a pull request. When you open a pull request, infrastructure can be automatically provisioned for that PR. &lt;/p&gt;

&lt;p&gt;This enables stakeholders to see the changes in a production-like environment before it’s merged. And then, when the pull request is merged or closed, its environment will be automatically cleaned up.&lt;/p&gt;

&lt;p&gt;Preview environments are a better replacement for long-lived staging environments. Because staging is running all the time, whether it needs to or not. And you have to merge a PR before anyone can verify the change.&lt;/p&gt;

&lt;p&gt;Preview environments are a companion to feature flags. Larger changes should use feature flags and will have many PRs for that feature. But small changes are easier to review in a preview environment instead of going through the hassle of managing a feature flag for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Infrastructure-as-code
&lt;/h3&gt;

&lt;p&gt;Hopefully, you have automated deployments, but you might not have automated infrastructure. Without infrastructure-as-code (IaC), you typically define your infrastructure config by clicking through a dashboard. &lt;/p&gt;

&lt;p&gt;Bringing automation to your infrastructure config in the form of infrastructure-as-code has a huge number of benefits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeatability or reproducibility&lt;/li&gt;
&lt;li&gt;Consistency and standardization&lt;/li&gt;
&lt;li&gt;Predictability&lt;/li&gt;
&lt;li&gt;Version controlled&lt;/li&gt;
&lt;li&gt;Collaboration and review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IaC can take many forms. If using AWS, it can be low level like CloudFormation or Terraform. Or it can be at a higher level of abstraction, designed for product developers. Examples are Flightcontrol’s &lt;code&gt;flightcontrol.json&lt;/code&gt; or Render’s &lt;code&gt;render.yaml&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  7. Platform Engineering
&lt;/h3&gt;

&lt;p&gt;Platform engineering might be a new term for you, so let me give you the back story that got us to this point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ylRTFST6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3svukz14kj3rgzlkuibg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ylRTFST6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3svukz14kj3rgzlkuibg.png" alt="Image description" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back in the old days, you had to rack your own servers in a data center. The abstraction level of infrastructure was extremely low. Then came AWS which introduced the cloud and raised the abstraction level. But it was still too low for the average developer.&lt;/p&gt;

&lt;p&gt;This led to the creation of Heroku, to the glee of developers all around the world. But that excitement was not to last because ops were not happy. It turns out abstractions like Heroku do not scale for large companies. So ops take over and create a new abstraction over AWS, infrastructure as code and Terraform. This works well, but it’s still too tedious for developers.&lt;/p&gt;

&lt;p&gt;Additionally, company leadership wants to increase operational efficiency, and one way to do that is to provide devs with self-serve infrastructure, so we, as an industry, started creating internal platforms that provide a better developer experience. Through this, we found a way for both ops and devs to be mostly happy. This has come to be known as platform engineering.&lt;/p&gt;

&lt;p&gt;Now many larger companies are building an internal platform, sometimes known as an internal developer platform. This platform can look more like an internal Heroku or more like plain Terraform.&lt;/p&gt;

&lt;p&gt;Either way, the three key concepts are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploys to your own AWS/GCP account&lt;/li&gt;
&lt;li&gt;Self-serve infrastructure with good developer experience&lt;/li&gt;
&lt;li&gt;Ops can dictate and customize the underlying primitives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are &lt;a href="https://platformengineering.org/platform-tooling"&gt;many tools&lt;/a&gt; in the space, one of which is &lt;a href="https://www.flightcontrol.dev/"&gt;Flightcontrol&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Work as a team
&lt;/h3&gt;

&lt;p&gt;Back in the beginning of Flightcontrol, it was only my cofounder and me. We had a clear separation of duties aligned with our skillsets. He did all the backend/infra stuff, and I did all the web app and frontend things. It worked great!&lt;/p&gt;

&lt;p&gt;But then we started hiring more engineers. We initially kept the same work model where each person was off working on their own project or feature.&lt;/p&gt;

&lt;p&gt;It started to feel like something wasn’t right.&lt;/p&gt;

&lt;p&gt;We weren’t benefiting from collaboration. Since each person was working mostly alone, we weren’t benefiting from others’ expertise on everything from architecture design to code quality. &lt;/p&gt;

&lt;p&gt;We would review each other’s code, but since no one else had the full context of the project, they were only able to give superficial reviews. LGTM!&lt;/p&gt;

&lt;p&gt;Then, somewhere during this time, I ran across a &lt;a href="https://swizec.com/blog/reader-question-so-about-that-perfect-burndown-chart/"&gt;few&lt;/a&gt; &lt;a href="https://swizec.com/blog/reader-question-what-do-collaborative-teams-look-like/"&gt;blog&lt;/a&gt; &lt;a href="https://swizec.com/blog/scaling-teams-is-a-technical-challenge/"&gt;posts&lt;/a&gt; by Swizec Teller, talking about how most teams don’t actually work as a team, and if you actually work as a team, you can be way more effective. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we first started working as a team instead of a group of soloists, every story felt like a million gerbils running through my brain.&lt;br&gt;
We moved faster. We got more done. We kept everyone in the loop. Shared more ideas. Found more edge cases. Created fewer bugs. And heard more opinions.&lt;/p&gt;

&lt;p&gt;—Swizec&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I read this, and my heart was saying, YES YES, but my mind was saying, I don’t understand!&lt;/p&gt;

&lt;p&gt;As a team, we decided to fundamentally shift how we worked. We’d no longer have multiple projects in progress at the same time. Instead, we’d have one project, and the entire team would work on it together from start to finish.&lt;/p&gt;

&lt;p&gt;Initially, it was scary, awkward, and felt like it wouldn’t work smoothly. And it was rough for a couple months until we got things ironed out. But now it’s many months later, and we can’t imagine working any other way.&lt;/p&gt;

&lt;p&gt;We can emphatically say that teams should work as a team. Everything has improved. We ship better features, have fewer bugs, and cover more edge cases. Job satisfaction and team morale increased. Because now they get true collaboration, not a “hi” as you pass them in the slack channel.&lt;/p&gt;

&lt;p&gt;How does this work?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small team (2-6 people, 4 is ideal)&lt;/li&gt;
&lt;li&gt;Entire team works on 1 project at a time, together.&lt;/li&gt;
&lt;li&gt;Kickoff meeting (deep discussions on how to build)&lt;/li&gt;
&lt;li&gt;Break project into small tasks (usually in kickoff)&lt;/li&gt;
&lt;li&gt;Work on subtasks in parallel.&lt;/li&gt;
&lt;li&gt;Small PRs, at least 1 per day.&lt;/li&gt;
&lt;li&gt;Quick reviews. I.e. don’t be a blocker.&lt;/li&gt;
&lt;li&gt;Unblock yourself; merge your own safe PR if no one is available to review and you are blocked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. Trunk based development
&lt;/h3&gt;

&lt;p&gt;The next level of team productivity is to get rid of pull requests and commit straight to the main branch.&lt;/p&gt;

&lt;p&gt;I’m serious.&lt;/p&gt;

&lt;p&gt;It’s called trunk based development. If this is a new concept to you, I know you’re thinking this is impossible; there is no way this can work. Even if you’ve heard of this concept before, you are probably thinking, “I have no idea how this could work”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ofWU3BIC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkaz5z7nqfyv0xl9s9z4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ofWU3BIC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xkaz5z7nqfyv0xl9s9z4.png" alt="Image description" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of it like a cafeteria. Your tray is the main branch. When the burger is done, it goes on the tray. When the fries are ready, they go on the tray. When the milk shake is poured, it goes on the tray. Once the tray is full, you’re done.&lt;/p&gt;

&lt;p&gt;That's how trunk-based development works. Every feature goes straight to main when it's ready. Whether subtasks or an entire project, it doesn’t matter because they're all working, independent, and deployable.&lt;/p&gt;

&lt;p&gt;If committing straight to main is too radical for you, then do the next best thing, which is short-lived branches.&lt;/p&gt;

&lt;p&gt;And by short-lived branches, I mean, &lt;strong&gt;short&lt;/strong&gt; lived branches. &lt;/p&gt;

&lt;p&gt;You want to be as close as possible to pure trunk-based development as possible.&lt;/p&gt;

&lt;p&gt;PRs shouldn’t last more than about a day. For a project, you should have many short PRs that are quick for others to review and easy to merge. &lt;/p&gt;

&lt;p&gt;That’s how you get momentum.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We’ve covered seven principles and ten tactics for improving how you ship software. &lt;/p&gt;

&lt;p&gt;What do you think of these? Have things to add or take away?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>programming</category>
      <category>engineering</category>
    </item>
    <item>
      <title>🎉 Announcing Blitz.js: Rails-like framework for full-stack React apps — built on Next.js</title>
      <dc:creator>Brandon Bayer</dc:creator>
      <pubDate>Fri, 24 Apr 2020 15:23:30 +0000</pubDate>
      <link>https://dev.to/flybayer/announcing-blitz-js-rails-like-framework-for-full-stack-react-apps-built-on-next-js-g1o</link>
      <guid>https://dev.to/flybayer/announcing-blitz-js-rails-like-framework-for-full-stack-react-apps-built-on-next-js-g1o</guid>
      <description>&lt;p&gt;Today we're announcing the &lt;a href="https://github.com/blitz-js/blitz"&gt;first alpha release of Blitz.js&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Blitz is a Rails-like framework for monolithic, full-stack React apps.&lt;/p&gt;

&lt;p&gt;Blitz brings back the &lt;strong&gt;simplicity and conventions&lt;/strong&gt; of server-rendered frameworks like Ruby on Rails while preserving everything we love about React and client-side rendering!&lt;/p&gt;

&lt;p&gt;Blitz is the framework for the 99% of us at companies with &amp;lt;100 employees. This means &lt;strong&gt;we don't force you to use advanced technologies like GraphQL&lt;/strong&gt;. We let you add advanced technologies on your terms and at your pace.&lt;/p&gt;

&lt;p&gt;Blitz &lt;strong&gt;maximizes your productivity&lt;/strong&gt; both when starting an app and when scaling it to lots of code and users.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;p&gt;⚡️ Built on Next.js&lt;br&gt;
⚡️ Don't have to build an API for client-side rendering&lt;br&gt;
⚡️ Client-side rendering, Server-side rendering, and fully static pages all in the same app&lt;br&gt;
⚡️ Full Typescript support with static, end-to-end typing (no code generation step needed like with GraphQL)&lt;br&gt;
⚡️ React Concurrent Mode enabled&lt;br&gt;
⚡️ Database/ORM agnostic, but Prisma 2 is default&lt;br&gt;
⚡️ CLI with code scaffolding, Rails-style console REPL, etc&lt;br&gt;
⚡️ GraphQL Ready&lt;br&gt;
⚡️ Deploy serverless or serverful&lt;/p&gt;

&lt;h4&gt;
  
  
  Other key features coming:
&lt;/h4&gt;

&lt;p&gt;⚡️ Highly secure authentication&lt;br&gt;
⚡️ Authorization you can use on both server and client&lt;br&gt;
⚡️ Model validation you can use on both server and client&lt;br&gt;
⚡️ Plugins for easily adding libraries like Tailwind, CSS-in-JS, etc.&lt;br&gt;
⚡️ React native support&lt;br&gt;
⚡️ GUI so you don't have to use the CLI&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Blitz Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g blitz
blitz new myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/blitz-js/blitz/blob/canary/USER_GUIDE.md"&gt;Read the Alpha User Guide&lt;/a&gt; to learn more!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>framework</category>
    </item>
    <item>
      <title>The Blitz.js Manifesto (A New Fullstack React Framework)</title>
      <dc:creator>Brandon Bayer</dc:creator>
      <pubDate>Tue, 10 Mar 2020 11:12:21 +0000</pubDate>
      <link>https://dev.to/flybayer/the-blitz-js-manifesto-a-new-react-framework-1gg7</link>
      <guid>https://dev.to/flybayer/the-blitz-js-manifesto-a-new-react-framework-1gg7</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/blitz-js/blitz"&gt;Blitz.js&lt;/a&gt; is a new Javascript framework for building monolithic, full-stack, serverless React apps with zero data-fetching and zero client-side state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Technology follows a repeating cycle of bundling and unbundling. Created in 2005, Ruby on Rails became a major bundling force, making web application development easier and more accessible than ever before. This benefited everyone, from those learning programming to seniors building production systems.&lt;/p&gt;

&lt;p&gt;A major unbundling happened in 2013 with the release of React, a hyper focused rendering layer without any opinions for things like styling, state management, and routing. As React grew in popularity, so did the choices for all the other parts, leaving developers with hundreds of decisions to make when starting a new app. While this has contributed to JavaScript Fatigue, it's been a powerful driving force for rapid frontend innovation.&lt;/p&gt;

&lt;p&gt;Now, in 2020, is the perfect time for another major bundling. Developers are yearning for an easier, simpler way to build web applications. Beginners want a guiding hand for building a robust app, and seniors want a framework that removes mundane tasks while providing a highly scalable architecture with all the right escape hatches.&lt;/p&gt;

&lt;p&gt;Hence the creation of Blitz.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Blitz For?
&lt;/h2&gt;

&lt;p&gt;Blitz is for building tiny to large database-backed web applications (and in the future, mobile apps). It's not for building extremely large web apps, like Facebook.com. It's not for building content sites, although you can easily add fully static pages to a Blitz app so you don't need a separate host for your marketing site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foundational Principles
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fullstack &amp;amp; Monolithic&lt;/li&gt;
&lt;li&gt;Backend API Optional&lt;/li&gt;
&lt;li&gt;Convention over Configuration&lt;/li&gt;
&lt;li&gt;Loose Opinions&lt;/li&gt;
&lt;li&gt;Easy to Start, Easy to Scale&lt;/li&gt;
&lt;li&gt;Stability&lt;/li&gt;
&lt;li&gt;Community over Code&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Fullstack &amp;amp; Monolithic
&lt;/h3&gt;

&lt;p&gt;A fullstack, monolithic application is simpler than an application where frontend and backend are developed and deployed separately. Monolithic doesn't mean it will be slow or hard to scale to large teams. Monolithic doesn't mean there isn't separation of concerns. Monolithic means you can reason about your app as a single entity.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Backend API Optional
&lt;/h3&gt;

&lt;p&gt;Choosing React for your view layer should not force you to build a backend API. Usually you only need an API to get data to your frontend, unless you need a public API for third-parties or a mobile app. It's extremely expensive to build and maintain an API that's only used by your frontend because it adds a lot of unnecessary complexity, making development slower, maintenance harder, and deployment more complex.&lt;/p&gt;

&lt;p&gt;In a Blitz app, you write server-side controllers for all your CRUD operations. These controllers have direct access to your database. You connect them to the pages that need that data, and then Blitz automatically and securely gets your data from the backend controller to your frontend components. You don't make any client-side fetch calls, deal with global state management, or mess with client-side data caching. Mutations work in a similar fashion.&lt;/p&gt;

&lt;p&gt;You develop Blitz apps similar to a traditional server rendered framework like Rails, but the end-user experience is as a React Single Page App.&lt;/p&gt;

&lt;p&gt;If at some point you actually do need an API, you can easily add a GraphQL API with auto generated resolvers. Or if REST is your jam, you can add that to your Blitz app instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Convention over Configuration
&lt;/h3&gt;

&lt;p&gt;When starting a new app, you should be able to immediately start developing core app features instead of spending days to configure eslint, prettier, husky git hooks, jest, cypress, typescript, deciding on a file structure, setting up a database, adding authentication and authorization, setting up a router, defining routing conventions, setting up your styling library, and all the other menial tasks for initial app setup.&lt;/p&gt;

&lt;p&gt;Blitz will make as many decisions and do as much work for you as possible. This makes it lightning fast to start real development. It also greatly benefits the community. Common project structure and architectural patterns make it easy to move from Blitz app to Blitz app and immediately feel at home.&lt;/p&gt;

&lt;p&gt;Convention over configuration doesn't mean no configuration. It means configuration is optional. Blitz will provide all the escape hatches and configuration options you need for bespoke customization.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Loose Opinions
&lt;/h3&gt;

&lt;p&gt;Blitz is opinionated. The out-of-the-box experience guides you on a path perfect for most applications. However, Blitz isn't arrogant. It totally understands there are very good reasons for deviating from convention, and it allows you to do so easily. For example, Blitz has a conventional file structure, but, with few exceptions, doesn't &lt;em&gt;enforce&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;And when there's not consensus among the React community for a thing, &lt;code&gt;blitz new&lt;/code&gt; will prompt you to choose the approach you want, such as Tailwind CSS, Theme UI, or styled-components.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Easy to Start, Easy to Scale
&lt;/h3&gt;

&lt;p&gt;A framework that's only easy for one end of an application lifecycle is not a good framework. Both starting and scaling must be easy.&lt;/p&gt;

&lt;p&gt;Easy to start includes being easy for beginners and being easy to migrate existing Next.js apps to Blitz.&lt;/p&gt;

&lt;p&gt;Scaling is important in all forms: lines of code, number of people working in the codebase, and code execution in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Stability
&lt;/h3&gt;

&lt;p&gt;In the fast-paced world of Javascript, a stable, predictable release cycle is a breath of fresh air. A stable release cycle ensures minimal breaking changes and ensures you know exactly what and when a breaking change will occur. It also minimizes bugs in stable releases by ensuring features are in beta for a minimum amount of time. &lt;a href="https://emberjs.com/releases/"&gt;Ember is the model citizen&lt;/a&gt; in this regard.&lt;/p&gt;

&lt;p&gt;The exact details of the Blitz release cycle are to be determined, but we'll follow a pattern similar to Ember which strictly follows SemVer with stable releases every 6 weeks and LTS releases every 6 months.&lt;/p&gt;

&lt;p&gt;Blitz will follow a public RFC (request for comments) process so all users and companies can participate in proposing and evaluating new features.&lt;/p&gt;

&lt;p&gt;If a Blitz API needs to be removed, it will be deprecated in a minor release. Major releases will simply remove APIs already deprecated in a previous release.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Community over Code
&lt;/h3&gt;

&lt;p&gt;The Blitz community is the most important aspect of the framework, by far.&lt;br&gt;
We have a comprehensive &lt;a href="https://github.com/blitz-js/blitz/blob/canary/CODE_OF_CONDUCT.md"&gt;Code of Conduct&lt;/a&gt;. LGBTQ+, women, and minorities are especially welcome.&lt;/p&gt;

&lt;p&gt;We are all in this together, from the youngest to the oldest. We are all more similar than we are different. We can and should solve problems together. We should learn from other communities, not compete against them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now Accepting Sponsorships and Donations
&lt;/h2&gt;

&lt;p&gt;Funds will be used to replace my consulting revenue so I can work more on Blitz and get it production ready asap (probably late Q2). With sufficient funds, other contributors will be supported too!&lt;/p&gt;

&lt;p&gt;This is a great chance to get your business in front of early adopters!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sponsors/blitz-js"&gt;On Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://paypal.me/thebayers"&gt;On Paypal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opencollective.com/blitzjs"&gt;On Open Collective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://patreon.com/flybayer"&gt;On Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>serverless</category>
    </item>
  </channel>
</rss>
