<?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: Leo Melo</title>
    <description>The latest articles on Forem by Leo Melo (@leomeloxp).</description>
    <link>https://forem.com/leomeloxp</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%2F3614%2F66243d5e-1429-44c3-a685-63fca0ba54ce.jpg</url>
      <title>Forem: Leo Melo</title>
      <link>https://forem.com/leomeloxp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/leomeloxp"/>
    <language>en</language>
    <item>
      <title>Lessons learned from messaging strangers on the internet</title>
      <dc:creator>Leo Melo</dc:creator>
      <pubDate>Mon, 07 Aug 2023 15:17:07 +0000</pubDate>
      <link>https://forem.com/leomeloxp/lessons-learned-from-messaging-strangers-on-the-internet-2m57</link>
      <guid>https://forem.com/leomeloxp/lessons-learned-from-messaging-strangers-on-the-internet-2m57</guid>
      <description>&lt;p&gt;This post is based on a talk I gave at the &lt;a href="https://geeksessions.io/"&gt;Geek Sessions&lt;/a&gt; meet-up in Faro, Portugal 🇵🇹 on the 28th of June, 2023.  The full title for this talk was &lt;em&gt;"Lessons learned from messaging strangers on the internet in a language I did not speak"&lt;/em&gt; and the idea here is to draw some parallels between the idea of learning new (spoken) languages and learning new skills in technology.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c5nc04hp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0170xrfrgrvdgx5dml1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c5nc04hp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0170xrfrgrvdgx5dml1.jpg" alt="If we can't talk to strangers, how can we make friends?" width="400" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back in June 2020 I was very bored and in lockdown, like most folks, and decided that I needed to learn something in order to keep sane. Being the language nerd that I am I decided I was going to learn Spanish.&lt;/p&gt;

&lt;p&gt;Since I couldn't just learn the basics and then take a two week holiday somewhere in Spain to practice I needed to decide how I was going to approach it before I could get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zXD0GTF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nutitqusb64j7t3amodd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zXD0GTF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nutitqusb64j7t3amodd.jpg" alt="I have a plan!" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I am a native speaker of Brazilian Portuguese I thought this was going to be a quick and easy exercise. Just how I thought the pandemic and the lockdowns would be over before the end of summer or by halloween. Boy was I wrong...&lt;/p&gt;

&lt;p&gt;So my idea was simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'd exchange at least 50 messages a day with a number of people using language learning chatting apps&lt;/li&gt;
&lt;li&gt;Watch videos in Spanish with Spanish subtitles. Money Heist taught a great Italian song (and some Spanish too!)&lt;/li&gt;
&lt;li&gt;Start listening to music, and later podcasts, in Spanish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Armed with a sound plan and a fool's confidence, I set my target language to Spanish in HelloTalk and got to work!&lt;/p&gt;

&lt;h2&gt;
  
  
  How did it go?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Gow_ouR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2387k2dccp0q1j8h1e1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Gow_ouR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2387k2dccp0q1j8h1e1.png" alt="Risitas, a Spanish comedian, looking troubled" width="400" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As it turns out, knowing Portuguese didn't help nearly as much as I thought it would. Brazilian Portuguese has a much simpler grammatical structure, which meant that whilst I could read messages and take a second to understand which grammar tense was being used, I couldn't really keep up with people's audio messages or Youtube videos and series.&lt;/p&gt;

&lt;p&gt;Added to that, whilst there's an overlap of about 90% of vocabulary between the two languages, this overlap doesn't help as much as you'd think. Some words have slightly different meanings, have fallen out of fashion in one language or the other, or just sound straight up embarrassing and you didn't even know it.&lt;/p&gt;

&lt;p&gt;I was always looking words up on either &lt;a href="https://spanishdict.com"&gt;SpanishDict&lt;/a&gt; or using Google Translate, DeepL and the apps' builtin translation tools.&lt;/p&gt;

&lt;p&gt;After about 6 months I was already better at writing and didn't need to rely so much on SpanishDict for verb conjugations of regular verbs and the most common irregulars like &lt;em&gt;ser&lt;/em&gt;, &lt;em&gt;estar&lt;/em&gt;, &lt;em&gt;ver&lt;/em&gt; and a few others.&lt;/p&gt;

&lt;p&gt;At about the 9 to 12-month mark I started being able to speak a few sentences without having to write them down first. My accent was horrible but at least I was able to alternate between audio and written messages during my practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KHgmHPOq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d8xrlufy5mphrqggiv6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KHgmHPOq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d8xrlufy5mphrqggiv6.gif" alt="Berto Romero smiling and waving his hand as if he was celebrating" width="498" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After about 18 months I started to recall things quicker, expressing myself and having more in-depth conversations with others become much easier. I no longer needed subtitles and became able to listen to audiobooks and podcasts, some even at 1.5 or 2 times the normal playback speed.&lt;/p&gt;

&lt;p&gt;Around this same time I also started to develop a kind of intuition for verb conjugations I didn't know, and was able to use some of the less common verb conjugations in speech without the need to look them up in a dictionary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2SXNZF3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvpu7gufqvoyjnmu5ol9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2SXNZF3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvpu7gufqvoyjnmu5ol9.jpg" alt="Chihuahua wearing a sombrero" width="400" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About three years into this learning journey my language level has oscillated between a good &lt;a href="https://en.wikipedia.org/wiki/Common_European_Framework_of_Reference_for_Languages#Common_reference_levels"&gt;B2&lt;/a&gt; and an acceptable B1.&lt;/p&gt;

&lt;p&gt;I've had the opportunity to travel to Spain a few times and spend time there with friends speaking mostly Spanish for a number of days in a row each time. After being in a Spanish speaking environment for about a day I am very much back at my best.&lt;/p&gt;

&lt;p&gt;My accent is still inconsistent, I'll very quickly start mirroring whichever accent is spoken around me and then use expressions and vocabulary that may not be as common or native to where I am, e.g. using Mexican or South American words whilst speaking to a Spanish person.&lt;/p&gt;

&lt;p&gt;I don't mind this as much as I used to, I would like to have a more consistent accent but I've come a long way and I feel like I have achieved way more than what I had originally set out to achieve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallels between skilling up in technology and learning a spoken language
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HKwyBVmE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dtb1zfjn11176qabb2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HKwyBVmE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dtb1zfjn11176qabb2h.png" alt="Spidermen pointing at one another meme" width="400" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that I've given some context of my learning journey, let's shift our attention to some of the things I've identified in my process that could also be used to improve our experience when learning new skills in tech.&lt;/p&gt;

&lt;p&gt;Learning can be a very personal experience and different people will have different ways in which they prefer to acquire new skills, for the purposes of my talk I chose to focus on a few more general points in order to try and make it as useful and relatable to as many people as possible. These are the five points I want to touch on:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Identify your goals
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jbwtYKDa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9l4mcu35r0shb99a7q8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jbwtYKDa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9l4mcu35r0shb99a7q8.jpg" alt="A football goal" width="400" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before you start you should identify your goals, this will help you with checking in on your progress along the way. These are a few of the questions you can ask yourself to try and understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do you want to do with this new skill?&lt;/li&gt;
&lt;li&gt;How will you know when you've achieved it?&lt;/li&gt;
&lt;li&gt;How strict are you about those answers?&lt;/li&gt;
&lt;li&gt;Will there be a next level after you're done with this one?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions are not comprehensive but should be a great starting point. I find it specially useful to know how flexible I can be with the goal as I progress and how well documented my goal setting needs to be.&lt;/p&gt;

&lt;p&gt;For professional goals we're usually required to have a more detailed description and be more strict with our definition of done. Personal goals can go from a mental note to a full blown schedule, depending on what it is that you're aiming for.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Take small steps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AS3wVOZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/90xgq08g5zo46dwo59f4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AS3wVOZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/90xgq08g5zo46dwo59f4.jpg" alt="Accomplish your goals one small step at a time" width="400" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you've determined what the end of the journey should look like, let's go back to the start. For almost any skill in technology it pays off to really understand the foundations of what you're learning—you should learn to walk before you try to run.&lt;/p&gt;

&lt;p&gt;If you're learning a programming language you should focus on the basics of its syntax and peculiarities first, e.g. understand the basics of Rust's ownership system, or Javascript's asynchronous nature.&lt;/p&gt;

&lt;p&gt;It's also a good idea to start with some tutorials or books that will walk you through these basics and then start to experiment with the simpler examples that you see, exploring things in your own way.&lt;/p&gt;

&lt;p&gt;If you're trying to learn a new skill that is more role specific, like DevOps, then perhaps  you can start with understanding the basics of Docker, Kubernetes and what it takes to deploy a "hello world" style app using such technologies. The main goal at this point is to start small so you can find your pace. Learning shouldn't be overwhelming, nor boring.&lt;/p&gt;

&lt;p&gt;After the talk we had a small QA session and one of the questions was about how can we know whether we're doing too much or too little when trying to learn. A good analogy I came up with for the case of spoken languages was: if you're dreaming in your target language, you're good, if you start losing sleep over it then it is too much.&lt;/p&gt;

&lt;p&gt;I don't expect anyone to measure their learning effort of Rust or Haskell by how much they dream about these languages but this is still a good analogy in terms of the levels of exposure to the thing you're trying to learn and how much you should make it a part of your daily life.&lt;/p&gt;

&lt;p&gt;This takes us to the next point...&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Practice regularly and immerse yourself in the technology
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hUSxF6Ia--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytp8sdsm5yop9v0824gy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hUSxF6Ia--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytp8sdsm5yop9v0824gy.gif" alt="Practice regularly" width="593" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to learn a new skill effectively you need to be able to incorporate as much practice as possible into your daily life. In the case of spoken languages this is obvious and easier to define. You should be listening to music, watching videos in the target language and speaking to natives or fluent speakers of that language as much as possible. For technology things can be a little bit trickier.&lt;/p&gt;

&lt;p&gt;It is unlikely that you'll be able to get a job utilising a skill that you've just started to learn when it comes to tech, in order to counter that you'll have to find other ways to immerse yourself into the tech area you're trying to learn.&lt;/p&gt;

&lt;p&gt;The most obvious way to get exposure to the thing you're learning is by practising it. Building low stakes projects will be the most effective way to achieve this as you can try different things out without running the risk of having a bigger impact on things around you. Then after that I would recommend listening to podcasts, reading blog posts, books, developer documentation, watching conference talks (online and in-person if possible), joining communities online around the topic that you're trying to learn (more on this later).&lt;/p&gt;

&lt;p&gt;These are all great options and you should try and mix and match them as and when you can, so long as you incorporate some kind of daily practice on your routine you will see the value in this effort in no time.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Embrace your mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WhnsiziS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6up7z399qwutb4qtf8qh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WhnsiziS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6up7z399qwutb4qtf8qh.jpg" alt="Happy little accidents" width="400" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mistakes are a very natural part of learning. Regardless of whether we're just getting started or have been practising for a little while, it's obvious that we will make many mistakes along the way. You should learn to be comfortable with your mistakes early on, in order to avoid frustrations.&lt;/p&gt;

&lt;p&gt;As briefly alluded to in my previous point, having low stakes settings for your practice is one way to help you be more comfortable with making mistakes. Another point that is worth noting is that mistakes can also be used to give us more perspective on what we're learning.&lt;/p&gt;

&lt;p&gt;Whenever you make a mistake, be it one that makes it so your code doesn't compile or something that someone else is telling you shouldn't be done in that way you can ask yourself why is it that this is not how it should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did you break a hard rule by making a syntax error or referencing a variable or file that doesn't exist?&lt;/li&gt;
&lt;li&gt;Did you not follow best practice and are now running into unexpected behaviour?&lt;/li&gt;
&lt;li&gt;Did you rely on a feature of the language you're learning that you didn't fully understand and now don't know why it isn't doing what you hoped it would?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mistakes in programming and other aspects of technology can come in different shapes and forms but they're a great way to help us understand what it is that we're lacking in terms of knowledge so that we can work to fill that gap.&lt;/p&gt;

&lt;p&gt;Another great way to use our mistakes as a positive part of our growth is by having a mentor or community that can help you to keep moving when you're struggling to understand something or to get it to work as intended, this takes us to the last point I want to touch on...&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The importance of focused communities
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NT6xR1H1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jm2fqxsdjwxxopm5rs7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NT6xR1H1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jm2fqxsdjwxxopm5rs7z.png" alt="Come to the dark side, we have cookies!" width="400" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There will always be other learning or using the same things you're trying to learn, if you can find a good group of people to learn with or at least exchange some of your experiences the synergy it creates can drastically improve your learning journey. Furthermore, by participating in communities you will likely start to meet people that could eventually help you on a professional level too, or that you may be able to help them.&lt;/p&gt;

&lt;p&gt;I strongly recommend trying to find local communities for this as well, for offline meet-ups and events. These will usually have an online side to them but being able to get together and meet people, join hackathons or other events where you also get to do things alongside others can really help the immersion part of learning.&lt;/p&gt;

&lt;p&gt;Another, possible less obvious, benefit of being part of more focused communities is that it helps with staying motivated. Very often in our lives things will happen that will force us to set things aside for a short period of time or  deprioritise something in favour of a more pressing issue. When this happens, being part of a community and attempting to stay active will serve as a reminder of your learning journey and how you should continue to try and learn as much as your available time allows.&lt;/p&gt;

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

&lt;p&gt;That's it! I understand that this is by far not a comprehensive list but I hope it helps you when you next try to learn something from scratch or even on your current learning journey.&lt;/p&gt;

&lt;p&gt;You can find the slides for my original talk &lt;a href="https://lessons-from-messaging-strangers-talk.leomeloxp.dev/"&gt;in here&lt;/a&gt; and the source code for the slides &lt;a href="https://github.com/leomeloxp/lessons-from-messaging-strangers-talk"&gt;on my Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Share in the comments below what sort of techniques or tips you keep coming back to when learning and what you are trying to learn now. Me, I'm currently trying to learn more of the Rust programming language, as it's a compiled, lower level, language and I've never really done anything with compiled languages before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kYQw2sZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sba2jwg4w4li885e1nhu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kYQw2sZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sba2jwg4w4li885e1nhu.gif" alt="Speedy Gonzales dancing" width="498" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Taking React and Redux to the next level with Typescript</title>
      <dc:creator>Leo Melo</dc:creator>
      <pubDate>Mon, 02 Sep 2019 18:26:32 +0000</pubDate>
      <link>https://forem.com/leomeloxp/taking-react-and-redux-to-the-next-level-with-typescript-1m84</link>
      <guid>https://forem.com/leomeloxp/taking-react-and-redux-to-the-next-level-with-typescript-1m84</guid>
      <description>&lt;h2&gt;
  
  
  Prologue
&lt;/h2&gt;

&lt;p&gt;If you ever used Redux before you know that much of the ways we write Redux logic and why it works relies on us knowing the shape of our state ahead of time. That need is very much inline with how good typescript code forces us to define the shape of our functions and variables before we can build the output JavaScript code.&lt;/p&gt;

&lt;p&gt;As I'll be making heavy use of Redux in the near future and I haven't done much with it for some time, I decided to go through Level Up Tutorials' (LUT) React and Redux For Everyone course to refresh my memory on the many concepts around Redux. To add some spice to it, and because I love TS, this time I decided I'd write the tutorial app in Typescript.&lt;/p&gt;

&lt;p&gt;This post is a collection of thoughts and highlights of my experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some example code
&lt;/h2&gt;

&lt;p&gt;You can see the code for the course, and each step of my way via git tags, on &lt;a href="https://github.com/leomeloxp/lut-react-redux-typescript"&gt;my github&lt;/a&gt;. I've also created a &lt;a href="https://codesandbox.io/s/59sp8"&gt;CodeSandbox&lt;/a&gt; which contains a minimal setup for &lt;code&gt;react-redux&lt;/code&gt; and a connected component using Typescript.&lt;/p&gt;

&lt;p&gt;You're free to look through them or use them as inspiration for your own code. I'll mostly use the repo on Github here to illustrate some points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the global state and root reducer
&lt;/h2&gt;

&lt;p&gt;In my repo I had two reducers being merged by &lt;code&gt;combineReducers&lt;/code&gt;, their state is defined as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;movies&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxMoviesState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMovie&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;moviesLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;moviesLoadedAt&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;IMovie&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;movieLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;ul&gt;
&lt;li&gt;
&lt;code&gt;toggle&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxMessageState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;messageVisibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;With our reducers returning each of these states, we can define the global app state like:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;movies&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;type&lt;/span&gt; &lt;span class="nx"&gt;AppState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the &lt;code&gt;AppState&lt;/code&gt; look like:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AppState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IReduxMessageState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IReduxMoviesState&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;This is great because everywhere our redux state is used, we know exactly what it looks like and what we can reference from it when connecting components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining action creators and action type constants
&lt;/h2&gt;

&lt;p&gt;It's common practice in Redux to have action types being defined as constants. Because we're using Typescript, we can make use of enums and extending interfaces to make our code more descriptive. In my repo I have the following enum for action types:&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;export&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;GET_MOVIE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_MOVIE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GET_MOVIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_MOVIES&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;RESET_MOVIE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET_MOVIE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TOGGLE_MESSAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TOGGLE_MESSAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're familiar with Typescript you'll see that I made the enums have defined values. This is to avoid the enum keys being assigned numerical values which could possibly make the code less resilient. Either way, this will make defining our action creators a little easier.&lt;/p&gt;

&lt;p&gt;I defined the actions basing myself on an interface with a more generic &lt;code&gt;type&lt;/code&gt; value, it is pretty bare bones but it allows for great scalability:&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;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxBaseAction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&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;For example, in the case of the movies reducer, there are a few different actions that can be dispatched:&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;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxGetMoviesAction&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IReduxBaseAction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GET_MOVIES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMovie&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxGetMovieAction&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IReduxBaseAction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GET_MOVIE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMovie&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReduxResetMovieAction&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IReduxBaseAction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RESET_MOVIE&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;As with many things in Typescript, you don't need to know how the values for data are defined, all you need to know in this case is that each action will contain the correct type of object or array for the &lt;code&gt;data&lt;/code&gt; property of our action.&lt;/p&gt;

&lt;p&gt;By aggregating those types into a union type, I can write my movies reducer like the 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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TMoviesReducerActions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IReduxGetMoviesAction&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;IReduxGetMovieAction&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;IReduxResetMovieAction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&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;IReduxMoviesState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TMoviesReducerActions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GET_MOVIES&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;moviesLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;moviesLoadedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GET_MOVIE&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;movieLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;EReduxActionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RESET_MOVIE&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;movieLoaded&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="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&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;This reducer is one of my favourite parts of this TS and Redux implementation.&lt;/p&gt;

&lt;p&gt;Because I use different values of &lt;code&gt;EReduxActionTypes&lt;/code&gt; for each action. when I get &lt;code&gt;action.data&lt;/code&gt; within the different &lt;code&gt;case&lt;/code&gt;'s, Typescript already knows that data is of the correct type, i.e. &lt;code&gt;Imovie&lt;/code&gt; for &lt;code&gt;IReduxGetMovieAction&lt;/code&gt; and &lt;code&gt;IMovie[]&lt;/code&gt; (an array of movies) for &lt;code&gt;IReduxGetMoviesAction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a VERY POWERFUL THING.&lt;/p&gt;

&lt;p&gt;In my tutorial app, the reducers are fairly simple but we can already see that scaling this wouldn't be much of an issue and wouldn't really increase the complexity of our store that much.&lt;/p&gt;

&lt;p&gt;This is specially true if we take into account the excellent developer experience that VS Code offers to us for Typescript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting components and using our store's state
&lt;/h2&gt;

&lt;p&gt;To connect our &lt;code&gt;movies&lt;/code&gt; state with a &lt;code&gt;MoviesList&lt;/code&gt; component, the code used is as follows:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&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;AppState&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="na"&gt;movies&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;movies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;isLoaded&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;movies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moviesLoaded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;moviesLoadedAt&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;movies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moviesLoadedAt&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;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AnyAction&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;bindActionCreators&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;getMovies&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;dispatch&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;MoviesList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's quite a bit of code and re-assignment of values in here. Usually this could lead to some confusion as to which props are going to be available to our &lt;code&gt;MoviesList&lt;/code&gt; component but Typescript will make sure that doesn't happen by letting us parse the type definitions of &lt;code&gt;mapStateToProps&lt;/code&gt; and &lt;code&gt;mapDispatchToProps&lt;/code&gt; and use it when creating our component:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MoviesList&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;PureComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&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="c1"&gt;// Code for the component goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could even simplify things slightly by creating a &lt;code&gt;MoviesList&lt;/code&gt; props type like so:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TMoviesListProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MoviesList&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;PureComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TMoviesListProps&lt;/span&gt;&lt;span class="p"&gt;,&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="c1"&gt;// Code for the component goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we try to reference anything from &lt;code&gt;this.props&lt;/code&gt; inside our component, we will have full visibility of all the properties supplied to us by &lt;code&gt;mapStateToProps&lt;/code&gt; and &lt;code&gt;mapDispatchToProps&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Even though managing state with Redux and following its standard practices can lead us to spread logic through a number of files and/or add, an arguably large, amount of boilerplate code. By making use of Typescript, we can greatly increase the readability of our code and likely make it easier for anyone that may not be as aware of the ins and outs of a complex application, what each of its parts is responsible for and what they expect to receive from other components.&lt;/p&gt;

&lt;p&gt;The tutorial application may not be the most complex one and maybe I didn't make the most elaborate use of Typescript. I still would like to think that it highlights some of Typescript's power and why more and more people are starting to look into it recently.&lt;/p&gt;

&lt;p&gt;What do you think about Typescript and how it can change our developer experience when creating and scaling applications? Feel free to comment below or reach out to me on social media, details can be found on my website: &lt;a href="https://www.leomeloxp.dev"&gt;leomeloxp.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One last thing. When writing this app I tried to keep the code as close to the original code written in LUT's React and Redux for Everyone course as possible. If you like to learn more about the course or Level Up Tutorials in general feel free to visit their &lt;a href="https://www.leveluptutorials.com/"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post was not sponsored by Level Up Tutorials, I just really like their content.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What is JAM Stack</title>
      <dc:creator>Leo Melo</dc:creator>
      <pubDate>Sun, 13 May 2018 13:57:01 +0000</pubDate>
      <link>https://forem.com/leomeloxp/what-is-jam-stack-2957</link>
      <guid>https://forem.com/leomeloxp/what-is-jam-stack-2957</guid>
      <description>&lt;p&gt;This post was based on a talk I gave at a local web development meetup in Jersey 🇯🇪 on May 4th, 2018. Enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  JAM Stack
&lt;/h2&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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fstack-of-jam.jpg" 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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fstack-of-jam.jpg" alt="A stack of jam tubs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JAM stands for &lt;em&gt;&lt;strong&gt;Javascript, API and Markup&lt;/strong&gt;&lt;/em&gt;, an acronym with a nested acronym. 🤓 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;jamstack.org&lt;/a&gt; defines JAM as &lt;em&gt;modern web development architecture based on client-side JavaScript, reusable APIs, and pre-built Markup.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Defining what JAM means doesn't really gives us enough depth though, is there any secret behind it?&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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fsecret-stuff.jpg" 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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fsecret-stuff.jpg" alt="Michael Jordan looking disappoint at my bad puns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at the file structure for an example JAM website:&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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fjam-code.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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fjam-code.png" alt="Screenshot of a file tree containing an index.html, style.css and script.js files"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, there's no magic behind it. Just a set of files that we're all used to seeing in the front-end aspects of our projects&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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fsecret-stuff-gone.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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fsecret-stuff-gone.gif" alt="Bugs bunny holding a bottle with "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on that file structure some could even try to argue that &lt;a href="https://www.warnerbros.com/archive/spacejam/movie/jam.htm" rel="noopener noreferrer"&gt;Space Jam's website&lt;/a&gt; is a JAM site (spoiler: it isn't, it doesn't even use CSS 😂).&lt;/p&gt;

&lt;p&gt;What makes JAM so useful for us is on its Javascript and API aspects&lt;/p&gt;

&lt;p&gt;Javascript + API = &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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fbugs-bunny.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%2Frawgit.com%2Fleomeloxp%2Fjam-stack-talk%2Fmaster%2Fsrc%2Fassets%2Fbugs-bunny.gif" alt="Animated gif of bugs bunny showing his muscles in a hyperbolic way"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we look at one example of a JAM website built using &lt;a href="https://www.gatsbyjs.org/" rel="noopener noreferrer"&gt;Gatsby JS&lt;/a&gt;, &lt;a href="https://rach.io/store/" rel="noopener noreferrer"&gt;Rachio Smart  Sprinkler&lt;/a&gt;, we can see that for the end user, there are no immediate visual changes, this website is statically built and still offer full ecommerce and checkout journeys, with the help of APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should I give myself the trouble?
&lt;/h2&gt;

&lt;p&gt;Even if the end user won't really have any immediate advantages, there are a number of reasons that will encourage you to consider the JAM approach on your next project. Let's visit some of them:&lt;/p&gt;

&lt;h3&gt;
  
  
  Load speeds
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No database querying&lt;/strong&gt;: As your website's markup is built on build time, there is no database queries being done at every page request. This saves both on server load as well as overall response times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No template parsing&lt;/strong&gt;: Depending on your stack, chances are you have a template file in your code base that gets parsed and is used to build the HTML that gets sent back to the browser on every page request. With a static site that wouldn't happen, meaning you can also save on server loads and response time by taking this aspect out of the request/response flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separation of concerns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Front-end takes care of all presentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With front-end frameworks increasing in popularity and capabilities, having your website/application's presentation decoupled from any backend framework means you can harness all the power that your front-end stack gives you, and in turn deliver a better experience to your end users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralised/focused UX design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Equally relevant, if you don't need to worry about how the backend of your application handles its data and business logic, you can focus more of your efforts ensuring that your user experience is at the level you want and your end users expect, without have any potential constraints imposed by backend solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frequency of content update
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;How often do we really update ALL our pages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a point that is very often overlooked. For a number of our pages, content is rarely ever updated, eg contact pages, terms and conditions, blog posts. &lt;/p&gt;

&lt;p&gt;You may update such pages a few times soon after they're published to fix potential typos or inconsistencies but once that period is gone chances are you will never edit that page again so why not have it statically built and save your server the hassle of having to compile this page on every request?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frequently changing content can use APIs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have pages that still need to provide dynamic or time sensitive content, you can use APIs to update that content once the page has loaded and maybe cache that content on the client-side or (less optimal) include that content after the page has loaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  No need to implement everywhere
&lt;/h3&gt;

&lt;p&gt;There is no need to move your entire application to JAM all at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JAM Stack your blog&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As mentioned above, certain pages are less likely to change after they've been published so making them static would provide you with increased performance and better experience for end users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User authenticated areas could remain non-JAM'd&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your application has some sort of authenticated area where things need to be kept dynamic, you can skip that section when &lt;em&gt;JAM'ing&lt;/em&gt; your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Progressive migration to JAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The takeaway from this section is that you can slowly migrate your content to a static build, and bring in more API backed dynamic content as you identify the opportunities in your application for a JAM approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tie in with service workers, SPA's and animated page transitions
&lt;/h3&gt;

&lt;p&gt;JAM stack makes it easier for us to include new web workflows onto our applications, such as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" rel="noopener noreferrer"&gt;Service Workers&lt;/a&gt;, single page application frameworks and animated transitions between pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offline support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With service workers you can make some or all of your website's content available to users when they're offline. This is a great feature, but specially important if your core market involves tourists or users with less than optimal internet connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push update to service workers on build time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I said earlier some pages would rarely change their content after being published, but when they do, you can use service workers to revalidate your content based on your needs. This will ensure your end users always have the most relevant content on their devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Page transitions make UX sleek (like on native apps)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This may not seem like a key feature of static and JAM based sites, but if you take a moment to think about how nice some native apps transitions between their different areas, it is really exciting to think that we can do the same on a web based application. See &lt;a href="https://t.co/pr1NhYseRK" rel="noopener noreferrer"&gt;Sarah Drasner&lt;/a&gt;'s &lt;a href="https://page-transitions.com/" rel="noopener noreferrer"&gt;page transitions&lt;/a&gt; example if you need some inspiration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Lastly, caching a statically built site is even more efficient than a dynamic one as you can cache all aspects of your site and depending on your content type your cache can be set to extremely long expiry dates.&lt;/p&gt;

&lt;p&gt;For any portions of your site that need to be dynamic, you can use the Javascript and APIs aspect   of JAM to pull in content after the page has loaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;p&gt;As with most things in our area, there can also be trade-offs or at least things that you should keep in mind when crafting your JAM based application.  I already touched on these above but for the purpose of having all of these under one section, a few caveats to consider when building JAM apps are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-commerce and extremely time sensitive content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your content is extremely time sensitive and relies heavily on a backend solution, JAM may not be the best option. One way to circumvent this would be to use APIs to update the content on the front-end, but this may not be possible all the time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Must implement SSR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many reasons behind this, but it's always recommended that you implement some sort of server side rendering logic at least at build time, for your content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ensure no JS support if relevant and SEO best practices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know this may sound a bit dated, but implementing no JS support can be very relevant depending on your target audience or the percentage of users you want to deliver your application to. It's worth mentioning that no JS support could be slightly limited when compared to the full application, but it's important to give no JS users at least some sort of consistent experience.&lt;/p&gt;

&lt;p&gt;Depending on the type of website or application you will also want to ensure that you're covering your grounds in terms of SEO. Having a great website could mean nothing if no one can find out about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authenticated areas of your app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authenticated areas of your site may not always be compatible with the JAM approach. Again, APIs can help you here, but it's up to you to make that call for each individual case.&lt;/p&gt;

&lt;p&gt;A few suggestions on this would be to SSR the chrome of your site, and maybe add some placeholder markup to indicate that the user specific content is still being fetched with AJAX/APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I join the JAM Stack hype train?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QgRkEgibQp65q/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QgRkEgibQp65q/giphy.gif" alt="Station officers pushing people into a crowded train"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have seen some pros and cons of JAM, you may want to try it out for yourself. There are plenty of ways you can build a JAM based website and most of these have some sort of static site feeling to them.&lt;/p&gt;

&lt;p&gt;I compiled a list with some options you could try, but this is by no means a comprehensive list, just things that I came across or used myself in the past.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;React JS&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React is probably the most widely used front-end framework these days and if you know React you probably know all these options. Either way, these are a few tools that you can use to build a JAM stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;create-react-app&lt;/a&gt;: Great zero config React application scaffolder with the possibility to &lt;em&gt;eject&lt;/em&gt; your app once more custom features are needed.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gatsbyjs.org/" rel="noopener noreferrer"&gt;GatsbyJS&lt;/a&gt;: A static site generator for React with a built in GraphQL data layer and the ability to built static HTML from your React components on build time.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;: A framework for server-rendered React applications with support for static sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://vuejs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Vue.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue is also a front-end framework that has been increasing in popularity and adoption very quickly. If you're using Vue, these are a few of the tools you can use to build JAM apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;Nuxt&lt;/a&gt;: Universal Vue JS application framework, often said to be the Vue equivalent of Next.js,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vuepress.vuejs.org/" rel="noopener noreferrer"&gt;VuePress&lt;/a&gt;: Static site generator for Vue.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Zulko/eagle.js" rel="noopener noreferrer"&gt;eagle.js&lt;/a&gt;: A hackable slideshow framework built with Vue.js (used to create my talk's slides 🤓).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other options&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt;: Ruby based static site generator, widely used for &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;: Go lang based static site generator.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.staticgen.com/" rel="noopener noreferrer"&gt;StaticGen&lt;/a&gt;: StaticGen offers a list of static site generators that you can sort and filter based on your preference or needs.&lt;/li&gt;
&lt;li&gt;Build your own: &lt;a href="https://en.wikipedia.org/wiki/Not_invented_here" rel="noopener noreferrer"&gt;NIH syndrome&lt;/a&gt; aside, if you have a very specific set of features that you require, you can always build your own static markup and integrate it with your APIs in a way that suits your business and needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  JAM friendly backend solutions?
&lt;/h2&gt;

&lt;p&gt;One other important aspect of JAM stack is ensuring that your backend solutions integrate well with front-end frameworks and provide APIs that you can harness from the front-end/client-side of your application. A few examples of frameworks and services that can help you with that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headless WordPress: Using WordPress as your CMS doesn't necessarily mean you need to use it to generate your website's markup directly. API-first/Headless WordPress is something that is increasing in popularity and plugins and libraries to help you get started are out there.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.netlifycms.org/" rel="noopener noreferrer"&gt;Netlify CMS&lt;/a&gt;: A file based CMS that can plugin in directly into your version control and build workflow.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prerender.io/" rel="noopener noreferrer"&gt;Prerender&lt;/a&gt; : SEO friendly plugin to your application that ensures your website can be crawled correctly by search engines&lt;/li&gt;
&lt;li&gt;Your current framework of choice: This may not be as obvious for all CMS/frameworks but chances are you can already build a JAM website and integrate with your current backend solution, possibly by using REST and/or GraphQL.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Thanks for reading my post. JAM stack is awesome and I believe it's the most efficient way forward for us. When you get to your next project, consider giving JAM stack a try, or maybe consider rebuilding portions of your current set up using JAM, you won't be disappointed. 😉&lt;/p&gt;

&lt;p&gt;There are probably tons of things that I didn't talk about (and consequentially are not part of this post), feel free to mention things I may have missed in the comments.&lt;/p&gt;

&lt;p&gt;Some inspiration for my talk was taken from another &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt; post on JAM Stack and I recommend you check it out:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/lauragift21" 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%2F19000%2Fc8919037-c4bc-41d7-9c9c-4230dfd51f74.gif" alt="lauragift21"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/lauragift21/what-is-jamstack-and-why-you-should-try-it-5f8h" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;What is JAMstack and why you should try it&lt;/h2&gt;
      &lt;h3&gt;Gift Egwuenu ・ Apr 16 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#jamstack&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#staticsites&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#netlify&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;The slides for my talk can be seen &lt;a href="https://leomeloxp-jam-talk.netlify.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, you can also check out the &lt;a href="https://github.com/leomeloxp/jam-stack-talk" rel="noopener noreferrer"&gt;Github repo with the slides' code&lt;/a&gt;. Cheers 🤓&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gatsby</category>
      <category>react</category>
      <category>vue</category>
    </item>
    <item>
      <title>Hi, I'm Leo Melo</title>
      <dc:creator>Leo Melo</dc:creator>
      <pubDate>Sun, 02 Apr 2017 09:59:36 +0000</pubDate>
      <link>https://forem.com/leomeloxp/hi-im-leo-melo</link>
      <guid>https://forem.com/leomeloxp/hi-im-leo-melo</guid>
      <description>&lt;p&gt;Hi ðŸ¤“&lt;/p&gt;

&lt;p&gt;I have been coding for over 5 years, mostly web development involving PHP and many aspects of front and backend JavaScript, my favourites probably being: React (Native and Web), Node and three.js. I also really enjoy tinkering with Linux based systems, be it servers or user focused.&lt;/p&gt;

&lt;p&gt;On my free time, apart from more coding I also enjoy gaming, specially JRPGs and Rhythm games and music, from RHCP to Math Rock and a lot of things in between.&lt;/p&gt;

&lt;p&gt;You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/leomeloxp" rel="noopener noreferrer"&gt;Twitter @leomeloxp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/leomeloxp" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See ya o/&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
