<?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: Joe Sak</title>
    <description>The latest articles on Forem by Joe Sak (@joemsak).</description>
    <link>https://forem.com/joemsak</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%2F173172%2F435bae11-0010-4ded-a6f9-6a0bfbf7a403.jpg</url>
      <title>Forem: Joe Sak</title>
      <link>https://forem.com/joemsak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joemsak"/>
    <language>en</language>
    <item>
      <title>Git Rebase Explained and (eventually) Illustrated</title>
      <dc:creator>Joe Sak</dc:creator>
      <pubDate>Mon, 17 Feb 2020 13:33:34 +0000</pubDate>
      <link>https://forem.com/joemsak/git-rebase-explained-and-eventually-illustrated-5hlb</link>
      <guid>https://forem.com/joemsak/git-rebase-explained-and-eventually-illustrated-5hlb</guid>
      <description>&lt;p&gt;Hi there! If you're new to Git, or just don't feel that confident about using it in general, then I hope this post is of use to you. As you can already see, there's a big wall of text here without much in the way of illustrations yet. I'm big on over-providing context; it's kinda My Thing. &lt;/p&gt;

&lt;p&gt;If you feel good enough at Git but just not rebasing, you can safely skip down to Understanding this One Weird Trick about Branches&lt;/p&gt;

&lt;h2&gt;
  
  
  Credit where it's due
&lt;/h2&gt;

&lt;p&gt;Before we get going, I want to give a quick shout out to the book that helped me grasp Git concepts and fundamentals when I first read it 9 years ago: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://pragprog.com/book/pg_git/pragmatic-guide-to-git" rel="noopener noreferrer"&gt;Pragmatic Guide to Git by Travis Swicegood&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you buy that book, you can forget about this post entirely!&lt;/p&gt;

&lt;p&gt;Also shouts outs to front-end development extraordinaire &lt;a href="https://dev.to/dgca"&gt;Dan Cortes&lt;/a&gt; for reviewing this article and helping me polish the finer details. Thanks, Dan!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prologue
&lt;/h2&gt;

&lt;p&gt;You may be someone who has had a particularly bad experience with Git rebase before, with those awful merge conflicts wasting your time and mental energy. Don't worry, I've got tips for making your rebase life easier at the bottom of the post. &lt;/p&gt;

&lt;p&gt;If you're thinking, who cares, I'll just use merge it's easier, well ... fine. You're right. Just use merge and forget about this post. You'll be fine, your team and project will be fine, nothing terrible will happen if you don't learn how to rebase. However, I hope to encourage you to learn a little bit more about the fundamental tool of your work that is Git!&lt;/p&gt;

&lt;p&gt;I've elaborated on this a bit more below, but one issue with always using merge is that it may result in a harder to follow commit history. Having a simpler timeline of changes can go a long way toward alleviating your efforts in the future. For example, if you wanted to isolate a set of changes it is a lot easier when the commits aren't mixed in with unrelated ones, which is what merging instead of rebasing can end up doing to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Glossary of terms
&lt;/h2&gt;

&lt;p&gt;This post assumes you've had some experience with Git and most likely have tried rebase before and hated it and yourself afterward. But even so, I've used some terms in this post that I think are worth defining to avoid leaving beginners in the dust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parent branch&lt;/strong&gt;&lt;br&gt;
The branch you were on when you typed&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch my-branch-name
# or, if you want to switch to 
# your new branch at the same time:
git checkout -b my-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This is the branch you "rebase onto" and "merge into" as it pertains to your child branch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Child branch&lt;/strong&gt;&lt;br&gt;
The branch you are working out of that you want to keep up to date with new changes from some parent branch (almost always the branch you originally stemmed off of in the first place)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull Request&lt;/strong&gt;&lt;br&gt;
A common UI feature of source control web apps, used by teams to allow fellow devs to review your work before merging it into the parent branch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Review&lt;/strong&gt;&lt;br&gt;
Your team reviews the code that you're intending to merge via your pull request&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHA, commit SHA, or SHA-1&lt;/strong&gt;&lt;br&gt;
The 40 character unique hash string that is made for each commit &lt;em&gt;(ex: f4f78b319c308600eab015a5d6529add21660dc1)&lt;/em&gt;. It's actually the name of the algorithm that creates the hash, but devs commonly refer to the string itself as the SHA. Most services usually shorten these, when displaying them, to the first seven characters &lt;em&gt;(ex: f4f78b3)&lt;/em&gt; because that will always be unique enough in a single project. If you need to reference a commit SHA with some Git command, you can use the shortened version and Git won't bat an eye.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;head&lt;/strong&gt;&lt;br&gt;
The latest SHA / commit point of a given branch, tag, or other such Git reference object&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HEAD&lt;/strong&gt;&lt;br&gt;
The currently active head - so a Git repository has multiple heads, but one HEAD&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merge Conflict&lt;/strong&gt;&lt;br&gt;
When you and a teammate make different changes to the same lines of code, Git will have a harder time resolving the changes automatically. Rebase will stop and ask you to resolve the conflicts manually before continuing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploying&lt;/strong&gt;&lt;br&gt;
A team-specific process for getting a desired version of the code onto a remote server environment such as staging(testing by internal staff) or production(seen by actual customers)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please request any other terms used in the post that you'd like me to define, and I will add them!&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Why should I rebase?
&lt;/h3&gt;

&lt;p&gt;I'd love to see more reasons in the commments, but in my experience, rebasing is all about keeping the commits in your branch together and on the top of the commit history for pull request / code review time.&lt;/p&gt;

&lt;p&gt;If you merge when a rebase would be more appropriate, it creates these false merge points in the commit history. When you look back in the list of commits you may not easily be able to pick out only the merge points from approved pull requests, for example. &lt;/p&gt;

&lt;p&gt;Rebasing keeps commits in a logical order and doesn't mix them from one teammate's work all up with yours when your two branches are merged in to the main parent. This makes it a lot easier to follow the history of project features and code changes.&lt;/p&gt;
&lt;h3&gt;
  
  
  When should I rebase?
&lt;/h3&gt;

&lt;p&gt;Basically, whenever there are new changes on the parent branch, and your own child branch hasn't been merged back in yet. Depending on the size of your team and how active they are, you may have to do it every day or multiple times a day. The more often you rebase, the less frequenty you will have trouble with merge conflicts, and the less likely you will be to work on code that became outdated since you created your branch. &lt;/p&gt;

&lt;p&gt;Ultimately, this is something you can trust yourself to feel out over time and develop your own intuition for.&lt;/p&gt;
&lt;h3&gt;
  
  
  When should I merge?
&lt;/h3&gt;

&lt;p&gt;It helps me to think of merge and rebase as commanding different directions for the changes to go. Merge goes from child to parent, or, child merges &lt;strong&gt;into&lt;/strong&gt; parent. Rebase goes from parent to child, or, child rebases &lt;strong&gt;onto&lt;/strong&gt; new commits found on parent(or an entirely different  branch!).&lt;/p&gt;
&lt;h2&gt;
  
  
  Understand this One Weird Trick about Branches
&lt;/h2&gt;

&lt;p&gt;The first thing that I believe will help you understand rebasing better is: &lt;strong&gt;in Git, branches are just text files that say which commit SHA is the newest one for that branch.&lt;/strong&gt; While Git is rebasing, it uses this trick to figure out how to, as you may have seen before, “rewind” your branch and "replay" its commits from a new point.&lt;/p&gt;

&lt;p&gt;Git rebase makes it as if you had branched from the newest commit on the parent, instead of that original commit you were at when you first created your branch. &lt;strong&gt;You are changing your branch's base commit, or, re-basing your branch.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Oh my god dude, this is way more words than I expected, just show me!
&lt;/h2&gt;

&lt;p&gt;Okay. So you're at the latest point of your main branch (main-branch)&lt;/p&gt;

&lt;p&gt;Here we see 3 commits at the top of the history, labeled A, B, C, and "main-branch" is pointing at commit C&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5aw88ppfsbz77imbpkce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5aw88ppfsbz77imbpkce.jpg" alt="3 multicolored dots labeled A, B, C, connected along a horizontal line, and " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you create your branch with&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b new-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;and you see that Git points new-branch also at commit C&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo6akcoolfwlu507rzuka.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo6akcoolfwlu507rzuka.jpg" alt="Same image as before with " width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over time, you add two more commits to new-branch, D &amp;amp; E&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqt03f9bo8dl4w63jbosa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqt03f9bo8dl4w63jbosa.jpg" alt="Similar image as before, but now a branch, connected by a line like the other commit dots, is descending below the main-branch line (still indicated at C), showing commit dots labeled D &amp;amp; E, and " width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And while you were doing that, perhaps you checked out back to main-branch, pulled, and found two new commits. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git checkout main-branch
&amp;gt; git pull
# ... new commits arrive!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This isn't the only method to detect changes on the main-branch, but I don't want to distract you with that right now. &lt;em&gt;(&lt;a href="https://www.atlassian.com/git/tutorials/syncing/git-fetch" rel="noopener noreferrer"&gt;psst. hey. kid. c'mere&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw6k9b36j1af1kchmju4n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw6k9b36j1af1kchmju4n.jpg" alt="Similar image as above but now main-branch has 2 more dots labeled F &amp;amp; G, indicating main-branch at G. new-branch is still indicated below at E" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now it's time for the big moment. You checkout new-branch again and run the rebase command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git checkout new-branch
&amp;gt; git rebase main-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;...and Git does the following behind the scenes (more or less, this is over-simplified on purpose)&lt;/p&gt;

&lt;p&gt;Git looks backward from each branch's head through each commit until it finds the first shared point between both branches (hence the arrows showing the relationship of the commits and the extra red arrows showing the search)&lt;/p&gt;

&lt;p&gt;Git creates a hidden, temporary branch and points it at C, the part where you may have seen "rewinding" in the terminal&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwkg0ru3l4u898vf3zpmz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwkg0ru3l4u898vf3zpmz.jpg" alt="Same image as above but with arrows to show the search for the commits and an indicator for the temporary hidden branch at commit C. The other branches are still indicated at G &amp;amp; E. Diagram also shows the Git rebase command, is labeled " width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that Git knows all the missing commits from your new-branch, it points the temporary branch to main-branch's head, at G&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fui4ro8nhyzhoxpnk9cna.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fui4ro8nhyzhoxpnk9cna.jpg" alt="Labeled " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, Git "replays" the commits from the new-branch from commit G, adding commits D2 and E2&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F58v4vpgni46kcnccm5q1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F58v4vpgni46kcnccm5q1.jpg" alt="The main-branch line now has 2 branches stemming from it, from commits C &amp;amp; G. new-branch is still indicated from C, to commit E; and the temporary hidden branch stems from commit G, showing commits D2 and E2. Labeled " width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, because we magically had no merge conflicts &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"cmon man, please help me learn how to do that part!" ... don't worry, that's coming soon (-:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Git discards the temporary branch and points new-branch to E2&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4gknwl4tjsm1szuvv0we.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4gknwl4tjsm1szuvv0we.jpg" alt="" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this post, we took a simplified look at how Git rebase works for a typical development scenario. In truth, rebase has a lot more use and power outside of just the one I've illustrated here, but I hope this provides a fundemantal framework for approaching it with little to no experience. Together, we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The general why and when to use rebase versus merge. My personal rule of thumb is: merge goes from child to parent, rebase brings changes from parent to the bottom of the child's history&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That branches are just hidden text files that Git uses to know where a branch's head is&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At a glance, what Git does in the background during a rebase, how it "rewinds" to the first shared commit between the two branches, and "replays" the child branch's commits from the new head of the parent branch&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Rebase Workflow Tips
&lt;/h2&gt;

&lt;p&gt;I know some of you may be wanting to learn more about handling merge conflicts and I do plan to make a screencast for a follow up post. Until then, I have a few tips from my personal workflow that may help you avoid merge conflict hell more often than not:&lt;/p&gt;
&lt;h3&gt;
  
  
  .gitconfig settings to consider
&lt;/h3&gt;

&lt;p&gt;If you use VSCode you can set it as your merge conflict editor. Other nice GUI editors support an easier merge conflict UI as well, so I'd love to hear from other commenters how to configure other editors:&lt;/p&gt;

&lt;p&gt;Assuming that you do use VSCode and have &lt;a href="https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line" rel="noopener noreferrer"&gt;installed the "code" commandline tool&lt;/a&gt;, you can add these settings to your "~/.gitconfig" file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The last one for keeping backups is &lt;em&gt;my own personal preference&lt;/em&gt; that others may not agree with. I prefer it because in all my years of dev work, I've never needed them and I got sick of cleaning them up all the time.&lt;/p&gt;

&lt;p&gt;An alternative here would be to add ".orig" to your project's ".gitignore" file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Consider setting all branches to "pull" with rebase by default:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Are you sick of repeating the SAME merge conflict over and over again when you're in rebase hell?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Git's &lt;strong&gt;Re&lt;/strong&gt;use &lt;strong&gt;Re&lt;/strong&gt;corded &lt;strong&gt;Re&lt;/strong&gt;solution setting:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;[rerere]&lt;/strong&gt; will probably be the number one life saver for most people who have tried and hated rebasing in the past.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebase often&lt;/strong&gt; - the longer you wait to rebase your branch on new changes, the higher your chances of having tons of merge conflicts. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consider squashing your commits with interactive rebase&lt;/strong&gt; - when you run &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase -i main-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;...the "-i" option means interactive. It will show you all of your branch's commits in an ordered list (earliest on the top). &lt;/p&gt;

&lt;p&gt;The screen will provide instructions for different options for each commit, with the default being to "pick" the commit, meaning to keep it for the "replay" part. &lt;/p&gt;

&lt;p&gt;Another option is to "squash" it with the one above it. If your branch is super old and has tons of commits, you may find it helpful to squash it down to one so that your merge conflicts can only happen once (because only one giant commit is being replayed). This is something you'd want to discuss with your team first, though.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;Well shoot. That's about all I can muster. What do you think? Has this been helpful? Can I clarify or elaborate anything else? Fellow code veterans, am I way off base, or could I tweak some of my information to be more accurate? All comments, questions, concerns, and feedback are very much welcome, and I thank you for your time today. Happy coding!&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Barebones AWS Amplify + React + GraphQL App</title>
      <dc:creator>Joe Sak</dc:creator>
      <pubDate>Sun, 17 Nov 2019 17:51:57 +0000</pubDate>
      <link>https://forem.com/joemsak/barebones-aws-amplify-react-graphql-app-5ae8</link>
      <guid>https://forem.com/joemsak/barebones-aws-amplify-react-graphql-app-5ae8</guid>
      <description>&lt;p&gt;This is a simple guide on how to get a very basic React app going with GraphQL and AWS Amplify. Unfortunately, the AWS docs aren't the best and I find myself forgetting what to do and unable to follow their examples every time.&lt;/p&gt;

&lt;p&gt;I think the biggest culprit is the part of the docs which cover adding Auth to your app. If you don't need Auth, you'll be tempted to skip that section, but unfortunately one of the most crucial steps is documented there and only there, instead of as a basic preliminary step for all apps that want to use Amplify.&lt;/p&gt;

&lt;p&gt;Not only that, but all the tutorials and examples that I can find out there are super complex, including libraries and code design strategies that further confuse me and throw me off track. I am putting out the super barebones example that I wish I could find.&lt;/p&gt;

&lt;p&gt;Finally, create-react-app sets you up with a functional component by default, whereas the docs use examples for a classical component, which is also confusing. So here goes:&lt;/p&gt;

&lt;p&gt;Requirements:&lt;br&gt;
(As of this post in mid November 2019)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;node 13.1.0&lt;/li&gt;
&lt;li&gt;amplify 3.16.0&lt;/li&gt;
&lt;li&gt;create-react-app 3.2.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This post assumes you already ran &lt;code&gt;aws configure&lt;/code&gt; - this portion of the docs has never been an issue for me personally&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;create-react-app my-project-name
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-project-name
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add aws-amplify aws-amplify-react

&lt;span class="nv"&gt;$ &lt;/span&gt;amplify init
  &lt;span class="c"&gt;# follow the default instructions&lt;/span&gt;
  &lt;span class="c"&gt;# wait for the cloud processes to finish&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;amplify add api 
  &lt;span class="c"&gt;# follow prompts for GraphQL + &lt;/span&gt;
  &lt;span class="c"&gt;# API Key for authorization +&lt;/span&gt;
  &lt;span class="c"&gt;# default prompts that will guide you &lt;/span&gt;
  &lt;span class="c"&gt;# in creating a schema +&lt;/span&gt;
  &lt;span class="c"&gt;# Single-Object +&lt;/span&gt;
  &lt;span class="c"&gt;# No to editing the schema&lt;/span&gt;

&lt;span class="c"&gt;# You now have a basic API for a simple ToDo model&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;amplify push
  &lt;span class="c"&gt;# say Yes to generate the code for your GraphQL API&lt;/span&gt;
  &lt;span class="c"&gt;# (all the default answers will work fine for this post)&lt;/span&gt;
  &lt;span class="c"&gt;# ... and wait a while (-:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now here is the crucial code that they sort of hide in the "Adding Auth" section of the docs, for those of us who do not need to add Auth:&lt;/p&gt;

&lt;p&gt;Add this code to &lt;code&gt;index.js&lt;/code&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="c1"&gt;// other imports...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Amplify&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-amplify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;awsconfig&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-exports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;Amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;awsconfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// ReactDOM.render...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, start with a bare-bones &lt;code&gt;App.js&lt;/code&gt;&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;React&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;react&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&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="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so that our CSS isn't wonky later, consider replacing the &lt;code&gt;.App&lt;/code&gt; definition in &lt;code&gt;App.css&lt;/code&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="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="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cm"&gt;/* instead of text-align: center; */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add a basic input to create a ToDo and store it at the AWS AppSync GraphQL backend&lt;/p&gt;

&lt;p&gt;First, we will need to add a controlled input, and in a functional component, we must import &lt;code&gt;useState&lt;/code&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="c1"&gt;// change FROM this:&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;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;// TO this:&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&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;In the top of the App function, add this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// ...the rest...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And return the JSX for the input + button:&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="c1"&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;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&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="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todoName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="si"&gt;}&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="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add ToDo&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&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="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the function to handle the controlled input change:&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&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="nf"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// return ( ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to enable the &lt;code&gt;addTodo&lt;/code&gt; function we will import the API and graphQL tools:&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;API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;graphqlOperation&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-amplify&lt;/span&gt;&lt;span class="dl"&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;createTodo&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;./graphql/mutations
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally the &lt;code&gt;addTodo&lt;/code&gt; function&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;graphqlOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todoName&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="nf"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// make the input blank again&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Another fun fact of the AWS docs is&lt;/span&gt;
  &lt;span class="c1"&gt;// they don't give the updated &lt;/span&gt;
  &lt;span class="c1"&gt;// example that the 2nd argument &lt;/span&gt;
  &lt;span class="c1"&gt;// is an object with the "input" property (-:&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your local server started via &lt;code&gt;yarn start&lt;/code&gt; you ought to now be able to successfully create a ToDo in your AWS GraphQL backend!&lt;/p&gt;

&lt;p&gt;Let's list our ToDos just to be sure.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: the following is probably a very naïve implementation and others will suggest a "better" way but I just want to be sure that my application is working during this prototyping phase.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We'll import our GraphQL query:&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;listTodos&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;./graphql/queries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add another useState to get an array of our ToDo items:&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;todoItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodoItems&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Create a function to populate our ToDos from AWS:&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;updateTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allTodos&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;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;graphqlOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;setTodoItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allTodos&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="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&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;Add some quick JSX to list our ToDos:&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="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todoItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&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;Modify our addTodo function:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(yes there is a better way with graphQL subscriptions, but this is okay for today!)&lt;/em&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;graphqlOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todoName&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="nf"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;updateTodos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// here it is&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the very, very naïve call to &lt;code&gt;updateTodos&lt;/code&gt; before returning our JSX:&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="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="nf"&gt;updateTodos&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="c1"&gt;//...&lt;/span&gt;
    &lt;span class="c1"&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;Welp, that should be it!&lt;/p&gt;

&lt;p&gt;Here is the full &lt;code&gt;index.js&lt;/code&gt;&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;React&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;react&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="nx"&gt;ReactDOM&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;react-dom&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./index.css&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="nx"&gt;App&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;./App&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;serviceWorker&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;./serviceWorker&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="nx"&gt;Amplify&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-amplify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;awsconfig&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-exports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;Amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;awsconfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// If you want your app to work offline and load faster, you can change&lt;/span&gt;
&lt;span class="c1"&gt;// unregister() to register() below. Note this comes with some pitfalls.&lt;/span&gt;
&lt;span class="c1"&gt;// Learn more about service workers: https://bit.ly/CRA-PWA&lt;/span&gt;
&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregister&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And full &lt;code&gt;App.js&lt;/code&gt;&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;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&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;API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;graphqlOperation&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-amplify&lt;/span&gt;&lt;span class="dl"&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;createTodo&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;./graphql/mutations&lt;/span&gt;&lt;span class="dl"&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;listTodos&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;./graphql/queries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todoItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodoItems&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;addTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;graphqlOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todoName&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="nf"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;updateTodos&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;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&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="nf"&gt;setTodoName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allTodos&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;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;graphqlOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;setTodoItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allTodos&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="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;updateTodos&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;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&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="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todoName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="si"&gt;}&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="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add ToDo&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&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="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todoItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&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="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>aws</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
    <item>
      <title>New to Javascript? How to set up a macOS Dev Environment for the first time</title>
      <dc:creator>Joe Sak</dc:creator>
      <pubDate>Wed, 06 Nov 2019 22:03:53 +0000</pubDate>
      <link>https://forem.com/joemsak/new-to-javascript-how-to-set-up-a-macos-dev-environment-for-the-first-time-54g</link>
      <guid>https://forem.com/joemsak/new-to-javascript-how-to-set-up-a-macos-dev-environment-for-the-first-time-54g</guid>
      <description>&lt;p&gt;Remember: You don’t need to fully understand everything here yet - I don’t &lt;strong&gt;totally&lt;/strong&gt; understand it all at a fundamental level myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Xcode Developer Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Terminal&lt;/li&gt;
&lt;li&gt;Type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xcode-select --install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;p&gt;This supplies your computer with system libraries needed in general for all sorts of development&lt;/p&gt;

&lt;p&gt;Mainly right now, we just need it for the next one:&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Homebrew
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Terminal&lt;/li&gt;
&lt;li&gt;Type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;p&gt;Homebrew is a package manager - you can install lots of different kinds of packages into your computer system that you may need to do more development in the future&lt;/p&gt;

&lt;p&gt;Mainly right now, we just need it for the next one:&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ASDF
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Terminal&lt;/li&gt;
&lt;li&gt;Type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install asdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After that’s done, type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo -e "\n. $(brew --prefix asdf)/asdf.sh" &amp;gt;&amp;gt; ~/.bash_profile

echo -e "\n. $(brew --prefix asdf)/etc/bash_completion.d/asdf.bash" &amp;gt;&amp;gt; ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After that, type this and press enter:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Notice the “.” at the beginning of this one!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;p&gt;ASDF will let you install and manage different versions of development libraries / languages for each project on your computer - you will someday most definitely come across work that requires you to lock down to older versions, and this tool will make you prepared to do that in an isolated way without hassle&lt;/p&gt;

&lt;p&gt;Mainly right now, we just need it for the next one:&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Node JS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Terminal&lt;/li&gt;
&lt;li&gt;Type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asdf plugin-add nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then, type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asdf list-all nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If no one has told you what version you need, look for the latest one. Otherwise, look for the version that you specifically need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, type this and press enter: &lt;br&gt;
&lt;strong&gt;Where VERSION is the actual version, for example: 13.0.1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asdf install nodejs VERSION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;p&gt;Node is Javascript on your computer - you need it to build JS apps :-)&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Yarn
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Terminal&lt;/li&gt;
&lt;li&gt;Type this and press enter:
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation:
&lt;/h3&gt;

&lt;p&gt;Yarn is like NPM (what is NPM you might ask) but faster&lt;/p&gt;

&lt;p&gt;NPM means “Node Package Manager” - Yarn and NPM install node packages either globally if you tell them to, or locally in your current project by default&lt;/p&gt;

&lt;p&gt;Congratulations!&lt;/p&gt;

&lt;p&gt;You are now ready to install and use tools like &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/vue"&gt;@vue&lt;/a&gt;/cli&lt;/strong&gt; or &lt;strong&gt;create-react-app&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
