<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sascha Becker</title>
    <description>The latest articles on DEV Community by Sascha Becker (@saschb2b).</description>
    <link>https://dev.to/saschb2b</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%2F175250%2Fd1d1cf13-5372-49c1-a279-9d01febb9485.jpeg</url>
      <title>DEV Community: Sascha Becker</title>
      <link>https://dev.to/saschb2b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saschb2b"/>
    <language>en</language>
    <item>
      <title>Material Design 2 — more than just rounded corners</title>
      <dc:creator>Sascha Becker</dc:creator>
      <pubDate>Fri, 11 May 2018 14:50:00 +0000</pubDate>
      <link>https://dev.to/saschb2b/material-design-2-more-than-just-rounded-corners-khh</link>
      <guid>https://dev.to/saschb2b/material-design-2-more-than-just-rounded-corners-khh</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AtIOufDyXyCbog64OBiUrfg.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AtIOufDyXyCbog64OBiUrfg.png"&gt;&lt;/a&gt;&lt;a href="https://material.io/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://material.io/" rel="noopener noreferrer"&gt;https://material.io/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Material Design
&lt;/h3&gt;

&lt;p&gt;Google first showed it’s vision for the next UI principles in 2014.&lt;/p&gt;

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

&lt;p&gt;So with Google I/O 2018 an iterativ version of material design was published.&lt;/p&gt;

&lt;p&gt;Many things were left untouched, which is good because it worked well so far. Some things are now tweaked and enhanced to provide better freedom for creative UI designers. And some new stuff was added. Let’s break it down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goals
&lt;/h3&gt;

&lt;p&gt;The first version of the Material Design guidelines had two fundamental goals which it achieved very well over the past few years.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Create&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Create a visual language that synthesizes classic principles of good design with the innovation and possibility of technology and science.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Unify&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Develop a single underlying system that allows for a unified experience across platforms and device sizes. Mobile precepts are fundamental, but touch, voice, mouse, and keyboard are all ﬁrst-class input methods.&lt;/p&gt;

&lt;p&gt;If you want to read more about the first version, head over to the archived guidelines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/archive/guidelines" rel="noopener noreferrer"&gt;Introduction - Material Design&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Designs that adopted the Material Design guidelines were pretty intuitive. But they had one thing in common, they &lt;em&gt;looked and felt nearly all the same&lt;/em&gt;. You might argue that this a good thing, but if you want to present your brand, it’s certainly not. That’s why Google added a third goal this year.&lt;/p&gt;

&lt;h4&gt;
  
  
  Customize
&lt;/h4&gt;

&lt;p&gt;Expand Material’s visual language and provide a flexible foundation for innovation and brand expression. Take a look at the talk to see what can be now achieved by just making a few tweaks.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Principles
&lt;/h3&gt;

&lt;p&gt;Material Design started with three very important key principles.&lt;/p&gt;

&lt;h4&gt;
  
  
  Material is the metaphor
&lt;/h4&gt;

&lt;p&gt;Material Design is inspired by the physical world and its textures, including how they reflect light and cast shadows. Material surfaces reimagine the mediums of paper and ink.&lt;/p&gt;

&lt;h4&gt;
  
  
  Bold, graphic, intentional
&lt;/h4&gt;

&lt;p&gt;Material Design is guided by print design methods — typography, grids, space, scale, color, and imagery — to create hierarchy, meaning, and focus that immerse viewers in the experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  Motion provides meaning
&lt;/h4&gt;

&lt;p&gt;Motion focuses attention and maintains continuity, through subtle feedback and coherent transitions. As elements appear on screen, they transform and reorganize the environment, with interactions generating new transformations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two new principles
&lt;/h3&gt;

&lt;p&gt;To achieve the new goal of customization, they had to expand that list a bit.&lt;/p&gt;

&lt;h4&gt;
  
  
  Flexible foundation
&lt;/h4&gt;

&lt;p&gt;The Material Design system is designed to enable brand expression. It’s integrated with a custom code base that allows the seamless implementation of components, plug-ins, and design elements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cross-platform
&lt;/h4&gt;

&lt;p&gt;Material Design maintains the same UI across platforms, using shared components across Android, iOS, Flutter, and the web.&lt;/p&gt;

&lt;h3&gt;
  
  
  Colors
&lt;/h3&gt;

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

&lt;p&gt;&lt;a href="https://material.io/archive/guidelines/style/color.html#" rel="noopener noreferrer"&gt;Color - Style - Material Design&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s how it started. A predefined color palette and I, as a developer, was happy that my decisions were made so easy. It even says so in the video title!&lt;/p&gt;

&lt;p&gt;And now, for the new goal and principles, we have the choice for even more colors. Like all the colors. Want your app to be purple but kinda blue? No problem, go for 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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AuNfp9jsEENQgZqVq.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AuNfp9jsEENQgZqVq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So they defined three principles for colors.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hierarchical
&lt;/h4&gt;

&lt;p&gt;Color indicates which elements are interactive, how they relate to other elements, and their level of prominence. Important elements should stand out the most.&lt;/p&gt;

&lt;h4&gt;
  
  
  Legible
&lt;/h4&gt;

&lt;p&gt;Text and important elements, like icons, should meet legibility standards when appearing on colored backgrounds, across all screen and device types.&lt;/p&gt;

&lt;h4&gt;
  
  
  Expressive
&lt;/h4&gt;

&lt;p&gt;Reinforce your brand by showing brand colors at memorable moments that reinforce your brand’s style.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/color" rel="noopener noreferrer"&gt;The color system&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Shape
&lt;/h3&gt;

&lt;p&gt;Up until now we had round buttons, slightly round corners and hard corners. Now we can have every combination with various settings involved.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A5NwaS0Joh4PEso8l.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A5NwaS0Joh4PEso8l.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Material surfaces have a rectangular shape by default, with 4dp rounded corners. They have adjustable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Corner angles and curves&lt;/li&gt;
&lt;li&gt;Edge angles and curves&lt;/li&gt;
&lt;li&gt;The number of corners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shape changes, such as rounded or clipped corners, can be subtle or more significant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/shape/about-shape.html" rel="noopener noreferrer"&gt;About shape&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  App bar
&lt;/h4&gt;

&lt;p&gt;We already know and love the app bar. It’s placed at the top and provides space for our burger menu icon, a title and various actions we need.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AZeSNdKPlX2ElCrBg.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AZeSNdKPlX2ElCrBg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But you know what loves the top space? The notch. Oh the glorious notch. You may noticed the iPhone X UI tweaks to integrate the notch better into current designs. And it’s coming to android, too. Scaled page titles and all the top actions are now on the bottom. They don’t say it but that’s why the app bar bottom was introduced.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AMrmnIeOaXAaEw1i4.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AMrmnIeOaXAaEw1i4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shifts the current app bar to bottom and basically acts like normal. But what about a FAB (Floating Action Button). Doesn’t it get in the way you may ask?Yes, it would. So they just merged it.&lt;/p&gt;

&lt;p&gt;There are various variants on how the FAB is placed and its visual appeal. It can even be placed in a cutout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/components/app-bars-bottom.html" rel="noopener noreferrer"&gt;App bars: bottom&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Button
&lt;/h4&gt;

&lt;p&gt;What’s the primary action on this page? That’s what every designer asked in the past. And in most cases it was very easy to define what’s a &lt;em&gt;primary&lt;/em&gt; and what’s more a &lt;em&gt;secondary&lt;/em&gt; action. Use &lt;em&gt;flat buttons&lt;/em&gt; if you need less prominence and &lt;em&gt;raised buttons&lt;/em&gt; for more prominence.&lt;/p&gt;

&lt;p&gt;With material design 1 we had flat buttons and raised buttons. In combination with the primary or &lt;em&gt;secondary&lt;/em&gt; color a distinction was easy to make. But sometimes we wished for a “in-between” button to display a special use case. That’s what’s new!&lt;/p&gt;

&lt;p&gt;They renamed flat buttons to text buttons and raised buttons to contained buttons. And they called the “in-between” button outlined button.&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%2Fcdn-images-1.medium.com%2Fmax%2F720%2F0%2AF5RubobFy7Pn00YU.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%2Fcdn-images-1.medium.com%2Fmax%2F720%2F0%2AF5RubobFy7Pn00YU.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will make different emphasis easier to display and gives designers more options to work with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/components/buttons.html" rel="noopener noreferrer"&gt;Buttons&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Sheet
&lt;/h4&gt;

&lt;p&gt;Oh the lovely sheet. Drawers’ little brother. It is basically just a paper element which would raise from the button to display beautiful actions or details. In some cases it is even persistent and provides actions used in media playback.&lt;/p&gt;

&lt;p&gt;Some designs needed to display options on the side. Like filters, sort options or additional details. We had to build this ourselves. But no more my friend. I introduce the sheet on the side!&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AKEAQYW0XO_7u8zeO.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AKEAQYW0XO_7u8zeO.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works just like the bottom sheet but now on the side. Use it in a persistent state or like a modal and let it overlap your content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/components/sheets-side.html" rel="noopener noreferrer"&gt;Sheets: side&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Backdrop
&lt;/h4&gt;

&lt;p&gt;This is a completely new component. It combines the content displayed in the front layer with details, filters or other actions related to that content in the back layer.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AIXPbQbUpJ5QNfnTwn9ruVA.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AIXPbQbUpJ5QNfnTwn9ruVA.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/components/backdrop.html" rel="noopener noreferrer"&gt;Backdrop&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Text fields
&lt;/h4&gt;

&lt;p&gt;Input fields just had a label, its input area and an underline. Now there are two options to use. Filled text and outlined text.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AhOHC2MVbQlqiY754.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AhOHC2MVbQlqiY754.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Filled text fields carry more visual emphasis, making them stand out when surrounded by other content and components.&lt;/p&gt;

&lt;p&gt;Outlined text fields have less visual emphasis than filled text fields, which helps simplify layout in places like forms, where many text fields are placed together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://material.io/design/components/text-fields.html" rel="noopener noreferrer"&gt;Text fields&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Many subtle but very important changes for achieving the new goal towards more customization. Also really cool new additions which will address past confusion.&lt;/p&gt;

&lt;p&gt;These changes will lead to different variations and adaptions of the standards while still look and feel different.&lt;/p&gt;

&lt;p&gt;For me as a developer and designer it’s still a big pill to swallow as I just thought I mastered material design 1. But change and progress is good for everyone.&lt;/p&gt;




</description>
      <category>materialdesign</category>
      <category>google</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>A cryptocurrency trading bot that doesn’t scam you</title>
      <dc:creator>Sascha Becker</dc:creator>
      <pubDate>Tue, 14 Nov 2017 15:45:12 +0000</pubDate>
      <link>https://dev.to/saschb2b/a-cryptocurrency-trading-bot-that-doesn-t-scam-you-51en</link>
      <guid>https://dev.to/saschb2b/a-cryptocurrency-trading-bot-that-doesn-t-scam-you-51en</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F780%2F0%2ArslltOp4vWpMGgUS.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%2Fcdn-images-1.medium.com%2Fmax%2F780%2F0%2ArslltOp4vWpMGgUS.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cryptocurrency trading bots are becoming the next big thing people think they need. And so they buy one. So did I.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is not a copy &amp;amp; pasta example. It’s more a guideline on how to achieve what you want&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 0: Learn throwing money away the hard way
&lt;/h3&gt;

&lt;p&gt;Investing in a third party cryptocurrency trading bot makes you feel you did the right thing. You can become finally rich by doing nothing. The bot will make money for you, right? Wrong!&lt;/p&gt;

&lt;p&gt;You just gave away money to buy this bot to make the developer rich. And he does nothing, except some updates here and there. So in that way he does make money with a cryptocurrency bot.&lt;/p&gt;

&lt;p&gt;But you are still not rich. Dang it! What to do?&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Write your own
&lt;/h3&gt;

&lt;p&gt;The only bot you should trust comes from a codebase you build. It comes from a logic and pattern you invented. Don’t let anyone tell you what’s right.&lt;/p&gt;

&lt;p&gt;I coded one and you can, too! So let’s get started. (Spoiler: I’m not rich, yet)&lt;/p&gt;

&lt;p&gt;You can also clone my github repo if you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TeamWertarbyte/crypto-trading-bot" rel="noopener noreferrer"&gt;https://github.com/TeamWertarbyte/crypto-trading-bot&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Find a good cryptocurrency trading market
&lt;/h3&gt;

&lt;p&gt;This is the hardest part. Find a good place for your bot to trade on. Good starting points are either bittrex or kraken. The both have good APIs to work on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bittrex.com/Home/Api" rel="noopener noreferrer"&gt;https://bittrex.com/Home/Api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kraken.com/help/api" rel="noopener noreferrer"&gt;Kraken | Buy, Sell and Margin Trade Bitcoin (BTC) and Ethereum (ETH) - API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an account and let’s get to the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Define the bot environment
&lt;/h3&gt;

&lt;p&gt;For my bot I stuck with bittrex.com It has a solid API and good response times. They also provide a websocket for live updates.&lt;/p&gt;

&lt;p&gt;The framework I’m using for this example is node js. But you can choose whatever you like. I wanted to have it run via docker-compose in the command line. So node js was a good pick.&lt;/p&gt;

&lt;p&gt;The API can be accessed via a npm package like&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dparlevliet/node.bittrex.api" rel="noopener noreferrer"&gt;dparlevliet/node.bittrex.api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or you write your own REST client to access bittrex. The documentation for the API in bittrex is quite outdated. It is for version 1.1 which is in use for quite some time now. Bittrex also accepts calls from, the not yet official released, version 2.0. The mentioned package for node does a pretty good job implementing the shiny new 2.0 calls. Use that!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Define your trade logic
&lt;/h3&gt;

&lt;p&gt;As you want to crunch the numbers you some market indicators. For me it was the EMA (Exponential Moving Average) value. You can read more about other values here:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://stockcharts.com/school/doku.php?id=chart_school:market_indicators" rel="noopener noreferrer"&gt;Market Indicators [ChartSchool]&lt;/a&gt;&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ApmFIYVLaKWWUAgqrc-aOtw.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ApmFIYVLaKWWUAgqrc-aOtw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I chose two market indicators on an hour basis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(RED) EMA with a period of 50&lt;/li&gt;
&lt;li&gt;(BLUE) EMA with a period of 15&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alone they are not very effective. But look at those points where they cross. They are the ideal entry or exit points for buy or sell orders.&lt;/p&gt;

&lt;h4&gt;
  
  
  So my trade logic was clear
&lt;/h4&gt;

&lt;p&gt;Buy if EMA 15 is greater than EMA 50 and sell if EMA 50 is greater than EMA 15. This way my money is always in altcoins that are raising and once they fall sell it back to bitcoin.&lt;/p&gt;

&lt;p&gt;This is just one out of dizillion combinations. Try what’s best for you. I’m working on an AI that detects the best market indicators and creates new ones but that will be another post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Docker
&lt;/h3&gt;

&lt;p&gt;Your bot has to run 24/7 otherwise you won’t be profitable. So I wrapped my bot in a docker compose which runs forever.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:latest

# Create app directory
RUN mkdir - p / usr / src / app
WORKDIR / usr / src / app

# Install app dependencies
COPY package.json / usr / src / app/  
RUN npm install

# Bundle app source
COPY. / usr / src / app

RUN npm run build
CMD ["npm", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker-compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version:'2'
services:  
 server:  
 build:.
restart:'unless-stopped'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: The loop
&lt;/h3&gt;

&lt;p&gt;Let’s define the loop and its configs. I will explain every loop action step by step so be patient. Our config object will grow over time. Our constructor creates three internal variables.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bittrex — The access point to the bittrex api&lt;/li&gt;
&lt;li&gt;currencies — Holds our populated coins, its values, market indicators and everything else coin related&lt;/li&gt;
&lt;li&gt;bitcoin — It’s just the extracted bitcoin coin from the currencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use bluebird as my promise library because of concurrency control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const now = require('performance-now')
const Promise = require('bluebird')
const log = require('fancy-log')

Promise.config({
 cancellation: true  
})

const configs = {
 cancelOpenOrdersOnStart: true,
 refreshTimeout: 180000 // 3 minutes
}

const INVEST\_HOLD\_OR\_REJECT = {
 HOLD: 'HOLD',
 INVEST: 'INVEST',
 REJECT: 'REJECT',
 NONE: 'NONE'
}

export default class Watcher {
 constructor (bittrex) {
this.bittrex = bittrex
this.currencies = []
this.bitcoin = {}
 }

async watch () {
const start = now()
 log.info(`## Started emma watch ##`)

 configs.cancelOpenOrdersOnStart &amp;amp;&amp;amp; await this.cancelOldOrders()

await this.fetchMarkets()
await this.fetchBalances()

await this.injectMarketSummaries( this.currencies)
await this.filterCurrenciesByMarkets(configs.markets)
await this.injectCandleData( this.currencies)
await this.injectMarketIndicators( this.currencies)
await this.countEmaCrossPointTicks( this.currencies)
await this.injectClosedOrderHistory( this.currencies)

await this.injectMarketSummaries( this.currencies)
await this.evaluateInvestHoldOrReject( this.currencies)

await this.rejectBadInvestments( this.currencies)
await this.invest( this.currencies)

 log.info(`## Finished ${(now() - start).toFixed(5)} ms ##`)
 setTimeout(() =\&amp;gt; this.watch(), configs.refreshTimeout)
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.1: Cancel old orders
&lt;/h4&gt;

&lt;p&gt;Orders made by our bot may not always go through. So we have to cancel old orders if they won’t be accepted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async cancelOldOrders () {
const start = now()
const openOrders = await this.bittrex.getOpenOrders()

if (openOrders.length \&amp;gt; 0) {
for ( let openOrder of openOrders) {
const elapsedHours = ( new Date() - new Date(openOrder.Opened)) / 1000 / 60 / 60
if (elapsedHours \&amp;gt; configs.maxHoursToHoldOrder) {
 log.info(`Cancel ${openOrder.OrderType} on ${openOrder.Exchange} du to older than ${configs.maxHoursToHoldOrder} hours`)
await this.bittrex.cancel({uuid: openOrder.OrderUuid})
 }
 }
 log.info(`Canceled old orders ${(now() - start).toFixed(5)} ms`)
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added a config variable to control elapsed hours to hold an order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 cancelOpenOrdersOnStart: true ,
 maxHoursToHoldBalance: 168, // 7 days
 refreshTimeout: 180000, // 3 minutes
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.2: Populate the currencies
&lt;/h4&gt;

&lt;p&gt;We fetch the current markets and filter only the BTC markets. I don’t support ETH markets for now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fetchMarkets () {
const start = now()
this.currencies = await this.bittrex.getMarkets()

 // remove other market than BTC for now
this.currencies = this.currencies.filter(c =\&amp;gt; c.BaseCurrency === 'BTC')
 log.info(`Fetched currencies ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to inject the current balances of the coins to see their actual value from our wallet. I also separate bitcoin at this stage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async fetchBalances () {
const start = now()
const balances = await this.bittrex.getBalances()
for ( let currency of this.currencies) {
const balance = balances.find((b) =\&amp;gt; b.Currency === currency.MarketCurrency)
if (balance) {
 currency.balance = balance
 } else {
 currency.balance = null  
}
 }

this.bitcoin = balances.find((b) =\&amp;gt; b.Currency === 'BTC')

 log.info(`Fetched balances ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.3: Get market live data
&lt;/h4&gt;

&lt;p&gt;To get get BID,  ASK and LATEST we need to inject the market summaries into our currencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async injectMarketSummaries (data) {
const start = now()

const marketSummaries = await this.bittrex.getMarketSummaries({\_: Date.now()})

await Promise.map(data, async (d) =\&amp;gt; {
const marketSummary = marketSummaries.find((ms) =\&amp;gt; d.BaseCurrency === ms.Market.BaseCurrency &amp;amp;&amp;amp; d.MarketCurrency === ms.Market.MarketCurrency)
 d.marketSummary = marketSummary.Summary
 })

 log.info(`Injected market summaries ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.4: Filter your currencies
&lt;/h4&gt;

&lt;p&gt;I added specific markets where I want to trade on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 cancelOpenOrdersOnStart: true ,
 maxHoursToHoldOrder: 0.5,
 refreshTimeout: 180000, // 3 minutes
 markets: [
 'ADA',
 'BCC',
 'DASH'
 ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can filter also by volume or a specific BTC value. Or you just don’t filter and trade with all available coin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async filterCurrenciesByMarkets (markets) {
const start = now()

this.currencies = this.currencies.filter(c =\&amp;gt; markets.includes(c.MarketCurrency) || (c.balance &amp;amp;&amp;amp; c.balance.Available \&amp;gt; 0))

 log.info(`Filtered currencies by selected markets ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.5: Light the candles
&lt;/h4&gt;

&lt;p&gt;To crunch some market indicators we need the candles. A candle describes a value for the selected market in a timeframe with a given step interval.&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%2Fcdn-images-1.medium.com%2Fmax%2F525%2F0%2AuSWzgqSY4E7MsRJz.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%2Fcdn-images-1.medium.com%2Fmax%2F525%2F0%2AuSWzgqSY4E7MsRJz.gif"&gt;&lt;/a&gt;&lt;a href="http://globaltrendtraders.com/technical-analysis/technical-analysis-of-stock-trends-1-chart-types/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="http://globaltrendtraders.com/technical-analysis/technical-analysis-of-stock-trends-1-chart-types/" rel="noopener noreferrer"&gt;http://globaltrendtraders.com/technical-analysis/technical-analysis-of-stock-trends-1-chart-types/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can read more about candles here:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://globaltrendtraders.com/technical-analysis/technical-analysis-of-stock-trends-1-chart-types/" rel="noopener noreferrer"&gt;Technical Analysis of Stock Trends #1 - Chart Types&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async injectCandleData (data) {
const start = now()
const \_ = Date.now()

const USDT\_BTC = await this.bittrex.getCandles({
 marketName: 'USDT-BTC',
 tickInterval: configs.tickInterval,
 \_
 })

await Promise.map(data, async (d) =\&amp;gt; {
 d.candles = await this.bittrex.getCandles({
 marketName: `BTC-${d.MarketCurrency}`,
 tickInterval: configs.tickInterval,
 \_
 })

 d.candles = d.candles.map((c, i) =\&amp;gt; this.parseCandleData(c, USDT\_BTC[i]))
 }, {concurrency: 15})

 log.info(`Injected candle data ${(now() - start).toFixed(5)} ms`)
}

parseCandleData (d, USDT\_BTC) {
return {
 date: parseDate(d.T),
 open: USDT\_BTC.O \* d.O,
 high: USDT\_BTC.H \* d.H,
 low: USDT\_BTC.L \* d.L,
 close: USDT\_BTC.C \* d.C,
 volume: d.V
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The step interval is a new config variable called tickInterval. You can go as low as five minutes or as long as several hours. I went with an hour as it’s more robust and I don’t want fast trading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 cancelOpenOrdersOnStart: true ,
 maxHoursToHoldOrder: 0.5,
 refreshTimeout: 180000, // 3 minutes
 tickInterval: 'hour',
 markets: [
 'ADA',
 'BCC',
 'DASH'
 ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also not that I multiply the values with USDT_BTC. Bittrex always displays a BTC value. As I don’t want to trade on a given BTC instead on the actual USD value of the currency I have to calculate a bit.&lt;/p&gt;

&lt;p&gt;You can skip the USDT_BTC part if you want to trade on raw BTC value curves.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6.6: Crunch the numbers
&lt;/h4&gt;

&lt;p&gt;It’s time to get our market indicators. But wait! You don’t have to calculate it by yourself. there’s a package for that. Install react stockcharts together with react and you got the math for free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rrag/react-stockcharts" rel="noopener noreferrer"&gt;rrag/react-stockcharts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to use EMA. We also need a time and date parser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { timeParse } from'd3-time-format'
import { ema } from'react-stockcharts/lib/indicator'

const parseDate = timeParse('%Y-%m-%dT%H:%M:%S')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First let’s inject our market indicators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async injectMarketIndicators (data) {
const start = now()

await Promise.map(data, async (d) =\&amp;gt; {
 d.keyFigures = await this.calculateMarketIndicators(d.candles)
 })

 log.info(`Calculated key figures ${(now() - start).toFixed(5)} ms`)
}

calculateMarketIndicators (data) {
const ema50 = ema()
 .id(0)
 .options({windowSize: 50})
 .merge((d, c) =\&amp;gt; {d.ema50 = c})
 .accessor(d =\&amp;gt; d.ema50)

const ema15 = ema()
 .id(1)
 .options({windowSize: 15})
 .merge((d, c) =\&amp;gt; {d.ema15 = c})
 .accessor(d =\&amp;gt; d.ema15)

return ema50(ema15(data))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The windowSize defines the timespan to calculate the indicators from.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6.7: Count steps since last EMA crossing
&lt;/h4&gt;

&lt;p&gt;As an &lt;em&gt;EMA Crossing&lt;/em&gt; I define a point in time where my two defined EMA values (EMA50 and EMA15) crossed. Like a break even for cryptocurrencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async countEmaCrossPointTicks (data) {
const start = now()

await Promise.map(data, async (d) =\&amp;gt; {
const lastKeyFigures = d.keyFigures[d.keyFigures.length - 1]
const lastEmaDifference = lastKeyFigures.ema50 - lastKeyFigures.ema15

 d.positiveTicks = 0
 d.negativeTicks = 0
for ( let i = d.keyFigures.length - 1; i \&amp;gt; 0; i--) {
const keyFigures = d.keyFigures[i]

if (lastEmaDifference \&amp;gt; 0 &amp;amp;&amp;amp; keyFigures.ema50 - keyFigures.ema15 \&amp;gt; 0) {
 d.negativeTicks++
 } else if (lastEmaDifference \&amp;lt; 0 &amp;amp;&amp;amp; keyFigures.ema50 - keyFigures.ema15 \&amp;lt; 0) {
 d.positiveTicks++
 } else {
break  
}
 }
 })

 log.info(`Counted ticks since last ema crossing ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every currency now has either a positive or a negative step counter. This tells me how very good or very bad it would be to invest in this currency at this given point in time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6.8: Inject closed order history
&lt;/h4&gt;

&lt;p&gt;In the past I made decisions on how much profit I made since I bought that coin. Or how much loss I gained since last buy order. Currently I don’t use that information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async injectClosedOrderHistory (data) {
const start = now()

await Promise.map(data, async (d) =\&amp;gt; {
 d.orderHistory = await this.bittrex.getOrderHistory({
 market: `BTC-${d.MarketCurrency}`
 })
 }, {concurrency: 10})

 log.info(`Injected closed orders ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Every currency now has a orderHistory array filled with old orders. Bittrex does sadly only serve orders from the last 30 days or 500 entries in total. So use that with caution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Step 6.9: Refresh market history
&lt;/h4&gt;

&lt;p&gt;As we calculate and crunch the numbers time has passed by and the latest currency value might wrong at this time. So we refresh it in the loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await this.injectMarketSummaries( this.currencies)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.10: Decide where to invest and what to sell
&lt;/h4&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AO1Xk_bMt8kkB1xhi.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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AO1Xk_bMt8kkB1xhi.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will be the hardest part. When is it perfect to invest in a currency? When is it better to reject a current invest and start over? When do you do nothing and wait?&lt;/p&gt;

&lt;p&gt;I decided to only look on my EMA crossings and how long the are now. That’s what my counted ticks are for. I also added a minimum tick counter value config variable to prevent invest hopping (buy, sell, buy, sell in a short time).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 cancelOpenOrdersOnStart: true ,
 maxEffectiveLoss: 60, // 60%
 maxHoursToHoldOrder: 0.5,
 refreshTimeout: 180000, // 3 minutes
 tickInterval: 'hour',
 markets: [
 'ADA',
 'BCC',
 'DASH'
 ],
 minimumEmaTicks: 5
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also introduced a maximum loss cap to reject invest that fall way to low.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async evaluateInvestHoldOrReject (data) {
const start = now()

await Promise.map(data, async (d) =\&amp;gt; {
const lastKeyFigures = d.keyFigures[d.keyFigures.length - 1]

 d.holdOrReject = INVEST\_HOLD\_OR\_REJECT.HOLD

if (d.balance &amp;amp;&amp;amp; d.balance.Available \&amp;gt; 0) {
if (lastKeyFigures.ema15 \&amp;lt; lastKeyFigures.ema50 &amp;amp;&amp;amp; d.negativeTicks \&amp;gt;= configs.minimumEmaTicks) {
 log.info(`Will reject ${d.MarketCurrency} due to ${d.negativeTicks} negative ema ticks`)
 d.holdOrReject = INVEST\_HOLD\_OR\_REJECT.REJECT
 } else if (d.balance.Available \* d.marketSummary.Bid \&amp;lt; configs.btcPerInvest \* (1 - configs.maxEffectiveLoss / 100)) {
 log.info(`Will reject ${d.MarketCurrency} due to falling below ${configs.btcPerInvest} btc`)
 d.holdOrReject = INVEST\_HOLD\_OR\_REJECT.REJECT
 }
 } else if (!d.balance || (d.balance &amp;amp;&amp;amp; d.balance.Available === 0)) {
if (lastKeyFigures.ema15 \&amp;gt; lastKeyFigures.ema50 &amp;amp;&amp;amp; d.positiveTicks \&amp;gt;= configs.minimumEmaTicks) {
 log.info(`Will invest in ${d.MarketCurrency} due to ${d.positiveTicks} positive ema ticks. EMA15 ${lastKeyFigures.ema15} \&amp;gt; EMA50 ${lastKeyFigures.ema50}`)
 d.holdOrReject = INVEST\_HOLD\_OR\_REJECT.INVEST
 }
 }
 })
 log.info(`Evaluated invest hold or reject ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.11: Reject bad investments
&lt;/h4&gt;

&lt;p&gt;As you evaluated investments as bad they will be sold. So let’s do so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async rejectBadInvestments (data) {
const start = now()

await Promise.map(data, async (d) =\&amp;gt; {
if (d.holdOrReject === INVEST\_HOLD\_OR\_REJECT.REJECT) {
if (d.marketSummary.Bid \* d.balance.Available \&amp;gt;= configs.minimumSellBalanceInBTC &amp;amp;&amp;amp; d.balance.Available \&amp;gt; d.MinTradeSize) {
try {
await this.bittrex.sellLimit({
 market: `${d.BaseCurrency}-${d.MarketCurrency}`,
 quantity: d.balance.Available,
 rate: (d.marketSummary.Bid - configs.rateSellBuyExtraBtc)
 })
 } catch (e) {
 log.info(e)
 }
 log.info(`${d.MarketCurrency} placed REJECT SELL order`)
 }
 }
 }, {concurrency: 20})
 log.info(`Rejected investments ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added configs.rateSellBuyExtraBtc to add a tiny amount of BTC to secure the sell and buy order. Also configs.minimumSellBalanceInBTC was added to check the bittrex sell threshold. Bittrex doesn’t allow orders smaller than that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 cancelOpenOrdersOnStart: true ,
 minimumSellBalanceInBTC: 0.0005,
 maxEffectiveLoss: 60, // 60%
 maxHoursToHoldOrder: 0.5,
 refreshTimeout: 180000, // 3 minutes
 rateSellBuyExtraBtc: 0.0000000000001, // to secure buy or sell
 tickInterval: 'hour',
 markets: [
 'ADA',
 'BCC',
 'DASH'
 ],
 minimumEmaTicks: 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6.12: Invest all the bitcoin!
&lt;/h4&gt;

&lt;p&gt;Now let’s throw all our remaining bitcoin value into currencies that seems worth it. I sorted my options by EMA ticks to invest in fresh risers first.&lt;/p&gt;

&lt;p&gt;I also instroduced two new config variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configs = {
 btcBuffer: 0.01, // btc that has to stay on the bank
 btcPerInvest: 0.005,
 cancelOpenOrdersOnStart: true ,
 minimumSellBalanceInBTC: 0.0005,
 maxEffectiveLoss: 60, // 60%
 maxHoursToHoldOrder: 0.5,
 refreshTimeout: 180000, // 3 minutes
 rateSellBuyExtraBtc: 0.0000000000001, // to secure buy or sell
 tickInterval: 'hour',
 markets: [
 'ADA',
 'BCC',
 'DASH'
 ],
 minimumEmaTicks: 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;btcPerInvest defines a fixed BTC value which will be used to make that order happen. You can also scale that value exponential based on your available bitcoin.&lt;/li&gt;
&lt;li&gt;btcBuffer defines a fixed btc value which has to stay and will not used for investment. I like to have some btc left for my manual trades.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async invest (data) {
const start = now()

let buyCounter = 0

 // Sort by tick count from last ema crossing
 data.sort((a, b) =\&amp;gt; a.positiveTicks - b.positiveTicks)
for ( let d of data) {
if ( this.bitcoin.Available \&amp;gt; configs.btcPerInvest + configs.btcBuffer) {
if (d.holdOrReject === INVEST\_HOLD\_OR\_REJECT.INVEST) {
const quantity = (configs.btcPerInvest - 0.00000623) / d.marketSummary.Ask

if (quantity \&amp;gt; d.MinTradeSize) {
try {
await this.bittrex.buyLimit({
 market: `${d.BaseCurrency}-${d.MarketCurrency}`,
 quantity,
 rate: (d.marketSummary.Ask + configs.rateSellBuyExtraBtc)
 })
 buyCounter++
this.bitcoin.Available -= configs.btcPerInvest
 log.info(`Invested ${configs.btcPerInvest} bitcoin in ${d.MarketCurrency} for ${quantity} amount`)
 } catch (e) {
 log.info(e)
 }
 }
 }
 } else {
 log.info(`Not enough btc left to invest. Keep saving more!`)
break  
}
 }

 log.info(`Invested ${configs.btcPerInvest * buyCounter} btc in ${buyCounter} options ${(now() - start).toFixed(5)} ms`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Deploy
&lt;/h3&gt;

&lt;p&gt;The bot is done. I push the code onto my server and start it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose up --build -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will build and start my bot. Logs can be viewed via logs of docker-compose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Improve your bot
&lt;/h3&gt;

&lt;p&gt;Your bot will make errors, you will make bad invest decisions based on certain market indicators. Learn from it and improve your code. To be hones, my bot lost nearly half my money before becoming stable and making actual profit again. Don’t give up.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AzjEeAZCYHlyebNJP.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AzjEeAZCYHlyebNJP.jpg"&gt;&lt;/a&gt;&lt;/p&gt;




</description>
      <category>docker</category>
      <category>bitcoin</category>
      <category>cryptocurrency</category>
      <category>react</category>
    </item>
    <item>
      <title>Structure your react apps the mantra way</title>
      <dc:creator>Sascha Becker</dc:creator>
      <pubDate>Mon, 18 Sep 2017 13:53:14 +0000</pubDate>
      <link>https://dev.to/saschb2b/structure-your-react-apps-the-mantra-way-4j23</link>
      <guid>https://dev.to/saschb2b/structure-your-react-apps-the-mantra-way-4j23</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1twyraerzlw9n158q4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1twyraerzlw9n158q4.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The holy grail of discussion is what is the best way to structure your project. The answer is, there is none. But here is one I fell in love with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Then mantra way!
&lt;/h3&gt;

&lt;p&gt;First of let’s talk about what makes a structure good. There are certain elements that make good use of organisation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to navigate&lt;/li&gt;
&lt;li&gt;Scales well over time&lt;/li&gt;
&lt;li&gt;Swap logic is fast and without many breaks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what exactly is mantra? I’m not talking about meditate while creating folders. It’s the &lt;a href="https://kadirahq.github.io/mantra/" rel="noopener noreferrer"&gt;mantra js&lt;/a&gt; spec application architecture developed by kadira back when meteor js was the cool kid.&lt;/p&gt;

&lt;p&gt;It described an architecture that should be maintainable and future proof. They claimed once set up it will satisfy your inner geek for up to five years. Not even kadira lasted that long by the way, nor will maybe meteor.&lt;/p&gt;

&lt;p&gt;So I moved on, turned my back from meteor and dived into the raw package land. And mantra js was the one thing that I loved and tried to embed.&lt;/p&gt;

&lt;p&gt;Let’s take a look of what a project could look like. Here is an example of a website with multiple routes, components, actions and reducers.&lt;/p&gt;

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

&lt;p&gt;Stay with me. It’s not that confusing as it seems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modules
&lt;/h3&gt;

&lt;p&gt;Let’s break it down and we start with the modules folder. It’s the core idea of mantra and what makes it so great in my opinion.&lt;/p&gt;

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

&lt;p&gt;Modules is business concern first. That means I don’t split it into&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;components&lt;/li&gt;
&lt;li&gt;containers&lt;/li&gt;
&lt;li&gt;reducers&lt;/li&gt;
&lt;li&gt;actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;right here. Instead mantra adds a layer on top to achieve better maintainability and hopefully makes this future proof.&lt;/p&gt;

&lt;p&gt;One important rule is that you &lt;strong&gt;don’t cascade modules&lt;/strong&gt;. If a module should have a submodule create it separately. The advantage is that you see all modules at a glance. You don’t have to open every module to see what’s inside.&lt;/p&gt;

&lt;h4&gt;
  
  
  Module content
&lt;/h4&gt;

&lt;p&gt;But what’s inside a module?&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt; folder holds every dumb component you need in that module and that module alone. Separation of concern is key here. You can read more about &lt;a href="https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0" rel="noopener noreferrer"&gt;here&lt;/a&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&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;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../core/components/Text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;material-ui/styles/colors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;GameTile&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./GameTile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&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;class&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Games&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Component&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;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;mobile&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Containers&lt;/strong&gt; folder holds the logic. What should be pushed into my dumb components? What data should be fetched (via dispatching actions or redux state)? All those concerns should be stored in here.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&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;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Games&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/Games&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;coreActions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nf"&gt;componentDidMount &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coreActions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMenuIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&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;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Games&lt;/span&gt;
 &lt;span class="p"&gt;{...&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&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="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;connect&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="o"&gt;=&lt;/span&gt;&lt;span class="err"&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;mobile&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;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mobile&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see I introduced a “core module” to make shared actions happen. In some point of time you can’t isolate modules completely. Some actions have to be shared and I think that’s a good compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routes&lt;/strong&gt; folder holds, as the name suggests, all the routes that belong to that module. In this case we have a “/games” route that needs to be hooked to the games container.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Games&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../containers/Games&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&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="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;exact&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/games&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Games&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&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;Additional routes for example “/games/:id” are also welcome here.&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional folders
&lt;/h4&gt;

&lt;p&gt;Actions and reducers also need a place to live.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Actions&lt;/strong&gt; folder holds the action types for redux calls.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;MENU&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_TOGGLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MENU&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;_TOGGLE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_RESPONSIVE&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_BREAKPOINT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SET&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;_RESPONSIVE&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;_BREAKPOINT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_MENU&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_INDEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SET&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;_MENU&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;_INDEX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the actual actions which can be dispatched.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./actionTypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;toggleMenu &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MENU&lt;/span&gt;&lt;span class="err"&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;open&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setResponsiveBreakpoint &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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_RESPONSIVE&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_BREAKPOINT&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setMenuIndex &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_MENU&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_INDEX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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;&lt;strong&gt;Reducers&lt;/strong&gt; folder holds obviously the reducers for that module.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../actions/actionTypes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;defaultState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="na"&gt;mobileView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;mobile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;tablet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;desktop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;toggleMenu &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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;menu&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="o"&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;open&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&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;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&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;open&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="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setMenuIndex &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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;menu&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;index&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;index&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="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setResponsiveBreakpoint &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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;mobile&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;value&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;768&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;tablet&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;value&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;768&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;value&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;desktop&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;value&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1200&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="o"&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="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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultState&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="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="o"&gt;**&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;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MENU&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_TOGGLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;toggleMenu&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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_RESPONSIVE&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_BREAKPOINT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setResponsiveBreakpoint&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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SET&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_MENU&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;_INDEX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nf"&gt;setMenuIndex&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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also split this into multiple files if you want.&lt;/p&gt;

&lt;p&gt;And now comes the important part, the glue! After you defined your folders with its logic and visual components you want to expose it, right? That’s where the index.js of the module folder comes in. It collects all the needed parts of the module and expose it for further use. Something like 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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reducers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nx"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nx"&gt;routes&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So everytime you need access to this module you have all the important parts right in the root of the module folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make it run
&lt;/h3&gt;

&lt;p&gt;So now comes the fun part. After defining our modules we need to deploy them within our application. Let’s take a look back to our overview:&lt;/p&gt;

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

&lt;p&gt;First let’s combine all the &lt;strong&gt;reducers&lt;/strong&gt;. In “src/reducers/index.js” we bundle all the reducers exposed by our modules.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;core&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../modules/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;games&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../modules/games&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;anotherModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../modules/anotherModule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be later used to combine our store just with:&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../reducers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And all our reducers from all defined modules are ready to go. Neat!&lt;/p&gt;

&lt;p&gt;Same goes for the &lt;strong&gt;routes&lt;/strong&gt;. Take a look inside the AppRoutes.js content:&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Switch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/core/containers/Application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;home&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;games&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/games&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;team&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/team&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/contact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;impressum&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modules/impressum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&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="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="err"&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;home&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;games&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;team&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;impressum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Application&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Switch&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&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 file just exposed all routes defined in our modules. They are embedded in an shared Application component defined in the core module. Application is the wrapper with header and footer and takes children as prop.&lt;/p&gt;

&lt;p&gt;Now just import those routes in your Root.js and everything is ready to deploy.&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&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="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;OfflinePluginRuntime&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;offline-plugin/runtime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;configureStore&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./configs/configureStore&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;createRoutes&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./AppRoutes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;createHistory&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history/createBrowserHistory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ConnectedRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;MuiThemeProvider&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;material-ui/styles/MuiThemeProvider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;getMuiTheme&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;material-ui/styles/getMuiTheme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./main.less&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHistory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;OfflinePluginRuntime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="o"&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="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&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="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MuiThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;muiTheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getMuiTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ConnectedRouter&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&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;createRoutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
 &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ConnectedRouter&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/MuiThemeProvider&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Provider&lt;/span&gt;&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;We now have several modules that are &lt;strong&gt;isolated&lt;/strong&gt; from each other. That makes them &lt;strong&gt;easy to swap&lt;/strong&gt; out for others. Also &lt;strong&gt;import statements&lt;/strong&gt; are now extremely short. Further changes inside a module make &lt;strong&gt;distraction&lt;/strong&gt; while coding from another module obsolete. &lt;strong&gt;Maintainability&lt;/strong&gt; is far better than searching for files associated with a specific concern. It &lt;strong&gt;scales well&lt;/strong&gt; due to just a few glue points needed and &lt;strong&gt;less clutter&lt;/strong&gt; inside the modules folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supplement
&lt;/h3&gt;

&lt;p&gt;I wrote a npm package to hide most of the preparations needed to use this structure and do most of this behind the curtain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TeamWertarbyte/module-loader" rel="noopener noreferrer"&gt;TeamWertarbyte/module-loader&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s still in an early stage an every PR and comment is welcome. But I already use this in production so I’m pretty confident that this will work as intended.&lt;/p&gt;




</description>
      <category>node</category>
      <category>react</category>
      <category>javascript</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
