<?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>Forem: Jakub Skoneczny</title>
    <description>The latest articles on Forem by Jakub Skoneczny (@skona27).</description>
    <link>https://forem.com/skona27</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%2F349119%2F1d42ff59-bccf-4041-8ec8-22e95ba6ec4d.jpeg</url>
      <title>Forem: Jakub Skoneczny</title>
      <link>https://forem.com/skona27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/skona27"/>
    <language>en</language>
    <item>
      <title>IsEven API - SaaS platform for checking if number is even 🚀</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Fri, 26 Nov 2021 18:21:39 +0000</pubDate>
      <link>https://forem.com/skona27/iseven-api-saas-platform-for-checking-if-number-is-even-498k</link>
      <guid>https://forem.com/skona27/iseven-api-saas-platform-for-checking-if-number-is-even-498k</guid>
      <description>&lt;p&gt;Have you ever heard about the SaaS platform for if a number is even? Well, I've decided to recreate a service like this of my own! 😄 &lt;/p&gt;

&lt;p&gt;Not for the profit, of course - who would need the paid service for checking the parity of a number? 😄 I wanted to create a full-stack project from start to end and then deploy it. It seemed like a great challenge that would require gathering all my knowledge, structuring it, and maybe even learning some new stuff along. So this idea of creating a non-real SaaS platform fascinated me!&lt;/p&gt;

&lt;p&gt;So this is it! I present to you my latest project - &lt;a href="https://is-even.eu" rel="noopener noreferrer"&gt;is-even.eu&lt;/a&gt;. It is open-source, so go ahead and check the &lt;a href="https://github.com/Skona27/is-even" rel="noopener noreferrer"&gt;codebase&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the project
&lt;/h2&gt;

&lt;p&gt;The main idea behind this SaaS platform is that a customer can purchase a plan (different plans allow different API usage). He can then perform an analysis of a number via a protected route. Users must use API Key to have access to that route. The application tracks the usage for each user, and if he reaches the limit, he can no longer use our services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core features are:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users can signup and login,&lt;/li&gt;
&lt;li&gt;User can place orders and fulfill them,&lt;/li&gt;
&lt;li&gt;User can create API Keys&lt;/li&gt;
&lt;li&gt;User can use the service within his credits limit&lt;/li&gt;
&lt;li&gt;User can monitor the usage of his credits&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical informations
&lt;/h2&gt;

&lt;p&gt;The project gathers some of the best practices of project development and maintenance. It shows how one can implement a working system from start to end, deploy it and monitor it. This project contains of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modern Frontend application written in &lt;code&gt;Next.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;robust Backend application written in &lt;code&gt;Nest.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;infrastructure as a code with &lt;code&gt;AWS CDK&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Typescript codebase for every application&lt;/li&gt;
&lt;li&gt;docker environment for local development&lt;/li&gt;
&lt;li&gt;monorepo manager to control all the and its dependencies&lt;/li&gt;
&lt;li&gt;CI/CD pipelines for running tests and deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend application is deployed on &lt;code&gt;Vercel&lt;/code&gt;, one of the first choices for deploying the &lt;code&gt;Next.js&lt;/code&gt; application. &lt;/p&gt;

&lt;p&gt;The backend application is deployed on &lt;code&gt;AWS ElasticBeanstalk&lt;/code&gt;. I've found this challenging to create an infrastructure setup with AWS CDK, but it was worth it! Infrastructure as a Code is fantastic because now I can set it up from the start in no time!&lt;/p&gt;

&lt;p&gt;This whole project is a template, ready to copy and use accordingly to your start-up idea! Feel free to fork it and adjust to your needs 😉&lt;/p&gt;

&lt;p&gt;I've decided to use some new modern technologies in this project. One of the essential mentions is &lt;code&gt;XState&lt;/code&gt; - a library that brings state machines to Javascript. I enjoy doing state management in &lt;code&gt;React&lt;/code&gt; with that library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other worth mentions are:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stripe&lt;/li&gt;
&lt;li&gt;ChakraUI&lt;/li&gt;
&lt;li&gt;Rush.js as monorepo manager&lt;/li&gt;
&lt;li&gt;Next.js as frontend framework&lt;/li&gt;
&lt;li&gt;Nest.js as backend framework&lt;/li&gt;
&lt;li&gt;Multiple AWS services like: Cognito, RDS, EBS, ELB etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For complete documentation and more information, please check out the &lt;a href="https://github.com/Skona27/is-even" rel="noopener noreferrer"&gt;official Github repository&lt;/a&gt; or special &lt;a href="https://is-even.eu/about-the-project" rel="noopener noreferrer"&gt;page about the project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I encourage you to have a look, examine the code, and write your thoughts. What do you think about this project? What's missing or what could have been done differently? &lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;If you have a suggestion to improve this project, please fork the repo and create a pull request. You can also open an issue with the tag enhancement. Any contributions are welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;If you wonder why I decided to go with monorepo, here are some good reasons that I've written in my previous article:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/skona27" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F349119%2F1d42ff59-bccf-4041-8ec8-22e95ba6ec4d.jpeg" alt="skona27"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/skona27/control-your-monorepo-2ka6" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Control your Monorepo 🗄️ &lt;/h2&gt;
      &lt;h3&gt;Jakub Skoneczny ・ Aug 4 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#architecture&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codequality&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Also, I've written a more hands-on tutorial for setting up the infrastructure with AWS CDK:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/skona27" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F349119%2F1d42ff59-bccf-4041-8ec8-22e95ba6ec4d.jpeg" alt="skona27"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/skona27/deploy-scalable-nodejs-application-with-postgres-database-using-aws-cdk-22l4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Deploy scalable NodeJS application with Postgres database using AWS CDK&lt;/h2&gt;
      &lt;h3&gt;Jakub Skoneczny ・ Jan 1 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>react</category>
      <category>webdev</category>
      <category>aws</category>
      <category>node</category>
    </item>
    <item>
      <title>Control your Monorepo 🗄️ </title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Wed, 04 Aug 2021 18:49:31 +0000</pubDate>
      <link>https://forem.com/skona27/control-your-monorepo-2ka6</link>
      <guid>https://forem.com/skona27/control-your-monorepo-2ka6</guid>
      <description>&lt;p&gt;You might have heard the phrase &lt;strong&gt;monorepo&lt;/strong&gt; earlier before. But, for those who haven't heard anything about it, monorepo is an architectural pattern where you keep multiple projects inside a single git repository.&lt;/p&gt;

&lt;p&gt;Imagine working on a semi-large project that includes some back-end, web front-end, and mobile applications. The most common approach would be to create different repositories for each of those applications. Then, developers would work on each part separately, developing, committing, and pushing to those repositories. &lt;/p&gt;

&lt;p&gt;But, as the work goes along, you start to notice some issues with your workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you see that you have some code duplication between your projects&lt;/li&gt;
&lt;li&gt;detecting critical/breaking changes became difficult since many problems came up only in the staging environment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to get around code duplication?
&lt;/h2&gt;

&lt;p&gt;The most common approach to deal with duplication is to move code "up" and separate it into reusable functions or maybe reusable typings. But, since your whole project consists of three separate repositories, there is no common spot to place reusable code.&lt;/p&gt;

&lt;p&gt;The only way to achieve this opportunity to lift code 'up' is to create another repository for that reusable code. A package or library, which we will keep inside that repository, must be later built and published on the &lt;strong&gt;NPM&lt;/strong&gt; registry.&lt;/p&gt;

&lt;p&gt;Of course, since our two applications would use this package to import and use it, any change in that common library would create a need to publish a new version of that library on &lt;strong&gt;NPM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We would have to keep track of releases and bump the version of that reusable package accordingly to the changes, probably using semantic versioning.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to deal with late bug detection?
&lt;/h2&gt;

&lt;p&gt;Introducing multiple apps and packages in a separate repository to maintain brings more significant problems than keeping proper versioning in mind. Imagine the following situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are working on a back-end application, and you need to change the response shape of some endpoint&lt;/li&gt;
&lt;li&gt;you commit your changes, the &lt;strong&gt;PR&lt;/strong&gt; passes all the necessary tests, and your code ships to the staging environment&lt;/li&gt;
&lt;li&gt;after deployment, you realize that part of the front-end application related to that prior endpoint has stopped working 😮&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Did it happen because you haven't tested your changes locally with the front-end application? Yes. But did it also occur because your workflow is not resilient enough? Also yes!&lt;/p&gt;

&lt;p&gt;It's hard to test everything, so we developers have &lt;strong&gt;CI/CD&lt;/strong&gt; tools to take some weight off our shoulders. &lt;/p&gt;

&lt;p&gt;We create automatic pipelines that run tests and perform code analyses, which are run on push. For example, in our case, we could have had two pipelines configured, one for running all of the checks for the front-end application, the other to do the same but for the back-end application.&lt;/p&gt;

&lt;p&gt;Unfortunately, when it comes to having two separated pipelines for two different applications, the fact that they are passing doesn't give us much confidence. What about that reusable library, which we had moved to a separate repository? Is it even tested? Does the front-end use the same version of that package as the back-end? Those are the type of questions that we lack an answer for. Of course, our code is bug-free, and all the tests are passing, but will those two applications work together?&lt;/p&gt;

&lt;p&gt;Even most minor changes, like extending the shape of a response with the extra field, maybe breaking change if the front-end does some strict runtime validation for static types (runtypes, zod, etc.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Monorepos to the rescue
&lt;/h2&gt;

&lt;p&gt;What if we had put our applications together in the same repository? Code duplication would no longer be a problem since we could move all the reusable code to another module or directory. Late bug detection would also not be a problem anymore because the pipelines for our front-end and back-end applications would run simultaneously. Linting, type checking, and static code analysis would also run globally.&lt;/p&gt;

&lt;p&gt;In fact, we would ensure that both our applications would be compatible with each other at any point in time since none of the breaking changes could be done to one package without updating the other ones.&lt;/p&gt;

&lt;p&gt;There are also other advantages of using monorepo over separate repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we could have common configs and enforce the style and linting rules across multiple applications,&lt;/li&gt;
&lt;li&gt;developers working on the project would have better visibility into the codebase,&lt;/li&gt;
&lt;li&gt;dependency management would be simplified as we could enforce an exact version of the same package used in multiple applications,&lt;/li&gt;
&lt;li&gt;we could manage our git history better since changes to multiple packages can be packed into a single commit&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disadvantages of using monorepo
&lt;/h2&gt;

&lt;p&gt;Despite many visible pros of using monorepo, this architectural pattern comes with some limitations. The most significant limitation is the lack of control over packages to which developers have access. If all of the applications and packages are stored in the same repository, then the person having access to that repository can now look into the whole codebase. Some companies enforce strict access control and restrict some parts of the app, which is irrelevant to the user.&lt;/p&gt;

&lt;p&gt;The other big concern is performance. Since there is a lot of code in one place, the build time is higher, and there are many commits that Git tracks. watching for changes and rebuilding only the packages that have changed can shorten build times and pipelines. I've heard that some tools allow you to fetch only one package along with its dependencies to speed git locally, but I haven't tested them out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monorepo tooling
&lt;/h2&gt;

&lt;p&gt;There are great tools and utilities for constructing monorepo with multiple modules inside and a pleasant developer experience. Here I specify the most popular ones, which I've had an opportunity to get familiar with:&lt;/p&gt;

&lt;h3&gt;
  
  
  Yarn workspaces
&lt;/h3&gt;

&lt;p&gt;Yarn workspaces link your dependencies together, which means that your packages can depend on one another. In addition, it sets up a single &lt;code&gt;node_modules&lt;/code&gt; folder without cloning dependencies throughout different packages in the project. &lt;/p&gt;

&lt;p&gt;Details on how to set up yarn workspaces can be found on &lt;a href="https://classic.yarnpkg.com/en/docs/workspaces/"&gt;yarn's official docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would recommend &lt;strong&gt;yarn workspaces&lt;/strong&gt; to anyone who uses &lt;strong&gt;yarn&lt;/strong&gt; as a dependency manager. It is easy to set up and maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nx
&lt;/h3&gt;

&lt;p&gt;Nx is an advanced set of extensible dev tools for monorepos, emphasizing modern full-stack web technologies. It provides nifty features like incremental builds and generating dependency graphs.&lt;br&gt;
&lt;strong&gt;Nx&lt;/strong&gt; comes with a CLI that allows you to quickly generate and add new packages, applications, or libraries into your project.&lt;/p&gt;

&lt;p&gt;More on that can be found in the &lt;a href="https://nx.dev/latest/react/getting-started/intro"&gt;Nx docs&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rush.js
&lt;/h3&gt;

&lt;p&gt;Rush.js is a robust monorepo infrastructure open sourced by &lt;strong&gt;Microsoft&lt;/strong&gt;. &lt;br&gt;
One of its key features is that &lt;strong&gt;Rush.js&lt;/strong&gt; installs all dependencies for all projects into a shared folder and then uses isolated symlinks to reconstruct an accurate &lt;code&gt;node_modules&lt;/code&gt; folder for each project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rush.js&lt;/strong&gt; also helps to ensure there are no phantom nor duplicated dependencies. Along with the &lt;strong&gt;PNPM&lt;/strong&gt; package manager, it allows you to save disk space by installing your dependencies only once.&lt;/p&gt;

&lt;p&gt;It also allows you to manage your packages, build and publish them. At the present moment, &lt;strong&gt;Rush.js&lt;/strong&gt; is my favorite among other tools that I've mentioned. &lt;/p&gt;

&lt;p&gt;More on &lt;strong&gt;Rush.js&lt;/strong&gt; can be found on the &lt;a href="https://rushjs.io/pages/intro/get_started/"&gt;official docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Monorepo architecture is a controversial architectural pattern. It comes with significant advantages as well as some big challenges. Even though many of the biggest companies use monorepos (&lt;strong&gt;Google, Facebook, Microsoft&lt;/strong&gt;), this pattern has many opponents.&lt;/p&gt;

&lt;p&gt;What do you guys think? Do you have some thoughts about monorepos? Do you have some good or bad experiences with them? I would like to know your opinions, and I am looking forward to the discussion.&lt;/p&gt;

&lt;p&gt;I hope you liked this introduction to monorepos. 🙂 Feel free to comment or ping me with DM! ✉️&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>discuss</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A weekly dose of best resources and articles for a full stack web developer 🔥 #2</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Mon, 01 Feb 2021 17:44:34 +0000</pubDate>
      <link>https://forem.com/skona27/a-weekly-dose-of-best-resources-and-articles-for-a-full-stack-web-developer-2-l85</link>
      <guid>https://forem.com/skona27/a-weekly-dose-of-best-resources-and-articles-for-a-full-stack-web-developer-2-l85</guid>
      <description>&lt;p&gt;For about some time, I've been pinning the best articles and resources I've come across while learning web development. Since I can no longer find myself in my Google Chrome bookmarks, I've decided to publish them online for better organizing and for other people to have access to them. 😃&lt;/p&gt;

&lt;p&gt;The first set of articles is available in the previous post.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/skona27" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F349119%2F1d42ff59-bccf-4041-8ec8-22e95ba6ec4d.jpeg" alt="skona27"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/skona27/a-weekly-dose-of-best-resources-and-articles-for-a-full-stack-web-developer-1-4nmb" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;A weekly dose of best resources and articles for a full stack web developer 🔥 #1&lt;/h2&gt;
      &lt;h3&gt;Jakub Skoneczny ・ Jan 21 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I've got articles covering topics like Javascript, React, Serverless, Cloud, CI/CD, DevOps, and others. Due to lack of time, I will try to post them gradually. Here are another 10 of my pinned articles:&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a href="https://making.close.com/posts/finding-the-cause-of-a-memory-leak-in-jest" rel="noopener noreferrer"&gt;Finding the cause of a memory leak in Jest tests&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;With increasing test coverage using Jest and React Testing Library, you may start seeing some “out of memory” errors. In this article, you will find how to solve this and how to find the cause of a memory leak.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://itnext.io/an-introduction-to-web-push-notifications-a701783917ce" rel="noopener noreferrer"&gt;Push Notifications in JavaScript? Yes, you can!&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;With this tutorial, you will get started with JavaScript Push Notifications with working code samples and an easy explanation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.joshwcomeau.com/react/modern-spacer-gif/" rel="noopener noreferrer"&gt;Let's Bring Spacer GIFs Back!&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Learn how to design components so they only affect their inner layout and not the whole page&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/dev-blogs/multiple-nodejs-apps-on-single-server-47b8bba3ec68" rel="noopener noreferrer"&gt;Multiple NodeJS apps on single server&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Learn about what is web server and application server and how to deploy multiple NodeJS applications on a single server with Reverse Proxy&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://towardsdatascience.com/how-to-analyse-100s-of-gbs-of-data-on-your-laptop-with-python-f83363dda94" rel="noopener noreferrer"&gt;How to analyze 100 GB of data on your laptop with Python&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Learn the best way of approaching that kind of datasets, which are a bit uncomfortable to use&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.isquaredsoftware.com/2021/01/context-redux-differences/" rel="noopener noreferrer"&gt;Why React Context is Not a 'State Management' Tool (and Why It Doesn't Replace Redux)&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This post will clarify what Context and Redux actually are, how they're meant to be used, how they're different, and when you should use them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://codersbible.com/introduction-to-reactive-programming-for-everyone/" rel="noopener noreferrer"&gt;Introduction to Reactive Programming for Everyone&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;RxJava, RxJS... - do you see technologies like these listed in the job requirements and feel a little bit scared? With that article, you will get to know your opponent!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04" rel="noopener noreferrer"&gt;How To Set Up a Node.js Application for Production on Ubuntu 16.04&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This tutorial will cover setting up a production-ready Node.js environment on a single Ubuntu 16.04 server. The server will run a Node.js application managed by PM2 with Nginx Reverse Proxy.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.gabrielgambetta.com/client-server-game-architecture.html" rel="noopener noreferrer"&gt;Fast-Paced Multiplayer (Part I): Client-Server Game Architecture&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;First in a series of articles exploring the techniques and algorithms that make fast-paced multiplayer games possible&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/christopherkade/18-devtools-for-productivity-5ia"&gt;18 DevTools for productivity 🚀&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This may sound crazy, but developers are lazy. We need to automate lots of our tasks because repetition can be tiring. Here is a list of some tools I find extremely useful&lt;/p&gt;




&lt;p&gt;That's it for now. 😀 If you also have great resources pinned or saved on your computer, you can send me some (comment or message), and I will include them in my list.&lt;/p&gt;

&lt;p&gt;You can find the whole list of resources on my personal website:&lt;br&gt;
&lt;a href="https://blog.jskoneczny.pl/resources" rel="noopener noreferrer"&gt;Resources | Jakub Skoneczny - Javascript Developer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub" rel="noopener noreferrer"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>react</category>
    </item>
    <item>
      <title>Run Git commands from Node.js application using JavaScript! 🚀</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Mon, 25 Jan 2021 17:00:49 +0000</pubDate>
      <link>https://forem.com/skona27/run-git-commands-from-node-js-application-using-javascript-10be</link>
      <guid>https://forem.com/skona27/run-git-commands-from-node-js-application-using-javascript-10be</guid>
      <description>&lt;p&gt;When dealing with large applications and with &lt;strong&gt;complex, CI/CD pipelines with multiple staging environments&lt;/strong&gt;, it might be useful for you to have some way to automate applying the latest changes from one environment to the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency between multiple environments
&lt;/h2&gt;

&lt;p&gt;At my work, we have three environments - one is the production environment (&lt;strong&gt;PROD&lt;/strong&gt;), and two others are for fixing critical errors (&lt;strong&gt;HOTFIX&lt;/strong&gt;) and developing new stuff (&lt;strong&gt;STAGING&lt;/strong&gt;) with the possibility of introducing breaking changes.&lt;/p&gt;

&lt;p&gt;While creating a pull request with a quick fix of some bug and merging it to the &lt;strong&gt;HOTFIX&lt;/strong&gt; environment (with future deployment to production), it is also necessary to have this code in the &lt;strong&gt;STAGING&lt;/strong&gt; environment, so the future deployment of &lt;strong&gt;STAGING&lt;/strong&gt; into &lt;strong&gt;PROD&lt;/strong&gt; would not cause conflicts.&lt;/p&gt;

&lt;p&gt;The easiest way for having this cross-environment consistency is to make cherry-pick of the commit to &lt;strong&gt;STAGING&lt;/strong&gt; after it is merged into &lt;strong&gt;HOTFIX&lt;/strong&gt;. Easy, but manual, and since it's manual, someone can forget to do this. 😅 Plus, we need to know the specific identifier of a commit, so it's rather tricky for automatization.&lt;/p&gt;

&lt;p&gt;Another way to achieving this is to rebase &lt;strong&gt;STAGING&lt;/strong&gt; on top of &lt;strong&gt;HOTFIX&lt;/strong&gt; periodically. By doing it, we will have all of our feature changes as well as fixes of bugs. And also, it is somewhat manual work, but this time it is easy for automatization.&lt;/p&gt;

&lt;p&gt;For this automatization, we will use a &lt;a href="https://github.com/steveukx/git-js" rel="noopener noreferrer"&gt;simple-git&lt;/a&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  A lightweight interface for running git commands
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/steveukx/git-js" rel="noopener noreferrer"&gt;Simple-git&lt;/a&gt; is a tool for running git commands in any Node.js application. &lt;br&gt;
It gives us access to make all kinds of permutations on top of your commits and branches. With that library, we can easily create a script responsible for releasing our latest changes and running it from the command line.&lt;/p&gt;

&lt;p&gt;All we need to do in order to start using simple-git is to include into our JavaScript app and create a &lt;code&gt;git&lt;/code&gt; instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;simpleGit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;simple-git&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;simpleGit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we have access to any git command as well as for options supported by that command. You can later visit the &lt;a href="https://github.com/steveukx/git-js#api" rel="noopener noreferrer"&gt;public API of the library&lt;/a&gt; to see the full list of available methods. &lt;/p&gt;

&lt;p&gt;For now, simply try to checkout on some test branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test-branch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// logs "test-branch"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, and it's plain and simple like standard git commands! 🙂&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Remember that from within your script, any git command is like a side-effect, and it is not synchronous. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's imagine having a script like one below, which executes all the commands needed for rebase one branch into another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isClean&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HOTFIX&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;origin/HOTFIX&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;STAGING&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;origin/STAGING&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rebase&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HOTFIX&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;STAGING&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--force&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conflicted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our script fetches the latest changes on every branch, then it rebases &lt;strong&gt;STAGING&lt;/strong&gt; branch on top of &lt;strong&gt;HOTFIX&lt;/strong&gt;. Before executing anything, we check for not committed files since a hard reset will discard any changes made in development. Unfortunately in case of an error or merge conflicts, we must continue manually. &lt;/p&gt;

&lt;p&gt;So we have an automated way of rebasing branches to date with the latest &lt;strong&gt;HOTFIX&lt;/strong&gt; environment. And with &lt;a href="https://github.com/chalk/chalk" rel="noopener noreferrer"&gt;chalk&lt;/a&gt;, we can make it a beautiful command-line script:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1349085418269138946-483" src="https://platform.twitter.com/embed/Tweet.html?id=1349085418269138946"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1349085418269138946-483');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1349085418269138946&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Now with this script, which takes care of rebasing for us, the whole process of making your environments consistent is encapsulated in one single file, which can be executed from the command-line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;

&lt;span class="c1"&gt;// or we can specify a command in package.json&lt;/span&gt;
&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;branches&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;branches&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I guess it is even possible to hook up this script in the deployment pipeline, for example, with &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Github Actions&lt;/a&gt; or &lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;Husky&lt;/a&gt;. I will explore this topic in the future. 😃&lt;/p&gt;

&lt;p&gt;I really recommend you to inspect this awesome library for yourselves!&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub" rel="noopener noreferrer"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>git</category>
      <category>node</category>
    </item>
    <item>
      <title>A weekly dose of best resources and articles for a full stack web developer 🔥 #1</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Thu, 21 Jan 2021 22:13:49 +0000</pubDate>
      <link>https://forem.com/skona27/a-weekly-dose-of-best-resources-and-articles-for-a-full-stack-web-developer-1-4nmb</link>
      <guid>https://forem.com/skona27/a-weekly-dose-of-best-resources-and-articles-for-a-full-stack-web-developer-1-4nmb</guid>
      <description>&lt;p&gt;For about some time, I've been pinning the best articles and resources I've come across while learning web development. Since I can no longer find myself in my Google Chrome bookmarks, I've decided to publish them online for better organizing and for other people to have access to them. 😃&lt;/p&gt;

&lt;p&gt;I've got articles covering topics like Javascript, React, Serverless, Cloud, CI/CD, DevOps, and others. Due to lack of time, I will try to post them gradually. Here is the first set of them: &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a href="https://codelabs.developers.google.com/codelabs/ar-with-webxr#0"&gt;Building an augmented reality (AR) application using the WebXR Device API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Tutorial on building an AR web application. The application uses JavaScript to render 3D models that appear as if they exist in the real world.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.joshwcomeau.com/react/the-perils-of-rehydration/"&gt;The Perils of Rehydration&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;How to avoid rehydration problems with Gatsby and React SSR in depth. If you have ever experienced a warning about the mismatch between elements rendered on the server and on the client-side, this article is for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/javascript-in-plain-english/gamedev-patterns-and-algorithms-in-action-with-typescript-d29b913858e"&gt;Building a game with TypeScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Series of tutorials on how to build a board game from scratch with TypeScript and native browser APIs. Includes Canvas API and state machines.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://citw.dev/tutorial/create-your-own-compiler"&gt;Create Your Own Compiler&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This tutorial explains the mechanism of how JavaScript works. The Super Tiny Compiler is a simple compiler written in Javascript and you will write it step by step from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/@ryan.mcnierney/using-react-google-sheets-as-your-cms-294c02561d59"&gt;Using React + Google Sheets as your CMS&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Tutorial on how to serve up any data from a Google Sheet into a real React application. Maybe it's not meant to be used in production apps, but for a quick solution, it is perfect!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/midiblocks/introducing-handsfree-js-integrate-hand-face-and-pose-gestures-to-your-frontend-4g3p"&gt;Introducing Handsfree.js - Integrate hand, face, and pose gestures to your frontend&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Handle any kind of gestures into your web application. Handsfree.js is a client-side library that helps you add hand, face, and pose estimation to your front end projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API"&gt;Using the Web Speech API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The Web Speech API enables you to incorporate voice data into web apps. With this official MDN documentation, you can learn In-depth about speech recognition.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/free-code-camp/continuous-deployment-for-node-js-on-google-cloud-platform-751a035a28d5"&gt;Continuous Deployment for Node.js on the Google Cloud Platform&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Setup your Node.js application to deploy to App Engine on GitHub push. Covers the basics of Google Cloud Platform and Cloud Build.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://levelup.gitconnected.com/dockerizing-and-autoscaling-node-js-on-google-cloud-ef8db3b99486"&gt;Dockerizing and autoscaling Node.js on Google Cloud&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Learn how to dockerize a Node.js server for hosting in Google Cloud and configuring your VM instances to auto-scale proportionally with traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/@louiskengo3/getting-started-with-terraform-and-google-cloud-platform-9c3c45dc5bde"&gt;Getting Started with Terraform and Google Cloud Platform&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Terraform is an automation tool used to ease the process of setting up infrastructure on which you can deploy applications. It can be used for describing infrastructure as a code regardless of the cloud provider.&lt;/p&gt;




&lt;p&gt;That's it for now. 😀 If you also have great resources pinned or saved on your computer, you can send me some (comment or message), and I will include them in my list.&lt;/p&gt;

&lt;p&gt;If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>The easiest way to internationalize your NextJS application! 🌎</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Mon, 18 Jan 2021 17:09:03 +0000</pubDate>
      <link>https://forem.com/skona27/the-easiest-way-to-internationalize-your-nextjs-application-llj</link>
      <guid>https://forem.com/skona27/the-easiest-way-to-internationalize-your-nextjs-application-llj</guid>
      <description>&lt;p&gt;From version &lt;strong&gt;10&lt;/strong&gt;, &lt;strong&gt;Next.js&lt;/strong&gt; has built-in support for internationalized routing. This feature allows you to support multilanguage versions of your application just by providing a list of locales. &lt;/p&gt;

&lt;p&gt;Start with changing your &lt;strong&gt;Next.js&lt;/strong&gt; configuration, which is inside &lt;strong&gt;next.config.js&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Provide the locales you want to support in your application
     */&lt;/span&gt;
    &lt;span class="na"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * This is the default locale you want to be used when visiting
     * a non-locale prefixed path e.g. `/hello`
     */&lt;/span&gt;
    &lt;span class="na"&gt;defaultLocale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accessing the locale information
&lt;/h2&gt;

&lt;p&gt;After configuring the supported locales, you can access the locale information with the &lt;strong&gt;Next.js&lt;/strong&gt; built-in router. The router has the following properties inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;locale&lt;/code&gt;, which contains the currently active locale,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;locales&lt;/code&gt;, which includes all configured locales,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defaultLocale&lt;/code&gt;, which provides for the configured default locale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Router is accessible from the functional components by the &lt;code&gt;useRouter&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultLocale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When doing &lt;strong&gt;SSR&lt;/strong&gt; with &lt;code&gt;getStaticProps&lt;/code&gt; or &lt;strong&gt;SSG&lt;/strong&gt; with &lt;code&gt;getServerSideProps&lt;/code&gt;, the locale information is provided in the function's context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transition between locales
&lt;/h2&gt;

&lt;p&gt;You can use the built-in &lt;code&gt;Link&lt;/code&gt; component along with the &lt;code&gt;useRouter&lt;/code&gt; hook to transition between locales:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Inside your component
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;asPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;asPath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      PL
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;asPath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"en-US"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      ENG
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Presenting multilanguage data
&lt;/h2&gt;

&lt;p&gt;Now you can define an object in which we will store multi-language data for our components. After reading the current &lt;code&gt;locale&lt;/code&gt; value, we can get translated texts just by accessing the property on an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Define your multi-language data
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;pl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cześć!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Inside your component
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  What about type safety?
&lt;/h2&gt;

&lt;p&gt;When reading the value of &lt;code&gt;locale&lt;/code&gt; from the &lt;code&gt;useRouter&lt;/code&gt; hook, you may notice that your IDE identifies the type of the &lt;code&gt;locale&lt;/code&gt; as a string. Unfortunately, at this moment, &lt;strong&gt;Next.js&lt;/strong&gt; does not provide typescript support for locales. &lt;/p&gt;

&lt;p&gt;If you want to get full type safety, you may want to introduce your own custom hook for reading the value from of &lt;code&gt;locale&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1346865579349716992-300" src="https://platform.twitter.com/embed/Tweet.html?id=1346865579349716992"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1346865579349716992-300');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1346865579349716992&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;After defining your own type for supported locales and reading the current locale's value from the router, let's return this value with a simple &lt;code&gt;as&lt;/code&gt; type assignment.&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub" rel="noopener noreferrer"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I've rebuilt my portfolio. Now it loads in less than 1 sec! Here's how I did it! ⚡</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Mon, 11 Jan 2021 17:00:49 +0000</pubDate>
      <link>https://forem.com/skona27/i-ve-rebuilt-my-portfolio-now-it-loads-in-less-than-1-sec-here-s-how-i-did-it-6hd</link>
      <guid>https://forem.com/skona27/i-ve-rebuilt-my-portfolio-now-it-loads-in-less-than-1-sec-here-s-how-i-did-it-6hd</guid>
      <description>&lt;p&gt;Some time ago, during my early &lt;strong&gt;PHP&lt;/strong&gt; years, I had created a website for myself, which combined my resume and some space for sharing my thoughts with the world. That website was well designed and had many features like tagging posts, filtering, and searching. But on the other hand, that website was cumbersome. The application took about &lt;strong&gt;5 to 6 seconds&lt;/strong&gt; to load on a good internet connection!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FcYKVpfn%2Freport-numbers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FcYKVpfn%2Freport-numbers.png" alt="Bad Lighthouse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I realized that at some point, I would need to rewrite everything from scratch. That moment came when I have learned about the &lt;strong&gt;React&lt;/strong&gt; ecosystem. Now, after it's done, I would like to share my thoughts on how I have managed to make the website incredibly fast. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: When writing this article, I intend to explain what can be done to improve any website's performance. Please note that some of those points may not be valid for your use case since not all websites are the same (blog is different than e-commerce application).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Use the right tools for the job 🔨
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PHP&lt;/strong&gt; language was fantastic, as so &lt;strong&gt;Laravel&lt;/strong&gt;, which is a framework for developing web applications. But after I have learned the &lt;strong&gt;React&lt;/strong&gt; and its ecosystem, I have decided to go with &lt;strong&gt;NextJS&lt;/strong&gt;. And oh, boy, it was an excellent choice! &lt;strong&gt;NextJS&lt;/strong&gt; supports two forms of rendering your content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static Generation&lt;/strong&gt;: The &lt;strong&gt;HTML&lt;/strong&gt; is generated at build time,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side Rendering&lt;/strong&gt;: The &lt;strong&gt;HTML&lt;/strong&gt; is generated on each request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Static generation is perfect for use cases like blogs or personal websites, where the content does not change often. After you build the application with that approach, you end up with a bunch of static &lt;strong&gt;HTML&lt;/strong&gt; files, which you can deploy on any hosting. And nothing is more performant than simple &lt;strong&gt;HTML&lt;/strong&gt; files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize your assets 📦
&lt;/h2&gt;

&lt;p&gt;It seems like an obvious thing to do, but I will mention this anyway. Any static assets that you use on your website should be optimized. It includes minifying your &lt;strong&gt;CSS&lt;/strong&gt; files and &lt;strong&gt;JavaScript&lt;/strong&gt; files but also compressing images. For example, if you use a picture for your avatar, you don't need a file that has &lt;strong&gt;500x500px dimensions&lt;/strong&gt; and a weight of &lt;strong&gt;200 Kb&lt;/strong&gt;. Choose a resized file instead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Almost any image can be optimized by dropping its quality to about &lt;strong&gt;80%&lt;/strong&gt;, and there will be no visual difference between the compressed version and the original.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you use modern web frameworks like &lt;strong&gt;NextJS&lt;/strong&gt;, all of your bundles are already optimized. But be careful if you put external stylesheets or scripts to your website because they are not always minified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preload external scripts 🕖
&lt;/h2&gt;

&lt;p&gt;When dealing with external &lt;strong&gt;JavaScript&lt;/strong&gt; files, you need to be careful where you put those scripts inside your &lt;strong&gt;HTML&lt;/strong&gt; because this will affect the loading time. By putting external scripts in the head of the document, your browser will try to fetch and execute the script before rendering &lt;strong&gt;DOM&lt;/strong&gt;. It is recommended to move external scripts at the end of the body or specifying defer property on those scripts.&lt;/p&gt;

&lt;p&gt;Deferring scripts will result in them being downloaded with other resources but executed after the &lt;strong&gt;HTML&lt;/strong&gt; is parsed and rendered. I recommend you to read this excellent article on that topic: &lt;a href="https://flaviocopes.com/javascript-async-defer/" rel="noopener noreferrer"&gt;Efficiently load JavaScript with defer and async&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy load images 🖼️
&lt;/h2&gt;

&lt;p&gt;We tend to use a lot of images on our websites. Whether they are put in the background, or we want to share something, it's unnecessary to load them all at once.  The standard way to deal with images is to load only those directly in the viewport or close to it. We don't need to load an image that is far down the page and isn't visible to the user yet.&lt;/p&gt;

&lt;p&gt;There are many techniques to implement lazy loading, but the most common way is to use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;Intersection Observer API&lt;/a&gt; or a library that depends on it. Recently, native lazy load support has been added to the &lt;strong&gt;Google Chrome&lt;/strong&gt; browser. It is as simple as adding a &lt;strong&gt;loading&lt;/strong&gt; property onto the &lt;strong&gt;img&lt;/strong&gt; element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;lazy&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Not every browser yet supports it, but this will be the standard of lazy loading images in the future. You can learn more on that here: &lt;a href="https://web.dev/browser-level-image-lazy-loading/" rel="noopener noreferrer"&gt;Browser-level image lazy-loading for the web&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Use service worker 📝
&lt;/h2&gt;

&lt;p&gt;A Service Worker is a script that executes in the background, in a separate thread from the main &lt;strong&gt;JavaScript&lt;/strong&gt; bundle. A service worker can intercept all network request, so it's often used for caching assets and some of the critical API payloads that make possible for a website to function without an internet connection.&lt;/p&gt;

&lt;p&gt;Using the &lt;strong&gt;service worker&lt;/strong&gt; will not increase your website's speed on the very first load, but every other reload will be faster since some of the assets are already downloaded and stored inside the browser's cache. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: A service worker is recommended for the browsers to treat your application as an installable &lt;strong&gt;SPA&lt;/strong&gt;. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Use CDN 🌎
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Content Delivery Network&lt;/strong&gt; is a way to deliver content from your website to clients more quickly and efficiently, based on their geographic location. It allows for the quick transfer of assets needed for loading your content, including &lt;strong&gt;HTML&lt;/strong&gt;, scripts, and stylesheets from the server located closest to the client.&lt;/p&gt;

&lt;p&gt;The main benefits of using a &lt;strong&gt;CDN&lt;/strong&gt; in front of your web server or static hosting are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improving website load times&lt;/strong&gt;, because the website and its assets are cached and served from the closest server in the network,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducing bandwidth costs&lt;/strong&gt; since requests are interested and not directed to your server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many &lt;strong&gt;CDN&lt;/strong&gt; providers (e.g., &lt;strong&gt;Cloudflare&lt;/strong&gt;) provides you as well with security improvements for your application. They support you with a free &lt;strong&gt;SSL&lt;/strong&gt; certificate for your domain and with protection from &lt;strong&gt;DDoS attacks&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Effect? Blazing fast website ⚡
&lt;/h2&gt;

&lt;p&gt;After developing my new website and implementing all of the tips listed above, I have reduced the loading time to about &lt;strong&gt;1 second&lt;/strong&gt;! The effect had shocked me positively. Check out the lighthouse report:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2Ff9chbCJ%2FPrzechwytywanie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2Ff9chbCJ%2FPrzechwytywanie.png" alt="Bad Lighthouse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I realize that those numbers come only from a simulation, and they may differ on real devices. But seeing that audit with the &lt;strong&gt;time of First Meaningful Paint being 0.7 seconds&lt;/strong&gt; makes me smile. 😀&lt;/p&gt;

&lt;p&gt;Thanks for reading, and I hope you have enjoyed this article. I would love to receive your feedback on my portfolio site since it is new and freshly designed. Check it out, and let me know your opinions. 😊&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My portfolio&lt;/strong&gt;: &lt;a href="https://blog.jskoneczny.pl/" rel="noopener noreferrer"&gt;blog.jskoneczny.pl&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Skona27" rel="noopener noreferrer"&gt;
        Skona27
      &lt;/a&gt; / &lt;a href="https://github.com/Skona27/fancy-portfolio" rel="noopener noreferrer"&gt;
        fancy-portfolio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      My new fancy portfolio
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;: If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub" rel="noopener noreferrer"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Future of state management in React with XState</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Tue, 05 Jan 2021 15:15:17 +0000</pubDate>
      <link>https://forem.com/skona27/future-of-state-management-in-react-with-xstate-kg4</link>
      <guid>https://forem.com/skona27/future-of-state-management-in-react-with-xstate-kg4</guid>
      <description>&lt;p&gt;It is common to see a poll on social media asking for the most common ways to manage state in React. In many cases, the options are limited to &lt;strong&gt;MobX&lt;/strong&gt; or &lt;strong&gt;Redux&lt;/strong&gt;, &lt;strong&gt;React Context + Hooks&lt;/strong&gt;, &lt;strong&gt;Recoil&lt;/strong&gt;, but more recently, also &lt;strong&gt;XState&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With the other tools being well known and primarily accepted (maybe without Recoil, since it's also new), &lt;strong&gt;XState&lt;/strong&gt; is still relatively unknown to most developers. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The purpose of this post is not to compare XState to other state management tools, but rather to tell about the problem it solves and give you a quick introduction, so you can jump and start learning by yourself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So without further ado, let me tell you more about &lt;strong&gt;XState&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is XState?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XState&lt;/strong&gt; is a library that brings state machines to &lt;strong&gt;Javascript&lt;/strong&gt; and &lt;strong&gt;Typescript&lt;/strong&gt; world. State machines are a mathematical concept that has been introduced for describing complex systems. To explain it quickly, imagine a block schema - you have multiple blocks connected with lines and arrows. Those blocks represent states in your application, and lines with arrows represent the flow between those states.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FaJA2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FaJA2b.png" alt="Block Schema"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you start from the first block, you can only transition into the block you have a connection with. Therefore you are automatically prevented from transitioning to any block you want. And this is the most significant advantage of using state machines - you can only transition between states that have defined and allowed connections. &lt;/p&gt;

&lt;p&gt;Let's now drop this analogy tho schema and use the proper terminology. &lt;/p&gt;

&lt;p&gt;Every state machine has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;finite number of states&lt;/strong&gt; (such as &lt;code&gt;idle&lt;/code&gt; or &lt;code&gt;loading&lt;/code&gt;), &lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;finite number of events&lt;/strong&gt; (such as &lt;code&gt;{ type: 'SEARCH' }&lt;/code&gt; can trigger a transition between states).&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;list of defined transitions&lt;/strong&gt;, which say, "Given some event, go from state idle to pending".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, every state machine may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;context&lt;/strong&gt; which is data stored inside the machine,&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;final state&lt;/strong&gt;, after which the machine stops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, so we know what a state machine is. But when seeing a designed schema, it is easy to think about it as a machine. Let's see how one can think of anything like a machine and write it using &lt;strong&gt;XState&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Describing ordinary things in the form of a state machine
&lt;/h2&gt;

&lt;p&gt;Think about water. Just regular water. How does it behave? If we start with the liquid form, it freezes when it's cold, and it vaporizes when we boil it. We can even heat it more and more until it becomes plasma. Let's try to write it down in block schema:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fmedia-p.slid.es%2Fuploads%2F988410%2Fimages%2F7783918%2Fwater_machine.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fmedia-p.slid.es%2Fuploads%2F988410%2Fimages%2F7783918%2Fwater_machine.png" alt="water machine schema"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When water becomes plasma, we can no longer heat it because it can't change farther. We can only freeze it from there. If we start to freeze plasma, it will become a gas again. The same thing is with ice. If water is in ice form, we can't longer freeze it. We can only heat it.&lt;/p&gt;

&lt;p&gt;If you look closely, you will notice that water has no final form. We can always make a transition between its states. Let's see how we could implement it with &lt;strong&gt;XState&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Machine&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xstate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waterMachine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Machine&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;liquid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;states&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;HEAT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;liquid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;liquid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;HEAT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;FREEZE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;gas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;HEAT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plasma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;FREEZE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;liquid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plasma&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;FREEZE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to import a &lt;code&gt;Machine&lt;/code&gt; creator and pass it into the machine's object. Machine's object has &lt;code&gt;states&lt;/code&gt; property where we define our states. In each state, we can put the &lt;code&gt;on&lt;/code&gt; property, which handles events that are defined within.&lt;/p&gt;

&lt;p&gt;Event handlers are objects in which we can put &lt;code&gt;target&lt;/code&gt; property pointing on a different state. This means that when the &lt;code&gt;HEAT&lt;/code&gt; event in the &lt;code&gt;ice&lt;/code&gt; state comes, the machine will transition from an &lt;code&gt;ice&lt;/code&gt; state to a &lt;code&gt;liquid&lt;/code&gt; state.&lt;/p&gt;

&lt;p&gt;This explanation may sound complicated, but it starts to be straightforward if you look into the code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using XState with React
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XState&lt;/strong&gt; is a Javascript library, which means it is framework agnostic. But when it comes to &lt;strong&gt;React&lt;/strong&gt;, &lt;strong&gt;XState&lt;/strong&gt; gives us hooks for using a defined state machine inside &lt;strong&gt;React&lt;/strong&gt; components. All we need to do is to call it, and then we have access to properties like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;state&lt;/strong&gt; that represents the current state of the machine and its data,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;send&lt;/strong&gt;, a function that sends events to the machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that, you can use your machine inside components. You can read its current state (e.g., rendering different components based on state), you can read its context (for displaying data), and you can send events to that machine (make transitions between states).&lt;/p&gt;

&lt;p&gt;Just see the usage of our water machine inside the &lt;strong&gt;React&lt;/strong&gt; application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMachine&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@xstate/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// use hooks inside your component&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMachine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waterMachine&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 'liquid' &lt;/span&gt;

&lt;span class="c1"&gt;// send event for making a transition&lt;/span&gt;
&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HEAT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 'gas' &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prototyping and debugging with ease
&lt;/h2&gt;

&lt;p&gt;State machines built with &lt;strong&gt;XState&lt;/strong&gt; can be visualized with the usage of &lt;a href="https://xstate.js.org/viz/" rel="noopener noreferrer"&gt;XState Viz&lt;/a&gt;. This fantastic tool allows you to do many things with your machines like debugging, live preview, and interactivity. Just see how we can interact with our water state machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs8.gifyu.com%2Fimages%2F159e650772d49577e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs8.gifyu.com%2Fimages%2F159e650772d49577e.gif" alt="water machine visualized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing complex systems with state machines
&lt;/h2&gt;

&lt;p&gt;When thinking of large web applications, often it comes for us developers to introduce huge and intricate features. Some components are built with dozen or hundreds of child components that also have some logic inside. Coming up with a sound state management system for that can be tricky. Fortunately, state machines fit well for that. &lt;/p&gt;

&lt;p&gt;A state machine can be just like a single block in block schema. Your application can have multiple state machines, which communicate with each other. Also, you can have one main state machine which controls the others and enables that communication.&lt;/p&gt;

&lt;p&gt;And all of that logic nested inside multiple state machines can be later visualized with &lt;strong&gt;XState Viz&lt;/strong&gt; and be interactive. What a great business value for your PM!&lt;/p&gt;

&lt;p&gt;In my opinion, this is the most valuable advantage of state machines over other state management tools - it's not just a library for state management. It is a whole new ecosystem for designing and controlling business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further with XState
&lt;/h2&gt;

&lt;p&gt;If you want to dive deeper into &lt;strong&gt;XState&lt;/strong&gt; concepts, I highly recommend visiting the &lt;a href="https://xstate.js.org/docs/" rel="noopener noreferrer"&gt;official XState documentation&lt;/a&gt;. Documentation is written clearly and is pleasant to read. For those of you who instead prefer video sources over reading documentation, I have prepared an introductory course that is available on &lt;strong&gt;Udemy&lt;/strong&gt; - &lt;a href="https://www.udemy.com/course/introduction-to-state-machines-with-xstate-and-react" rel="noopener noreferrer"&gt;Introduction to State Machines with XState and React&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for sticking for that long! If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow &lt;a href="https://twitter.com/SkonecznyJakub" rel="noopener noreferrer"&gt;My Twitter account&lt;/a&gt; as well!&lt;/p&gt;

&lt;p&gt;This post has been originally posted on my &lt;a href="https://blog.jskoneczny.pl/post/future-of-state-management-in-react-with-xstate" rel="noopener noreferrer"&gt;personal blog&lt;/a&gt;. Please make sure you see it there as well :)&lt;/p&gt;

&lt;p&gt;PS. Comment if you have used XState in production!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>xstate</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Deploy scalable NodeJS application with Postgres database using AWS CDK</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Fri, 01 Jan 2021 14:40:32 +0000</pubDate>
      <link>https://forem.com/skona27/deploy-scalable-nodejs-application-with-postgres-database-using-aws-cdk-22l4</link>
      <guid>https://forem.com/skona27/deploy-scalable-nodejs-application-with-postgres-database-using-aws-cdk-22l4</guid>
      <description>&lt;p&gt;This simple tutorial will show how to deploy any NodeJS application on AWS cloud with AWS Cloud Development Kit usage. Our application will use the Postgress database, but code from this tutorial can be a basis for deploying any database with your application.&lt;/p&gt;

&lt;p&gt;I will not cover the AWS CDK basics since there are plenty of good resources, which explain everything from scratch and show how to bootstrap your AWS CDK project. &lt;/p&gt;

&lt;p&gt;If you need to check the basics, here are some good sources:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/tlakomy/what-is-aws-cdk-cloud-development-kit-and-why-it-s-awesome-4gm8"&gt;What is AWS CDK (Cloud Development Kit) and why it's awesome&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/aws/aws-cdk"&gt;AWS CDK repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I specify what we are going to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create secrets using AWS Secret Manager and read them from our custom stack&lt;/li&gt;
&lt;li&gt;Create an RDS stack with database definition&lt;/li&gt;
&lt;li&gt;Create ElasticBeanstalk stack for application deployment&lt;/li&gt;
&lt;li&gt;Create VPC stack and connecting everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: This tutorial is inspired by two other posts. Without them, it would take me much longer to figure out everything:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/michaelfecher/i-tell-you-a-secret-provide-database-credentials-to-an-ecs-fargate-task-in-aws-cdk-5f4"&gt;I tell you a secret: Provide Database credentials to an ECS Fargate task in AWS CDK&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@joshmustill/complete-node-js-aws-elastic-beanstalk-application-packaging-through-cdk-in-typescript-e91b7ffe4928"&gt;Complete AWS Elastic Beanstalk Application through CDK (TypeScript)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So without further ado, let's get started!&lt;/p&gt;
&lt;h2&gt;
  
  
  Create secrets in the AWS Secret Manager
&lt;/h2&gt;

&lt;p&gt;Go to your AWS Console and search for Secret Manager service and create two secrets to store your username and password for the database connection. AWS suggests you keep their naming conventions, so let's use &lt;code&gt;prod/service/db/user&lt;/code&gt; as a name for user secret and &lt;code&gt;prod/service/db/password&lt;/code&gt; as a name for the password.&lt;/p&gt;

&lt;p&gt;Once you create those secrets, keep the ARN, which you will get back. They will be required to set up our connection.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create stack for keeping credentials
&lt;/h2&gt;

&lt;p&gt;Let's create a file called &lt;code&gt;lib/credentials-stack.ts&lt;/code&gt; in which we will read credentials that were saved in Secret Manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ISecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Secret&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-secretsmanager&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ISecret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ISecret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CredentialsStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ISecret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ISecret&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromSecretCompleteArn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BackendPersistenceUsername&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// Pass your username secret ARN&lt;/span&gt;
      &lt;span class="dl"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromSecretCompleteArn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BackendPersistencePassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// Pass your password secret ARN&lt;/span&gt;
      &lt;span class="dl"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;secretUsername&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;secretPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have made a new stack in which we read secrets required for connecting to our database and keep them in the &lt;code&gt;credentials&lt;/code&gt; property attached to this stack. Later on, we will be able to pass those credentials to other stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create RDS stack with Postgress database
&lt;/h2&gt;

&lt;p&gt;Now we need to create a stack that will hold definitions for our Postgress database. For that, let's create a file called &lt;code&gt;lib/rds-stack.ts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-ec2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-rds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./credentials-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RdsStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Vpc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;RdsStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;postgreSQLinstance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DatabaseInstance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RdsStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgreSQLinstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DatabaseInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Postgres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DatabaseInstanceEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PostgresEngineVersion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VER_12_4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;instanceType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstanceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstanceClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstanceSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MICRO&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;vpcPlacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;subnetType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SubnetType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PUBLIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;storageType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StorageType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GP2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;deletionProtection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;databaseName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgreSQLinstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowDefaultPortFromAnyIpv4&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgreSQLinstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowDefaultPortInternally&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since any database in AWS must always be created in the scope of some VPC, we have defined an interface for props to our stack and specified that &lt;code&gt;vpc&lt;/code&gt; must be passed when instantiating this stack. Also, we will need to pass credentials, which we keep in &lt;code&gt;credentials-stack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This Postgress instance, which we have defined, uses a basic &lt;code&gt;T2 MICRO&lt;/code&gt; instance, and is placed in public scope - our database will be reachable from the internet. Please note that we allow connections by invoking special methods (&lt;code&gt;allowDefaultPortFromAnyIpv4&lt;/code&gt; and &lt;code&gt;allowDefaultPortInternally&lt;/code&gt;) on our instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating deployment with ElasticBeanstalk
&lt;/h2&gt;

&lt;p&gt;We can then create a stack responsible for copying our application files to S3 and then deploying it to ElasticBeanstalk service. Let's create a file called &lt;code&gt;lib/ebs-stack.ts&lt;/code&gt; and paste the code presented below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;EB&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-elasticbeanstalk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;S3Assets&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-s3-assets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./credentials-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;EbsStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;dbCredentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dbHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dbPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;EbsStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EbsStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Here you can specify any other ENV variables which your application requires&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbHost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;DB_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environmentOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws:elasticbeanstalk:application:environment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;optionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;applicationName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;S3Assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Asset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-assets`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Change path to your applications dist files&lt;/span&gt;
      &lt;span class="c1"&gt;// In my case I've created a monorepo, so path was like ../server/dist&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path/to/your/application/dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CfnApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-app`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appVersionProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CfnApplicationVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-version`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;sourceBundle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;s3Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3BucketName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;s3Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3ObjectKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CfnEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OptionSettingProperty&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws:autoscaling:launchconfiguration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;optionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IamInstanceProfile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-elasticbeanstalk-ec2-role&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws:ec2:instances&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;optionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;InstanceTypes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;t3.small&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CfnEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-environment`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;environmentName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;develop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applicationName&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;applicationName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;solutionStackName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;64bit Amazon Linux 2 v5.2.3 running Node.js 12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;optionSettings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;environmentOptions&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;versionLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appVersionProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;appVersionProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addDependsOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first step is to create an S3 bucket, including the source files for our application. This S3 logic fires before the CloudFormation template is acted upon to be available for EBS.&lt;/p&gt;

&lt;p&gt;Then, the environment for the application is created, and the application is assigned to it. We also specify the version for our application (&lt;code&gt;addDependsOn&lt;/code&gt;), which is unique for the uploaded source files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create VPC stack and connect all the stacks
&lt;/h2&gt;

&lt;p&gt;VPC is like a private network in the scope of our services that can communicate with each other. Any database in AWS must always be created in the scope of some VPC, so let's define a stack for that. Create a file called &lt;code&gt;lib/vpc-stack.ts&lt;/code&gt;. This one will be pretty short:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/aws-ec2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;VpcStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Vpc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Vpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VPC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have created a new, default VPC instance and assigned it to &lt;code&gt;vpc&lt;/code&gt; property on &lt;code&gt;VpcStack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, as we have all of the parts ready, we can connect it by creating an executable stack in &lt;code&gt;bin/infrastructure-stack.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EbsStackProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EbsStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/ebs-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CredentialsStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/credentials-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RdsStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/rds-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VpcStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/vpc-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vpcStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;VpcStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VpcStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vpcStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credentialsStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CredentialsStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CredentialsStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rdsStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;RdsStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RdsStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;credentialsStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rdsStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgreSQLinstance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ebsEnvironment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EbsStackProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;dbCredentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;credentialsStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;credentialsStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;dbHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instanceEndpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;dbPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5432&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EbsStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EbsStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ebsEnvironment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import all of our custom stacks and create instances of &lt;code&gt;VpcStack&lt;/code&gt; and &lt;code&gt;CredentialsStack&lt;/code&gt;. Then we can create a new database instance using the &lt;code&gt;RdsStack&lt;/code&gt;. Do not forget to pass VPC and credentials as props. We can then create an &lt;code&gt;EbsStack&lt;/code&gt; instance and pass every environment variable for the database connection.&lt;/p&gt;

&lt;p&gt;With some luck, running &lt;code&gt;yarn build &amp;amp;&amp;amp; cdk deploy --all&lt;/code&gt; will have your application packaged and deployed to CloudFormation. In there, you can verify that ElasticBeanstalk and RDS services were created and are running correctly.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and feel free to contact me!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>node</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Introduction to State Machines with XState and React</title>
      <dc:creator>Jakub Skoneczny</dc:creator>
      <pubDate>Fri, 13 Nov 2020 19:57:25 +0000</pubDate>
      <link>https://forem.com/skona27/introduction-to-state-machines-with-xstate-and-react-7nd</link>
      <guid>https://forem.com/skona27/introduction-to-state-machines-with-xstate-and-react-7nd</guid>
      <description>&lt;h1&gt;
  
  
  My first online course on Udemy
&lt;/h1&gt;

&lt;p&gt;I have recently made a course about creating state machines with XState and using it inside React apps.&lt;/p&gt;

&lt;p&gt;State machines with XState is a fresh topic for Frontend development, which allows us to better manage applications state.&lt;/p&gt;

&lt;p&gt;If you are new to finite state machines' concepts or if you have ever heard about state machines, but you have no clue what is that about, then go and check on this course.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://www.udemy.com/course/introduction-to-state-machines-with-xstate-and-react"&gt;https://www.udemy.com/course/introduction-to-state-machines-with-xstate-and-react&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample coding video with Video Player component
&lt;/h2&gt;

&lt;p&gt;I also present a sample coding video from this course in which I code a Video Player component with a cool autoplay option. Video is to be seen on Youtube. Link below:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ym8TQ8nLxuY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I really appreciate all kinds of feedback! Reviews and comments are welcome :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>xstate</category>
      <category>udemy</category>
    </item>
  </channel>
</rss>
