<?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: Reaper</title>
    <description>The latest articles on DEV Community by Reaper (@barelyhuman).</description>
    <link>https://dev.to/barelyhuman</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%2F136804%2F15e06c79-5ba6-4de1-b963-ffbf54329f8a.png</url>
      <title>DEV Community: Reaper</title>
      <link>https://dev.to/barelyhuman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/barelyhuman"/>
    <language>en</language>
    <item>
      <title>Writing cleaner state in React and React Native</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 30 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/barelyhuman/writing-cleaner-state-in-react-and-react-native-2dj3</link>
      <guid>https://dev.to/barelyhuman/writing-cleaner-state-in-react-and-react-native-2dj3</guid>
      <description>&lt;p&gt;Ever since hooks got introduced in React, it made it a lot more easier to handle composition in react components and also helped the developers of react handle the component context a lot better. Also, as consumers of the library, we could finally avoid having to write &lt;code&gt;this.methodName = this.methodName.bind(this)&lt;/code&gt; which was a redundant part of the code to which a few developers ended up writing their own wrappers around the component context.&lt;/p&gt;

&lt;h2&gt;
  
  
  But that's old news, why bring it up now?
&lt;/h2&gt;

&lt;p&gt;Well, as developers there's always some of us who just go ahead follow the standard as is even when it makes maintenance hard and in case of hooks, people seem to just ignore the actual reason for their existence all together.&lt;/p&gt;

&lt;p&gt;If you witnessed the talk that was given during the release of hooks, this post might be not bring anything new to your knowledge. If you haven't seen the talk&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You should.&lt;/li&gt;
&lt;li&gt;I'm serious, go watch it!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the rebels, who are still here reading this, here's a gist of how hooks are to be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context Scope and hook instances
&lt;/h2&gt;

&lt;p&gt;If you've not seen how hooks are implemented then to be put simply, the hook will get access to the component it's nested inside and has no context of it's own, which then gives you ability to write custom functions that can contain hook logic and now you have your own custom hook.&lt;/p&gt;

&lt;p&gt;Eg: I can write something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTimer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&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="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTimer&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;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="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that gives me a simple timer, though the point is that now I can use this timer not just in this &lt;strong&gt;component&lt;/strong&gt; but any component I wish to have a timer in.&lt;/p&gt;

&lt;p&gt;The advantages of doing this&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I now have an abstracted stateful logic that I can reuse&lt;/li&gt;
&lt;li&gt;The actual hook code can be separated into a different file and break nothing since the hook's logic and it's internal state is isolated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives us smaller Component code to deal with while debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does any of that have to do with state!?
&lt;/h2&gt;

&lt;p&gt;Oh yeah, the original topic was about state...&lt;br&gt;
Now the other part of having hooks is the sheer quantity that people spam the component code with it and obviously the most used one is &lt;code&gt;useState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned above, one way is to segregate it to a separate custom hook but if you have like 10-20 &lt;code&gt;useState&lt;/code&gt; because you are using a form and for some weird reason don't have formik setup in you codebase then you custom hook will also get hard to browser through.&lt;/p&gt;

&lt;p&gt;And, that's where I really miss the old &lt;code&gt;setState&lt;/code&gt; from the days of class components and there's been various attempts at libraries that recreate the setState as a hook and I also created one which we'll get to soon but the solution is basically letting the state clone itself and modify just the fields that were modified, not that hard right?&lt;/p&gt;

&lt;p&gt;You can do something like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUserDetails&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// in some handler&lt;/span&gt;
&lt;span class="nx"&gt;setUserDetails&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reaper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that works (mostly) but also adds that additional &lt;code&gt;...userDetails&lt;/code&gt; everytime you want to update state. I say it works mostly cause these objects come with the same limitations that any JS Object has, the cloning is shallow and nested states will loose a certain set of data unless cloned properly and that's where it's easier to just use library's that make it easier for you to work with this.&lt;/p&gt;

&lt;p&gt;I'm going to use mine as an example but you can find more such on NPM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSetState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@barelyhuman/set-state-hook&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useCustomHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSetState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;a&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="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* 
      setState({
        nested: {
          a: state.nested.a + 1
        }
      });
    // or 
    */&lt;/span&gt;
    &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;draftState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;draftState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;draftState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;draftState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCustomHook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&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;nested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and I can use it like I would with the default class styled &lt;code&gt;setState&lt;/code&gt; but if you go through it carefully, I actually mutated the original &lt;code&gt;draftState&lt;/code&gt; and that's because &lt;code&gt;@barelyhuman/set-state-hook&lt;/code&gt; actually create's a clone for you so you can mutate the clone and when you return it still creates a state update without actually mutating the older state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use custom hooks to avoid spaghetti state and effect management code&lt;/li&gt;
&lt;li&gt;Use a setState replicator if you are using way to many &lt;code&gt;useState&lt;/code&gt; hooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;make it easier on your brain to read the code you write.&lt;/p&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How I built a simple status site with go lang and vercel?</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Sat, 03 Jul 2021 15:59:18 +0000</pubDate>
      <link>https://dev.to/barelyhuman/status-vercel-and-how-i-built-it-29p8</link>
      <guid>https://dev.to/barelyhuman/status-vercel-and-how-i-built-it-29p8</guid>
      <description>&lt;p&gt;By &lt;strong&gt;Status&lt;/strong&gt; i mean this website &lt;a href="https://status.barelyhuman.dev"&gt;barelyhuman/status&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason I built it was simple, I needed a simple setup to see if the web services were all up and running, the list is quite small because those are the currrent one's I would like to keep a track off.&lt;/p&gt;

&lt;p&gt;Now this was built in a quick 60 min - 80 min time span and I'm going to explain the things I did and why I did them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go lang (templates and http server)&lt;/li&gt;
&lt;li&gt;Vercel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's basically it. No seriously, that's about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mental Model
&lt;/h2&gt;

&lt;p&gt;The idea was to have a simple go binary that would render a html page with each website that needs to be checked and its particular status.&lt;br&gt;
This is basically why the website takes a bit longer to load after the browser cache has expired&lt;/p&gt;

&lt;p&gt;The go binary is the microservice that vercel will use as an entry point, so on a very basic scale, since I won't be using code to show how this is being done, we'll go through the list of things that it does.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the list of sites to be queried&lt;/li&gt;
&lt;li&gt;Ping each site to check if it's up, in certain cases ping the backend api of the web service to check if the api is up.&lt;/li&gt;
&lt;li&gt;Check for the status to be 200, if not then the site/api is probably down&lt;/li&gt;
&lt;li&gt;Render the html with the above data&lt;/li&gt;
&lt;li&gt;Upload this as a microservice endpoint to Vercel&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Problems
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Vercel doesn't allow a root endpoint without configuration so the endpoint for the micro service would be &lt;code&gt;/api/pinger&lt;/code&gt; and the final url would be &lt;code&gt;https://status.barelyhuman.dev/api/pinger&lt;/code&gt; , which while not a big deal, is a few more keystrokes than just &lt;code&gt;https://status.barelyhuman.dev&lt;/code&gt; and thats one issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The html templates files are additional assets and those don't always work in the vercel api functions and that iffy deployment and checks would be a deal breaker for a service which is trying to show the current status of other services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vercel has a time limit on each request of 10 seconds , post the initial execution request, so about 12-13 seconds whole. If I ping a website on the Indian Server from a US server, the services that are hosted in EU / IN would add up about 2 seconds, thus making the website be shown as &lt;strong&gt;Timed Out&lt;/strong&gt; if it accidentally crosses the 12 second mark.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid showing people what the urls of each of these api's are, which while you can dig down a bit and find out, I'd prefer to have at least a layer of protection on top.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solutions and Hacks
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The first one was simple, i do a browser rewrite for the &lt;code&gt;/&lt;/code&gt; url to &lt;code&gt;/api/pinger&lt;/code&gt; and done, checked if vercel supported that and boom , done.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rewrites"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/pinger"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The templates are just strings at the end of the day and go will build everything into a single binary so if I just write them as strings assigned to a variable, I can achieve the same result, so tried that and it worked as expected. I've explained about it in this &lt;a href="https://github.com/vercel/vercel/discussions/6316#discussioncomment-901041"&gt;discussion thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pinging each site in a linear fashion would be a bad idea but that was the initial prototype. I wanted to test if everything was already working. Checked if it was and then I went ahead and deployed the prototype. Right after I realised, that these would fail if the request is coming from the US server to the Indian hosted backend, thus making it slower, and that basically actually happened. It pinged barelyhuman's blog properly but failed to get the status for the Taco backend and crashed, a reload showed both the results but I don't want it to crash for something so trivial.&lt;br&gt;
I then just setup a go routine to parallelize the fetching of each service's status and now the site handles 4 without any issue, not a big number but since it's parallel it theoretically should create any problems for more either.&lt;br&gt;
I can optimize this better by limiting the time of each response to be under 4 seconds but then a busy server might not respond at once so I'm rethinking if I should/shouldn't do it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The html render and the website links are all fetched from the environment variables so that's a secret on the vercel portal for now so as long as no one hacks into vercel, I'm a little safe, obviously you can look through each app but those are proxies and rate-limited proxies (not boasting, there's ways around each) but for now that's a simple barrier to keep the urls safe.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>go</category>
    </item>
    <item>
      <title>Announcing Taco</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Fri, 02 Jul 2021 04:43:22 +0000</pubDate>
      <link>https://dev.to/barelyhuman/announcing-taco-5h76</link>
      <guid>https://dev.to/barelyhuman/announcing-taco-5h76</guid>
      <description>&lt;p&gt;I totally forgot about creating a mirror post when I announced this a that I'd get a little more exposure here. &lt;/p&gt;




&lt;p&gt;Nope, I didn't forget about the announcement , nor was I busy doing something else. I wanted it to be a release at night so I can sleep and wake up and not worry about it all day or obsessively checking my email for feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But night releases don't work!!&lt;/strong&gt;, I know.&lt;/p&gt;

&lt;p&gt;I'm not Elon musk with millions of people waiting for my one line tweet&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Taco. It's up. check it on &lt;a href="https://alpha.taco.barelyhuman.dev"&gt;https://alpha.taco.barelyhuman.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm reaper, I talk full paragraphs, even if I can't do that in real life... anyway&lt;/p&gt;

&lt;p&gt;Oh by the way, if you do just plan on clicking the above link and going on a test run instead of reading the whole thing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username: demo@reaper.im
Password: Demo@123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You won't be able to run the signup, I don't want people spamming the test server with accounts they won't use&lt;/p&gt;

&lt;h2&gt;
  
  
  Taco
&lt;/h2&gt;

&lt;p&gt;I'm going to answer a few questions regarding it and then you can go ahead and login with the test credentials to go through the alpha version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Build another project manager?
&lt;/h3&gt;

&lt;p&gt;I've been on it for a while actually, I built &lt;a href="https://pending.reaper.im"&gt;pending&lt;/a&gt; with the same thought and then never went ahead because then I'd be building what everyone else already has.&lt;/p&gt;

&lt;p&gt;I'm not a kanban person, I prefer writing down notes and making checklists and marking them to manage my work.&lt;/p&gt;

&lt;p&gt;I do have solutions for the checklists part which is &lt;a href="https://todo.reaper.im"&gt;todo&lt;/a&gt; and the notes are just me noting down on paper or a tablet device , whatever is closer and it's worked well for years but then I write these notes here and there and never find them when I really need them and have to do stuff off of memory, this is where the idea of just building one for myself came into the picture and also where I accidentally discovered that Linear existed.&lt;/p&gt;

&lt;p&gt;Now linear does everything I expect an issue manager to handle and I can use it in the way I intended to build Taco and drop taco as a project altogether but then there's no BarelyHuman in the picture at all.&lt;/p&gt;

&lt;p&gt;To become an indie developer supported by people so I can live off of projects I wish to build, there has to be a starting point and/or project. Right?&lt;/p&gt;

&lt;p&gt;TillWhen was the prototype or experimental product to see if I'd be able to get users without any significant marketing and what that count is going to be, then I'd add up other metrics to see what I can improve on it and once I saw the hypothetical data of what I could do with a full fledged focused project , I sat down and finalised the designs for Taco.&lt;/p&gt;

&lt;p&gt;I could just copy everything from linear and call it a day but the point is to always learn and experiment with things so I sat down to experiment with micro-services for a full app while avoiding any data cloning to be involved and how would I deploy this.&lt;/p&gt;

&lt;p&gt;I came up with a go backend and a decent deployment plan but then I threw that away, started again and we ended up with a simple mono repo with a single stateless backend and frontend and obviously the concerns of UI Components and Shared Logical helpers as the other packages in the repo.&lt;/p&gt;

&lt;p&gt;Also ended up designing a few new components and I now have a base css that I use with basically everything.&lt;/p&gt;

&lt;p&gt;But none of that answers the questions, &lt;strong&gt;Why Project Manager?&lt;/strong&gt; , I could've built anything, why project manager? Simple reason being that I've built versions of it before and it wouldn't be hard to build it as a proper product. My mentality was to build something simple enough to attract at least a small group of people and something I've worked towards enough to be able to build it to a bigger proper project in case it worked out.&lt;/p&gt;

&lt;p&gt;And so Taco,&lt;/p&gt;

&lt;p&gt;The current announcement you are reading is basically for the first alpha release of the product and not an MVP release, the alpha basically means that there's features pending, there's things that are going to keep getting added to it and that's the whole reason you get access to a testing account and not an account of your own. This is to understand and get feedback from you about how things can be improved in the product , because what you see in the product at this stage is good enough for &lt;strong&gt;me&lt;/strong&gt; to work with other than the notes part which I plan to add next weekend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Those are less features than what JIRA/ASANA/Linear/etc etc has!
&lt;/h3&gt;

&lt;p&gt;You wouldn't be wrong in saying that.&lt;br&gt;
My intention isn't to compete with any of the giants, they have teams, investors, other things that I might not even know off. Like most projects by me the first customer of the project is me and the only difference here is that I plan to make it a project where the customer isn't just a single user and hence the alpha stage release , so we carve out a product that's not just built on my thinking of the product.&lt;/p&gt;

&lt;h3&gt;
  
  
  You are wasting time.
&lt;/h3&gt;

&lt;p&gt;Maybe, maybe not. I was happy when TillWhen got 3 users, I was happy when it got 150, that doesn't change for me, I built it. That's all that mattered to me back then and matters to me right now. Commitlog got 50 stars on GitHub, that was my goal for the entire year, I got lucky when it hit that goal in about a month.&lt;/p&gt;

&lt;p&gt;I've got a lot of time, 16 hours every weekend. I spend that on multiple projects, This is just another addition to the list of things I'm going to enjoy building&lt;/p&gt;

&lt;h3&gt;
  
  
  What's special ?
&lt;/h3&gt;

&lt;p&gt;Honestly, nothing during this release.&lt;/p&gt;

&lt;p&gt;There's no USP (Unique Selling Point) , nothing that can get shark tank's attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt; , just like every project by an indie developer, it's built to inspire more developers to build stuff on their own to learn, earn or maybe inspire more people.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's special about it for the consumers, genius.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's see, you get to run the feedback through an actual person instead of a chat bot, you get to request help regarding issues with the person who's actually developing it, the problems get checked by a human (Even if the name is barely human) and not through a 10 step issue validation process.&lt;/p&gt;

&lt;h3&gt;
  
  
  And where do I send this feedback?
&lt;/h3&gt;

&lt;p&gt;You can send this feedback on &lt;code&gt;ahoy@barelyhuman.dev&lt;/code&gt; for the &lt;a href="https://reaper.im"&gt;reaper.im&lt;/a&gt; fans or &lt;code&gt;me@barelyhuman.dev&lt;/code&gt; for the people who'd like to be professional.&lt;/p&gt;

&lt;p&gt;That's about it folks, hope you get through the app and like it, even in the shape that it is in right now.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Updates 15th and 16th May</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 17 May 2021 00:52:28 +0000</pubDate>
      <link>https://dev.to/barelyhuman/updates-15th-and-16th-may-2dcp</link>
      <guid>https://dev.to/barelyhuman/updates-15th-and-16th-may-2dcp</guid>
      <description>&lt;p&gt;I think I should add more tutorials and tips than just post updates but I don't know, I just prefer using the blog as an Update Log, I will try writing more tips and considerations from now on. &lt;/p&gt;

&lt;p&gt;As for now. &lt;/p&gt;

&lt;p&gt;This update log is mostly focused on &lt;strong&gt;Taco&lt;/strong&gt; cause that's all I worked on this weekend. There is a certain parser I wrote for a bit of work from office and it's a small update so let's start with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile Version Sync
&lt;/h3&gt;

&lt;p&gt;So, at &lt;a href="https://fountane.com"&gt;Fountane&lt;/a&gt; we've been getting a lot of hybrid app requests for mobile development recently and it's a pain to keep the NPM, Android(Gradle) , iOS version and build numbers in sync and this causes an issues when things like an Update server are involved. &lt;/p&gt;

&lt;p&gt;I did look up some NPM alternatives for the same but they weren't being maintained much and I didn't want to sit on a fork of a simple tool I could've written (or so I thought) and I got onto it. I already knew the iOS just needed updates in the Info.plist file so that would be a quick thing. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the plist file, parse the xml , edit the &lt;code&gt;CFBundle&lt;/code&gt; properties for the version and build and write it back to the plist, easy. &lt;/li&gt;
&lt;li&gt;Same goes for Android, read the build properties , update the versionName and versionCode, write it back and done. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Much to what I thought, there was no parser for gradle files in golang , so I ended up writing one which took me almost a day because I wanted to handle a few edge cases(not all) that would cause issues during the use case. &lt;/p&gt;

&lt;p&gt;And it's a tightly coupled parser right now, as it's part of the version-sync cli  right now, I'll decouple it as soon as I'm done with Taco, don't want to pause work on Taco and pick up new projects right now. &lt;/p&gt;

&lt;p&gt;If you wish to understand the logic behind the parser, I did write a small prototype for the same in JS before I wrote the actual go lang parser so you can find the JS version on &lt;a href="https://github.com/barelyhuman/gradle-parser-proto"&gt;barelyhuman/gradle-parser-proto&lt;/a&gt; and the go lang cli tool on &lt;a href="https://github.com/barelyhuman/mobile-version-sync"&gt;barelyhuman/mobile-version-sync&lt;/a&gt; , again it's in development and being used for a very specific use case, generalising it is a plan but not till I'm done with the existing project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taco
&lt;/h3&gt;

&lt;p&gt;Trust me, I try to keep these posts short, they just end up being big since I unconsiously add in stuff that I think people should know. &lt;/p&gt;

&lt;p&gt;Back to the topic, we've got the &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth (will be changing to passwordless before release)&lt;/li&gt;
&lt;li&gt;Projects &lt;/li&gt;
&lt;li&gt;Tasks and Tasks Status &lt;/li&gt;
&lt;li&gt;Settings and Plans &lt;/li&gt;
&lt;li&gt;Integration with TillWhen (This one might come as a shock)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Auth
&lt;/h4&gt;

&lt;p&gt;I'm basically done with the Auth part and it used the traditional email and password but I'll be moving it to the magic link setup that TillWhen has once I'm done with the rest of the features, this was done because it's quick and I didn't want to use TillWhen's code because I wanted the code to be concise for this project and TillWhen has patchy code that I didn't want to just copy over. &lt;/p&gt;

&lt;h4&gt;
  
  
  Projects
&lt;/h4&gt;

&lt;p&gt;Simplest one to implement, creation and assignment and visualising of projects is done, here's a preview &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xs1GUa8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-projects-taco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xs1GUa8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-projects-taco.png" alt="Preview Projects Taco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you see is the light version of the screen, the creation is using keyboard shortcuts for now because this is a &lt;strong&gt;developer preview&lt;/strong&gt; and not what the end version will have. You'll have proper buttons to create projects but the keyboard shortcuts are most likely going to come bundled as well. &lt;/p&gt;

&lt;p&gt;The alert icon you see is actually a pulsing icon and I can't really show it well in a picture but it pulses when you are approaching a project deadline.&lt;/p&gt;

&lt;p&gt;The menu on the bottom allows you to go to the project details to check on members and tasks as needed. &lt;/p&gt;

&lt;h4&gt;
  
  
  Tasks and Status
&lt;/h4&gt;

&lt;p&gt;Already implemented this quite a few times now with &lt;a href="https://todo.reaper.im"&gt;todo&lt;/a&gt; and TillWhen also has a beta task list so I don't think I need to explain what and how this is but it's not Kanban, I really don't see the need for someone working to have to go through moving items here and there in a board instead of just marking it as done or any other status, but that's just my thinking and Asana does it well but get's very bloaty in terms of things you can do and you accidentally end up clicking on something you didn't want too. Not what I want from a project manager. &lt;/p&gt;

&lt;p&gt;Here's what the tasks look like right now. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SZac5zyI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-tasks-taco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SZac5zyI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-tasks-taco.png" alt="Preview Tasks Taco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, the creation is left on keyboard for now and the assignment to users and projects is still being done since I need to add filters for the same in a way that doesn't add to the bulk of what you see visually. I'm still working on the UX for the same. &lt;/p&gt;

&lt;p&gt;The squircle dots on the left are the visual representation of the current status of the task and are what you click on to move it up or down, since the concept of backlog doesn't exist right now, it's not in the menu, I do plan to add that later since I use the backlog more than I use the actual task list. &lt;/p&gt;

&lt;h3&gt;
  
  
  Settings and Plans
&lt;/h3&gt;

&lt;p&gt;Nothing huge here, just simple notification settings for now and obviously the ability to update your username, the Plan defaults to &lt;code&gt;Hobby&lt;/code&gt; for everyone right now since the payment gateway etc will need a little more work and that's not going to be a part of the initial release anyway. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PMyXKoZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-general-taco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PMyXKoZo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-general-taco.png" alt="Preview Setting General Taco"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FjluzL_e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-profile-taco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FjluzL_e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-profile-taco.png" alt="Preview Setting Profile Taco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k03-cdGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-billing-taco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k03-cdGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/preview-setting-billing-taco.png" alt="Preview Setting Profile Taco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also since payments are going to be involved I'll have to prepare legal documents for the same and hence the whole billing and card addition is going to part of future releases and not the initial one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integration with TillWhen
&lt;/h4&gt;

&lt;p&gt;Sad to say but I might shut down TillWhen after this particular feature is done and added to the release, this is still in works since both apps need to be updated to be able to do this. The overall plan is for you to be able to export all data from TillWhen and import it on Taco and then taco is where you also handle time logs, so yes while this a big thing to do it is something I do have in mind. Reason being it'll be hard to maintain and work on 2 decently sized projects as an Indie developer.&lt;/p&gt;

&lt;p&gt;Or i can move everything that Taco does into Tillwhen but then that's more patches here and there which I don't want too. Why is TillWhen Patchy? It was built in 2 days, what do you expect ? &lt;/p&gt;

&lt;p&gt;Also I didn't plan scaling, integrations anything, I got lucky with them because of how I write but that's about it. It's got enough hacky and patchy implementations. The slack integration is a joke on it, exactly why Multi Workspace Slack integration on it has not been done yet. I don't want to break the existing implementation thats working well.&lt;/p&gt;

&lt;p&gt;That was a long post...&lt;/p&gt;

&lt;p&gt;Fortunately, that's all.&lt;/p&gt;

&lt;p&gt;Adios!&lt;/p&gt;

</description>
      <category>devjournal</category>
    </item>
    <item>
      <title>The most preferred way to add CI/CD to React Native </title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Tue, 04 May 2021 07:20:41 +0000</pubDate>
      <link>https://dev.to/barelyhuman/the-most-preferred-way-to-add-ci-cd-to-react-native-2jll</link>
      <guid>https://dev.to/barelyhuman/the-most-preferred-way-to-add-ci-cd-to-react-native-2jll</guid>
      <description>&lt;p&gt;I've got a few projects where I need to add in CI/CD for React Native and while I've got fastlane setup and React Native has the environment variables working, my main issue is with the bootstrapping of a new project and having to set all this again. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service Accounts for Play Store &lt;/li&gt;
&lt;li&gt;Gitlab Environment files&lt;/li&gt;
&lt;li&gt;Apple Account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While I know the above can't be given up , I was thinking something on the line's of a bash script that opens up the needed pages during the initial setup so I remember everything that needs to be taken care of before I let gitlab execute everything.&lt;/p&gt;

&lt;p&gt;Would like to know if there's other solutions that people are following. &lt;/p&gt;

</description>
      <category>help</category>
      <category>discuss</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Why I use Next.js for everything and why you shouldn't!</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Tue, 20 Apr 2021 05:19:27 +0000</pubDate>
      <link>https://dev.to/barelyhuman/why-i-use-next-js-for-everything-and-why-you-shouldn-t-1kpp</link>
      <guid>https://dev.to/barelyhuman/why-i-use-next-js-for-everything-and-why-you-shouldn-t-1kpp</guid>
      <description>&lt;p&gt;You can directly read the summary if you'd like to avoid the explanation, Summary&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;I became a &lt;a href="https://vercel.com"&gt;Vercel&lt;/a&gt; (formerly known as Zeit) fanboy and someone who wanted to join their team somewhere around April 2019 when I first discovered &lt;a href="https://zeit.co"&gt;Zeit.co&lt;/a&gt; for app deployments and also found out that most of what I used in terms of libraries and even tools were actually built by them &lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;And I've attempted writing to them a few times in terms of joining the team but with no success of any response so I'm just going to assume it's a &lt;strong&gt;No&lt;/strong&gt;, getting back to the point.&lt;/p&gt;

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

&lt;p&gt;Talking about the foundational framework of TillWhen and a lot of my web apps, mini tools and also the reason I mentioned Vercel first. Vercel is responsible for the Open source framework Next.js which is a SSG (Static Site Generator) based on React much like Gatsby. The reason I picked Next.js was simple&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy base app scaffolding (&lt;code&gt;yarn create next-app &amp;lt;app-name&amp;gt;&lt;/code&gt;) &lt;/li&gt;
&lt;li&gt;Don't have to add a router as the page structure defines routes (an inspiration for the &lt;a href="https://github.com/barelyhuman/statico"&gt;statico&lt;/a&gt; generator and also &lt;a href="https://github.com/barelyhuman/ftrouter"&gt;ftrouter&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;In built API handlers which are written as modules and are pretty scalable if you understand how to structure the routes&lt;sup id="fnref2"&gt;2&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;The Generated HTML works decently with or without JS unless you decide to handle routing programmatically, which you shouldn't but in case you do it might not work without JS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These points aren't unique to Next.js anymore but then the newer frameworks don't really offer anything significant to make me shift to them, If I had to jump out of Next.js I'd jump to Nuxt which is for Vue and just use React as is for other projects, I've given Gatsby a try but I guess I just prefer Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why shouldn't I use Next.js for everything like you do ?
&lt;/h3&gt;

&lt;p&gt;Well, I always say that you decide on tech stack based on intention of what you are building and the target you wish to achieve while building it. &lt;/p&gt;

&lt;p&gt;If the target is &lt;strong&gt;to learn&lt;/strong&gt;, you're better off choosing a tech you haven't used ever. This is how you understand where the tech prevails and where it's going to be a bad option.&lt;/p&gt;

&lt;p&gt;If you choose to &lt;strong&gt;build a quick prototype&lt;/strong&gt;, you choose the tech you are most familiar with, this can be a really old tech and probably obsolete at this point but if you are just testing out an idea or working on seeing if the product is going to gain any traction, you still use what you know has worked for you in the past. &lt;/p&gt;

&lt;p&gt;If you choose to &lt;strong&gt;build for production&lt;/strong&gt;, you take the prototype or concrete requirements and figure out and experiment with tech that was built for this stuff. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Eg:&lt;/em&gt; I built a static generator from scratch for my blog, doesn't mean I'd do it for a client. I'll pick up a battle tested (Wordpress, Ghost, etc) to be my base and hand them that, this can be a bit heavier but is a lot more stable in the long run. On the other hand while doing this you also get ideas as to how you can improve your own scratch built tools to fit more and more scenarios.&lt;/p&gt;

&lt;h4&gt;
  
  
  But you use next for everything
&lt;/h4&gt;

&lt;p&gt;True, now the reason for that is most of what I build is to act as quick prototypes of a certain idea that I had or something I wish to see and re-implement just to understand what's going on in the code when a dev actually built it and if I can improve it. Good examples of this are &lt;a href="https://hen.reaper.im"&gt;Hen&lt;/a&gt; , &lt;a href="https://colors.reaper.im"&gt;Colors&lt;/a&gt;, &lt;a href="//pending.reaper.im"&gt;Pending&lt;/a&gt;, other mini tools that I've built over the years. I do use each of them but they aren't unique concepts and just exist because something from some app inspired me and I just wanted to get down and build a clone to understand it and &lt;strong&gt;this is where it's fine to use a fallback default stack,&lt;/strong&gt; which in my case happens to be Next.js&lt;/p&gt;

&lt;p&gt;The stack may differ for everyone. You might be a Angular + Phoenix or React + Koa or a RoR + React/Angular  monolith person, doesn't matter. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Let's take Hen into consideration here, it's a simple live preview for component code written in React. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I need a SSG for this? Nope.&lt;/li&gt;
&lt;li&gt;Do I need an inbuilt router ? Nope. &lt;/li&gt;
&lt;li&gt;Do I need &lt;code&gt;n&lt;/code&gt; number of imports that come with the added framework ? Nope. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could build Hen with just vanilla JS or just React and that's more than enough. As a matter of fact Hen is built with just React, &lt;a href="https://github.com/barelyhuman/hen-experimental"&gt;Hen Experimental&lt;/a&gt; on the other hand is the repository that holds the unstable and testing code for the original Live Preview attempt and was written in Next.js. &lt;/p&gt;

&lt;p&gt;Point to take from this? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Prototype with a fallback stack and build/re-build it with the shortcomings and advantages with a stack that finds a nice middle ground&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may or may not have to do this with every app you build but it's generally a good idea to find out what the app requirements need , build a dummy version with tech you are quick with, this can even use existing codebase from previous projects etc etc etc, you get the idea. &lt;/p&gt;

&lt;p&gt;Again, you might not have to switch the entire stack and as the experience grows with various technologies you might not even have to build the prototype for a certain set of functionalities, you just know what will work well and what won't but to get there you'll have to experiment first and not take people's word for it (conditional but generally helps to increase your own knowledge and build an independent opinion)&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Have a fallback stack &lt;/li&gt;
&lt;li&gt;Don't use it for everything and anything just because you can, unless it fits with the requirement.&lt;/li&gt;
&lt;li&gt;Have a &lt;strong&gt;Prototype First, Production Later&lt;/strong&gt; mindset to make sure you build something that's a lot more scalable while avoiding monkey patching stuff in the future.&lt;/li&gt;
&lt;li&gt;Experiment with different technologies to build both knowledge and independent opinion, which can then help you make better decisions (I'm saying this with regards to programming, but you can apply this to life in a way as well)&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I used to have &lt;a href="https://hyper.is"&gt;Hyper&lt;/a&gt; as my primary terminal, &lt;a href="https://github.com/vercel/pkg"&gt;pkg &lt;/a&gt; to create executable node binaries, &lt;a href="https://www.npmjs.com/package/ms"&gt;ms&lt;/a&gt; to handle millisecond formatting and no I wasn't sponsored to say this, I actually did use all these libs a lot back then and I had already tried next.js at this point but it was still not production level as a few issues stopped me from using it for prod. Oh and there was release and also I did get inspired by their design system a few times  ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;You can create a huge mess if you write long api paths and don't follow entity based standard while writing routes. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>This Weekend in BarelyHuman Dev Labs - March 10th and 11th</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 12 Apr 2021 06:01:10 +0000</pubDate>
      <link>https://dev.to/barelyhuman/this-weekend-in-barelyhuman-dev-labs-march-10th-and-11th-27f1</link>
      <guid>https://dev.to/barelyhuman/this-weekend-in-barelyhuman-dev-labs-march-10th-and-11th-27f1</guid>
      <description>&lt;h2&gt;
  
  
  Project Updates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  statico
&lt;/h3&gt;

&lt;p&gt;Mentioned that we had a static generator written specifically for reaper.im and all I did was pull it out into a separate repository and is now under the name statico and while it can be used for basic markdown to html page generation while maintaining folder structure&lt;sup id="fnref1"&gt;1&lt;/sup&gt; it's still a very simple generator and not as generic as it should be, it will be as the project progresses.&lt;/p&gt;

&lt;h3&gt;
  
  
  commitlog
&lt;/h3&gt;

&lt;p&gt;There was a little progress in the release command addition to the cli, not a lot and no it's not been pushed, the older release command is still there in the codebase and while functional it doesn't increment the tag as I expected it to be so the cases are still being handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  vscode-monoclean-theme
&lt;/h3&gt;

&lt;p&gt;I started writing a vscode theme long time back, just completed it this weekend and also added a light variant to it. It's only been tested on Go and JS so I'm not sure about the other languages while it shouldn't cause many issues in other languages/workflows , do raise an issue if you do see one. You can find the install instructions and screenshots on github&lt;/p&gt;

&lt;h2&gt;
  
  
  Life Updates
&lt;/h2&gt;

&lt;p&gt;Wasn't able to post last week since there wasn't any progress, I've been sick the past week and wasn't able to pick up anything so there was nothing to post last weekend. Somehow I've caught covid while staying home all day, anyway I don't see any direct symptoms so I'm not that worried but we'll see how it goes.&lt;/p&gt;

&lt;p&gt;In terms of business setup, Tillwhen codebase is to be cleaned and I need a good project management workflow to be setup so I don't treat TillWhen like a side project and just abandon it, which will definitely happen if I don't setup a good workflow forcing me to sit and work on it.&lt;/p&gt;

&lt;p&gt;That's about it for now,&lt;/p&gt;

&lt;p&gt;Adios!&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;You can go through the reaper.im codebase to see what I mean by a simple structure  ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>devjournal</category>
    </item>
    <item>
      <title>Handling heavy memory tasks asynchronously</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Tue, 16 Mar 2021 02:53:45 +0000</pubDate>
      <link>https://dev.to/barelyhuman/heavy-replication-and-batches-3ohp</link>
      <guid>https://dev.to/barelyhuman/heavy-replication-and-batches-3ohp</guid>
      <description>&lt;p&gt;This is going to be both a post to point you to a library I made and also point you to a solution for handling heavier tasks. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer: This is one of many solutions that you can use, I'm just talking about this one since I end up using this a lot more than other solutions, I will mention other solutions though&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As programmers we are given problems that need to be solved or we discover a problem and then sit down to solve it. Once such problem has always been load management, we've got various tools that handle it for us at different levels. &lt;/p&gt;

&lt;p&gt;You've got load balancers for network requests, you've got the ability to scale vertically and horizontally in terms of parallel containers or k8 nodes but let's come to the small section of this, handling load in your actual code. &lt;/p&gt;

&lt;p&gt;I'm not sure if you've come across this but a lot of times you've got like 100s of functions that need to be run parallely or sequentially or even cases where the memory can't handle this run. &lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;A few days back I was working on a small dummy replication server on my Raspberry Pi which hardly had about 100-250mb ram left with all the other hosted services running on it. The replication server was to run my spotify , get all playlists, go through each playlist to get all the tracks and then match these on Apple Music and then sync them to my Apple Music. Why do this? I accidentally deleted my Apple Cloud library (My bluetooth keyboard malfunctioned and instead of deleting a single track, I deleted the entire library) and I need all the tracks back so I wasn't going to do it one by one and I could use SongShift but then it's slow and I'd have to setup multiple runners on it for each playlist and then run them manually so I figured I'd just write a small server for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Limited amount of RAM: 100-250MB &lt;/li&gt;
&lt;li&gt;Number of tracks to process: 2500&lt;/li&gt;
&lt;li&gt;Matching each track takes about : 1s&lt;/li&gt;
&lt;li&gt;total time to be 2500 seconds if done sequentially &lt;/li&gt;
&lt;li&gt;memory usage per track search = 500kb , so about 125MB total to import all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem? I have close to no ram left on the rasp when this runs and using the other hosted services becomes hard cause they need to shift to swap and then it lags. &lt;/p&gt;

&lt;h3&gt;
  
  
  Solution?
&lt;/h3&gt;

&lt;p&gt;There's quite a few solutions here &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message Queues&lt;/li&gt;
&lt;li&gt;In Memory Batches&lt;/li&gt;
&lt;li&gt;DB Queues&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Message queues
&lt;/h4&gt;

&lt;p&gt;Good solution but then I need to add RabbitMQ or redis + msg queue, setup a worker to listen to the queue and a server sending the instructions to the queue, limit the queue to not process more than 10-20 tracks at once. &lt;/p&gt;

&lt;h4&gt;
  
  
  DB Queues
&lt;/h4&gt;

&lt;p&gt;Similar to the message queues but instead I add rows to a &lt;code&gt;queued&lt;/code&gt; table of any existing database on the device and the worker keeps checking it after 10-20 mins to see if it has any new queued tasks and mark them complete when done with , this is simpler to implement and would be a viable solution if you need a  solution that's crash resistant. Message queues though might loose it's messages on crash in certain cases so this might be the most reliable solution to go with. &lt;/p&gt;

&lt;h4&gt;
  
  
  In Memory Batches
&lt;/h4&gt;

&lt;p&gt;Now, as the name says, its similar to the above two but we do it in-memory and yes, I'll loose all progress on a crash but this particular use case doesn't need to know if it's started again so we can go ahead with this and it's simpler if you are doing the same operation again and again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;You cut down the array of items into slices of certain amount, let's say I want to process only 20 tracks at once, then I run the async process and wait for the first 20 to complete. We then add the next 20 and process them and continue in the same manner but do it only in memory and this reduced the usage down to about 10mb of usage while this is running, leaving the remaining memory free to be used by other hosted apps.&lt;/p&gt;

&lt;p&gt;For synchronous you could just slice the array and run a while loop waiting for one to complete before the other starts but incase of async this can be a little more code to write than normal so you might want to use a library. &lt;/p&gt;

&lt;p&gt;I would recommend using one of the following &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/p-map"&gt;p-map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bluebirdjs.com/docs/api/promise.map.html"&gt;bluebird's promise.map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://barelyhuman.github.io/conch/"&gt;conch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though, &lt;strong&gt;p-map&lt;/strong&gt; and &lt;strong&gt;bluebird's promise.map&lt;/strong&gt; will allow you to maintain a queue that always have the mentioned number of promises waiting to be completed so it works like an in memory queue, on the other hand &lt;strong&gt;conch&lt;/strong&gt; will maintain batches and will process it one batch after the other instead of a continous queue, both work well in the case , I just prefer the batching.&lt;/p&gt;

&lt;p&gt;Another live example of this being used would be &lt;a href="https://music.reaper.im"&gt;music&lt;/a&gt;'s import logic, which does something similar but to search youtube with the provided spotify link&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>tutorial</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>what other ci/cds can do this?</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 15 Mar 2021 13:14:16 +0000</pubDate>
      <link>https://dev.to/barelyhuman/what-other-ci-cds-are-that-can-do-this-10ck</link>
      <guid>https://dev.to/barelyhuman/what-other-ci-cds-are-that-can-do-this-10ck</guid>
      <description>&lt;p&gt;So, I was going through a few CI/CD alternatives since Gitlab was down for quite a while today and 2nd time this week so wanted to have a fallback runner for the same. &lt;/p&gt;

&lt;p&gt;I came across &lt;a href="https://buddy.works/"&gt;buddy.works&lt;/a&gt; and I kinda like it but then the memory is kinda limiting on the free plan and the actual reason I chose buddy was that it allows maintaining a mirror of the repository and I can push to it's remote to trigger a build but the it failed on all the builds due to memory limitations and I was thinking if there's other CI/CDs that provide this kind of functionality where I can push a mirror repo to the service. &lt;/p&gt;

&lt;p&gt;It can be a self hosted solution as well&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Weekend Updates -  March 6th and 7th, 2021</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 15 Mar 2021 04:36:32 +0000</pubDate>
      <link>https://dev.to/barelyhuman/weekend-updates-march-6th-and-7th-2021-afb</link>
      <guid>https://dev.to/barelyhuman/weekend-updates-march-6th-and-7th-2021-afb</guid>
      <description>&lt;h2&gt;
  
  
  TillWhen
&lt;/h2&gt;

&lt;p&gt;This week, I wasn't really feeling like developing or working on TillWhen so there are no specific updates there other than a small patch that adds to the authentication check during first render of the app. &lt;/p&gt;

&lt;h2&gt;
  
  
  New Additions
&lt;/h2&gt;

&lt;p&gt;The past week was mostly me working on &lt;a href="http://themer.reaper.im/"&gt;themer&lt;/a&gt; and making fixes and making the code more cleaner and readable in case someone else wants to fix something that isn't working as they expected it to. &lt;/p&gt;

&lt;p&gt;Another project that was created yesterday was &lt;a href="https://github.com/barelyhuman/conch"&gt;conch&lt;/a&gt;, a micro library to handle sequential batch processing of promises for systems that can't handle processing like a 100 promises at once, and also something I needed to regulate for cases where I have to preserve memory usage, though the current logic can be improved a lot. &lt;/p&gt;

&lt;h2&gt;
  
  
  Modified / Feature Upgrades
&lt;/h2&gt;

&lt;p&gt;Other than adding themer to most maintained projects, &lt;a href="https://music.reaper.im"&gt;music&lt;/a&gt; got a UI upgrade and now supports importing spotify playlists into the queue, you can either replace the entire queue with the playlist or add the tracks from the playlist to the existing queue. The keyboard shortcuts it had still work but are not listed on the UI right now , since I haven't figured a good way to show them on the current UI style without making it look odd.&lt;/p&gt;

&lt;p&gt;Minor work includes template updates to the &lt;a href="https://github.com/barelyhuman/ftrouter-templates"&gt;ftrouter-templates&lt;/a&gt; repo, and this includes an experimental cli command that was added to the current &lt;code&gt;master&lt;/code&gt; branch of &lt;a href="https://github.com/barelyhuman/ftrouter"&gt;ftrouter&lt;/a&gt;, it now allows you to init a folder though this is not in any of the official releases tags, also I finally plan to sort the of ftrouter using some cli tool framework first before I release ftrouter onto the npm registry. You can still install it using the git repo as the repo consists of the compiled source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; new-project
&lt;span class="nb"&gt;cd &lt;/span&gt;new-project
ftrouter &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="c"&gt;# which is a shorthand for `ftrouter --init -d .`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an example on how ftrouter works you can check the &lt;a href="https://github.com/barelyhuman/music-server"&gt;music-server&lt;/a&gt; or the minimal template's example which includes both query and param cases as well. &lt;/p&gt;

&lt;p&gt;That's all that I was able to do this weekend, though I plan on focusing a little more on TillWhen next week, let's see if I do.&lt;/p&gt;

</description>
      <category>devjournal</category>
    </item>
    <item>
      <title>Themer and how you can handle dark mode a lot more gracefully.</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Thu, 11 Mar 2021 06:23:51 +0000</pubDate>
      <link>https://dev.to/barelyhuman/themer-and-how-you-can-handle-dark-mode-a-lot-more-gracefully-3hab</link>
      <guid>https://dev.to/barelyhuman/themer-and-how-you-can-handle-dark-mode-a-lot-more-gracefully-3hab</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Mirrored post from &lt;a href="https://reaper.im/blog"&gt;reaper.im/blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few days back I was basically redesigning the long lost &lt;a href="https://todo.reaper.im"&gt;todo&lt;/a&gt; app from my repositories and&lt;br&gt;
I ended up liking my selected color scheme and the dark variant of it. This lead to a simple dark and light toggle that I wrote in about 20 lines of JS, by simply changing a key in the local storage and handling that change and edge case accordingly.&lt;/p&gt;

&lt;p&gt;10 mins after this, I realised the the &lt;a href="https://commitlog-web.herokuapp.com"&gt;commitlog-web&lt;/a&gt; could take advantage of the new color scheme and the web version of it is written in golang and html templates so I needed something vanilla so I just ended up using the above code from the todo implementation. At this point, it's all good, but then a small issue. It'd take the stored theme instead of the system preferred theme only and for someone who's theme changes automatically over the course of the day , this was a problem. &lt;/p&gt;

&lt;p&gt;Now most people would be fine with just the &lt;code&gt;prefers-color-scheme&lt;/code&gt; media query but now I don't assume what scheme the user would want to use for my particular app so I want him to be able to choose between system, light, dark and now this is where &lt;code&gt;themer&lt;/code&gt; got created. &lt;/p&gt;

&lt;p&gt;It's like 200 lines and you can probably understand by reading the source code , but I'll get through the algorithm just in case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/barelyhuman/themer/blob/dev/src/index.js"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, you can just install &lt;a href="https://themer.reaper.im"&gt;themer&lt;/a&gt; and use it if you'd find that easier but here goes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ability to switch between system,light,dark.&lt;/li&gt;
&lt;li&gt;As a developer, the developer experience to just add in one button , point the library to it and have it work seamlessly.&lt;/li&gt;
&lt;li&gt;As a developer, the ability to customize the toggles when needed so a function export that can handle the same context.&lt;/li&gt;
&lt;li&gt;Permanent storage of the selected theme.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Plan&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Since there's a need for context, we are going to use a Prototype Function declaration for this library (more on that in a few mins).&lt;/li&gt;
&lt;li&gt;Ability to customize the button, so the button won't be created dynamically but picked from the config provided to the library, though I wanted a quick setup so the library will handle the icons inside the button, just not the button creation and styling.&lt;/li&gt;
&lt;li&gt;Write a function that can be exposed to the instance so that if needed, the person can create custom toggles programmatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code Flow&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We define a prototype function first. A prototype function is basically the vanilla js way of making/writing classes , give you the ability to add pre-defined methods to an instance created via the function as a constructor, an example of this would be &lt;code&gt;Date&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, first piece of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Themer&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;ol&gt;
&lt;li&gt;We need it to accept a config so that we can select if we want to handle the toggle ourselves or we want the user to handle it for us. Also, we will see if there's an existing theme value the user has or not.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Themer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
   &lt;span class="c1"&gt;// Check if the trigger was passed a class string or an id string and convert it to a proper html node ref&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&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="c1"&gt;// existing state for the theme , fallback to system if nothing is found&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;defaultState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, for the actual toggle, all we do is set the &lt;code&gt;body&lt;/code&gt; tag to have an attribute called &lt;code&gt;data-dark-mode&lt;/code&gt; and if this is present, your &lt;code&gt;css&lt;/code&gt; can over-ride the default light mode variables or you can write custom css with this as a selector.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-dark-mode&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;#121212&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;though, just resetting the variables would be easier, you can find an &lt;a href="https://github.com/barelyhuman/themer/blob/dev/style.template.css"&gt;example here&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All that's left is to find out which theme we are on and which the next one is supposed to be and this is done on the click on the trigger, also, remember we have to expose the function so we have to isolate that logic and also we need to make sure the same functions are also executed when the system preference changes if the set theme is on &lt;code&gt;system&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No use posting the snippet cause that's the whole &lt;a href="https://github.com/barelyhuman/themer/blob/dev/src/index.js"&gt;index.js&lt;/a&gt; which you can read.&lt;/p&gt;

&lt;p&gt;Hope you liked the post, &lt;/p&gt;

&lt;p&gt;Adios!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Improving the UI of an old mini tool</title>
      <dc:creator>Reaper</dc:creator>
      <pubDate>Mon, 08 Mar 2021 02:24:20 +0000</pubDate>
      <link>https://dev.to/barelyhuman/ui-overhaul-79b</link>
      <guid>https://dev.to/barelyhuman/ui-overhaul-79b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Mirrored post from &lt;a href="https://reaper.im/blog"&gt;reaper.im&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm not really good at post titles, so going to keep them short from now.&lt;/p&gt;

&lt;p&gt;A really old project of mine started gaining a bit of attention the past few days and I thought that I've been planning on making it look good for quite a while, I should just sit and redesign it once and for all. &lt;/p&gt;

&lt;p&gt;So, when I woke up at 4 , unable to go back to sleep, I decided to make a design change. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://old.todo.reaper.im"&gt;Old Todo&lt;/a&gt; , this is what it looked like and here's the new one, &lt;a href="https://todo.reaper.im"&gt;Todo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll add an image for everyone else to have a look at&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0t8yEceB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/todo-new-image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0t8yEceB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://reaper.im/assets/todo-new-image.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's go through everything that's there. &lt;/p&gt;

&lt;h1&gt;
  
  
  Features
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;the obvious one first, Dark Mode Support &lt;/li&gt;
&lt;li&gt;Addition of tasks, it's a todo list (what were you expecting?)&lt;/li&gt;
&lt;li&gt;Filter by state, you toggle between, All, Completed, Pending&lt;/li&gt;
&lt;li&gt;Power menu to change theme and filter by state(&lt;strong&gt;coming soon&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;PWA, you can install it if you're using chrome on desktop and Safari (Add to Home) / Chrome (Add to Homescreen) on iOS and Android respectively&lt;/li&gt;
&lt;li&gt;Offline support (cause pwa), and your tasks stay in your browser, there's no sync, though you can share an encoded link to people who you'd want to share the tasks with. &lt;/li&gt;
&lt;li&gt;Import tasks from shared URL into your task (&lt;strong&gt;coming soon&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And as always, it's free. Though you should try supporting the DEV!&lt;/p&gt;

&lt;p&gt;I did end up implementing the same style on other tools as well though. &lt;/p&gt;

&lt;p&gt;What's one project that you think was dead but then someone at random just tells you that they are using it and like it?&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
