<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Boopathi Rajaa on Medium]]></title>
        <description><![CDATA[Stories by Boopathi Rajaa on Medium]]></description>
        <link>https://medium.com/@boopathi?source=rss-bee523716728------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*aA1tbtryHu90UvcdzGtRBg@2x.jpeg</url>
            <title>Stories by Boopathi Rajaa on Medium</title>
            <link>https://medium.com/@boopathi?source=rss-bee523716728------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 09 Apr 2026 18:52:08 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@boopathi/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Service Workers — Gotchas]]></title>
            <link>https://medium.com/@boopathi/service-workers-gotchas-44bec65eab3f?source=rss-bee523716728------2</link>
            <guid isPermaLink="false">https://medium.com/p/44bec65eab3f</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[service-worker]]></category>
            <category><![CDATA[offline]]></category>
            <dc:creator><![CDATA[Boopathi Rajaa]]></dc:creator>
            <pubDate>Mon, 09 May 2016 23:42:57 GMT</pubDate>
            <atom:updated>2016-05-12T12:01:59.158Z</atom:updated>
            <content:encoded><![CDATA[<h3>Service Workers — Gotchas</h3><p>This article requires some understanding of ServiceWorkers. If you’re not familiar with ServiceWorkers, here are some links to help you get started —</p><p><a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">Service Workers: an Introduction | Web Fundamentals | Google Developers</a></p><p>Also, here is a good read —</p><p><a href="https://jakearchibald.com/2014/offline-cookbook/">The offline cookbook</a></p><p>Let’s discuss some of the gotchas when developing a web application with offline capabilities using service workers.</p><p>For the sake of brevity, sw = service workers.</p><h3>3xx — Almost Never</h3><p>Whenever a URL in your application possibly returns a <strong>3xx</strong> response, make sure you know what you’re doing when you handle that request via a Service Worker. The 3xx are a useful way to add some side effects to modify your persistent state (on the server, session entry or some token entry to db which you’re planning to use later, and on the client, cookies) and let the user move on.</p><p>An example is when you have a separate login page for your application.</p><ol><li>When the user visits /login, s/he expects to see the login page</li><li>When the user visits /login when s/he is already logged in, s/he should automatically navigate to the Homepage or Dashboard or similar.</li></ol><p>Do you see the problem already? If so, High Five!!!</p><blockquote>The 3xx itself is not the problem. The <strong>side effect</strong> it causes is the problem we should be aware of and handle.</blockquote><h4><strong>What happens when you cache the login page in sw?</strong></h4><ul><li>User enters /login for the first time. Login page is cached by sw</li><li>User completes login, and s/he is in some other page of the app (let’s not talk about the other 3xxs that you usually do here)</li><li>Some random link takes user to /login <strong>when offline or flaky connection</strong></li><li>CacheFirst (ReadThrough), NetworkFirst or any approach that involves response from Cache will result in her/him <em>seeing the Login page when s/he is already logged in</em>.</li></ul><p>This is one of the corner cases. But it’s an important gotcha that you’ve to plan and handle right from the beginning so that your sw code doesn’t get too complicated or convoluted. One simple solution to the problem is to NOT cache the page that can possibly throw a 3xx. But, it’s not that straightforward to identify. Inside a sw, the only way to make a request is to use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch API</a>. Chrome was the first browser to implement service workers and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch API</a>. Between Chrome 42 and Chrome 46, the sw spec and the fetch standard kept changing — new features were added and the defaults were changing. So if your users are using this range, take a note of this inconsistency —</p><h4>Simply don’t cache</h4><p>For the pages that can possibly throw a 3xx (i.e. it returns a 3xx for some requests and 2xx for some other requests), simply don’t cache stuff.</p><p>Though it is possible to respond with fetch(request), like —</p><pre>self.onfetch = function(event) {<br>  if (event.request.url === &#39;/login&#39;)<br>    event.respondWith(fetch(event.request));<br>};</pre><p>or with <a href="https://github.com/GoogleChrome/sw-toolbox">sw-toolbox</a>,</p><pre>toolbox.get(‘/3xx’, toolbox.networkOnly);</pre><p>it has had its issues in the first half of 2015. Fetching a <em>3xx</em> in service worker resulted in this —</p><ol><li>Browser URL = /301. Service worker handles /301.</li><li>SW: fetch(‘/301&#39;). fetch does the redirect to /200. The <em>.then</em> gets content for 200.</li><li>event.RespondWith(contentFor200)</li></ol><p>So, what’s the problem here?</p><blockquote>The browser URL still remains as /301.</blockquote><p>Oops! This is not the expected behaviour. The browser URL should have changed to /200. This happens in Chrome 42, 43 and one or two more versions. So, if your users use this range, take a note of this before you implement service workers for 3xxs.</p><h4>Can we fix it with some code and dirty checking?</h4><p>Apparently, it’s not so simple. In these versions, the fetch standard says that if the <a href="https://fetch.spec.whatwg.org/#requestredirect">redirect mode</a> is set to “manual”, the behaviour was to change to “follow” by default. And it was removed only in July 2015 by <a href="https://github.com/whatwg/fetch/commit/c5dc81406f588ad6207c61d475c96f7649e40578#diff-1feda49b40370635faef8b655f144f64L3518">this commit</a>. So, this gives us no way to find if a request threw a 3xx by tapping into the request-response lifecycle before the redirection is made. But now, with the latest spec, it is possible to use redirect=manual and know whether it returned a 3xx response (will discuss in later parts of this article).</p><p>Coming back to the same problem, there are some clues to know whether it was a redirect or not.</p><h4>1. request.url !== response.url</h4><p>If the request.url and the response.url does not match, then there is a redirection. But then you’ve to pass this information back to the Document from the serviceWorker and make the browser make a request to the resultant url. This will result in requesting the same resource twice. You can be intelligent about it, but it just ends up in code smell.</p><h4>2. Replace all 3xx with 200</h4><p>One other option is to remove the 3xxs from the server completely by replacing it with 200s with custom headers. Here you’ll be parsing custom headers in your sw code.</p><pre>function redirect(res, url) {<br>  res.header(&#39;X-Redirect-To&#39;, url);<br>  res.end();<br>}<br>app.get(&#39;/301&#39;, function(req, res) {<br>  redirect(res, &#39;/200&#39;);<br>});</pre><h4>3. 3xx via 200 and a script tag</h4><p>Same as the previous approach, but adding a script tag to do the redirection. Send a 200 response with the response body that will rewrite the url.</p><pre>function redirect(res, url) {<br>  res.header(&#39;X-Redirect-To&#39;, url);<br>  res.end(`<strong>&lt;script&gt;location.href=${JSON.stringify(url)}&lt;/script&gt;`</strong>)<br>}<br>app.get(&#39;/301&#39;, function(req, res) {<br>  redirect(res, &#39;/200&#39;);<br>});</pre><p>There is no straightforward way to get this to work on the browsers that was released with sw support in the first 3 quarters of 2015. So in my opinion, these approaches bring you to a point that gets stuff done using a hack. While this is not the best thing to do, it’s an option you can consider. If you find some other way to make it work, kindly leave a comment. Thanks!</p><blockquote>Note: For latest versions of all browsers that follow the latest spec or spec after mid 2015, you don’t have to worry about the above 3 things. It just works.</blockquote><p>The second part of the problem with fetch and sw is detecting a redirect. Let’s say <strong><em>/301</em></strong> returns a, well, 301 to <strong><em>/200</em></strong></p><pre>fetch(&#39;/301&#39;)<br>  .then(response =&gt; {<br>    assert(response<strong>.status</strong> === <strong>200</strong>);<br>  });</pre><p>Note that the response status is not 301. And it is the expected behaviour.</p><h4>RequestRedirect</h4><p>To change the above functionality and get more control, we have the RequestRedirect. <a href="https://fetch.spec.whatwg.org/#requestredirect">redirect</a> is a <a href="https://fetch.spec.whatwg.org/#requestinit">RequestInit</a> option using which you can specify the redirect mode to “follow”(<em>default</em>), “error”, or “manual”. The manual redirect mode allows you to detect the 3xxs.</p><pre>fetch(‘/301’, {<br>  redirect: ‘manual’<br>}).then(resp =&gt; {<br>  assert(resp.type === &#39;<strong>opaqueredirect</strong>&#39;);<br>});</pre><p>One important thing to note here is that — while tapping into the 3xxs gives you more control, it opens up a potential security problem. So you cannot simply get all the data you want from the 3xx. You only get one clue —type= ‘opaqueredirect’ and all other values are nullified — status=0, headers=null, body=null, etc… A brief of the security issue is in the spec —</p><p><a href="https://fetch.spec.whatwg.org/#atomic-http-redirect-handling">Fetch</a></p><p>So with this type=‘opaqueredirect’, you can now know whether a request returned a redirect and you can decide whether to cache or not based on some logic. But there is one gotcha — this is not available in that version range discussed above. You’re better off with a hack than relying on making response redirect work. I’m discussing about this here to let you know that there is a neat way to tap into redirects. You can make use of it in case you’ve no other option.</p><h4>Caching a 3xx response doesn’t make sense</h4><p>Seriously! Think of it as highly opinionated, but trust me, when you make a web app, you’ve to know which URLs can return a 3xx and make sure you don’t ever cache the 3xx response. It simply doesn’t make sense to cache an opaqueredirect response. Also, an opaqueredirect response is treated like an error in fetch.</p><h4>More Discussions</h4><p>Hopefully, this gives you a basic idea. Here are a few more discussions on the same topic, and you’ll probably find a lot more information here —</p><ul><li><a href="https://github.com/whatwg/fetch/issues/66">Allow &quot;manual&quot; redirect fetches with caveats · Issue #66 · whatwg/fetch</a></li><li><a href="https://github.com/whatwg/fetch/issues/79">Add a bit to Opaque Responses to distinguish redirects · Issue #79 · whatwg/fetch</a></li></ul><h3>Include credentials</h3><p>When you make a request for which the server expects some cookies, by default, cookies are NOT sent. And when you make a request for which the server sends some cookies, by default, the response’s Set-Cookie header doesn’t reach the Browser’s Document. This can be fixed by adding the include <a href="https://fetch.spec.whatwg.org/#requestcredentials">credentials</a> option in <a href="https://fetch.spec.whatwg.org/#requestinit">RequestInit</a>.</p><p>For example,</p><pre>fetch(&#39;/200&#39;)</pre><p>the server does NOT see the cookies. And when the server sends a <strong>Set-Cookie</strong> Header, the fetch here in the SW kinda swallows these cookies</p><pre>self.onfetch = function(event) {<br>  event.respondWith(fetch(event.request));<br>};</pre><p>and they don’t reach the Document context.</p><p>For things that require cookies in their transactions, you need to explicitly tell in the Request to include the credentials.</p><pre>fetch(url, { credentials: <strong>&#39;include&#39;</strong> });</pre><h3>Response Race</h3><p>While CacheFirst and NetworkFirst strategies operate based on one fails and the other kicks in, there is one more important strategy for certain things. In sw-toolbox it’s called — ‘<a href="https://github.com/GoogleChrome/sw-toolbox/blob/master/doc-pages/api.md#toolboxfastest">fastest</a>’ where cache and network are requested simultaneously using Promise.race.</p><p>When the request goes out for the first time — race(cache, network),</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/507/1*uKMS2UzZ6Bl67wB3ctEcxw.png" /><figcaption>First time — Cache fails. Network hits and updates cache</figcaption></figure><p>and for all other requests,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*79YqeusdSHPwLcQt15uEKg.png" /><figcaption>All other requests — Cache succeeds first, Network updates cache.</figcaption></figure><p>The <a href="https://github.com/GoogleChrome/sw-toolbox/blob/master/doc-pages/api.md#toolboxfastest">documentation</a> says it all —</p><blockquote>Request the resource from both the cache and the network in parallel. Respond with whichever returns first. Usually this will be the cached version, if there is one. On the one hand this strategy will always make a network request, even if the resource is cached. On the other hand, if/when the network request completes the cache is updated, so that future cache reads will be more up-to-date.</blockquote><h3>Just A Silly Mistake</h3><p>Here are some common silly mistakes that you can catch early and possibly avoid all the pain.</p><h4>url</h4><p>When you bring in one more layer in your request response cycle, you might miss out on some of the parameters. A reminder to you that url is not the only key in a request. It’s not uncommon to make this silly mistake —</p><pre>var <strong>url</strong> = event.request.url;<br>if (url.indexOf(&#39;something&#39;))<br>  return event.respondWith(fetch(<strong>url</strong>));</pre><p>Note the `fetch(url)`. It should simply be `fetch(event.request)`.</p><h4>Streams!!!</h4><p>The request and response are streams. So whenever you’re consuming the body of a stream, you have to make sure that you clone it before consuming it. This is because the body of the stream can be consumed only once. Cloning the Request and Response streams are as simple as —</p><pre>var reqClone = event.request.clone();<br>var respClone = response.clone();</pre><h4>SW Kill Switch</h4><p>When you get your ServiceWorker wrong, it’s hard to make it right. What does it even mean? Say you’ve made a mistake that all your pages are broken when it passes through sw fetch and a stale cache always kicks in. This is bad and one way to fix it on your system is to kill the serviceworker from devtools. But when you ship it to users, you can’t ask all of your users to kill the serviceworker or force refresh your page a few times whenever you correct some mistake.</p><p>A Service Worker updates itself by checking the byte diff with the new service worker when available. It tries this update process upon navigation respecting the freshness headers and <a href="https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md#updating-a-service-worker">the sw explainer gives a detailed description of the same</a>. For simplicity, let’s say the automatic update happens once in ~24 hours. And to update a service worker all you need to do is to change the contents of the file so that there is a diff. A simple —</p><pre>const VERSION = 42;</pre><p>will be enough. Incrementing this number will update the service worker in next load. This is mainly useful for cache invalidation —</p><pre>const CACHE_NAME = &#39;my-awesome-site-cache-&#39; + VERSION;</pre><p>When you use this ‘VERSION’ as a part of the Cache name, it invalidates the previous cache completely and new caches are populated. This undocumented feature is called the Service Worker Kill Switch.</p><p>Added to the VERSION parameter, you can also call the <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update">update method</a> in ServiceWorkerRegistration object —</p><pre>navigator<br>  .serviceWorker<br>  .register(&#39;/sw.js&#39;)<br>  .then(registration =&gt; {<br>    button.onClick = () =&gt; registration.<strong>update()</strong>;<br>    window.onSomethingHappened = () =&gt; registration<strong>.update()</strong>;<br>  })</pre><p><strong>registration.update()</strong> will try for a new update of service worker bypassing the ~24 hour update check. Note that the byte diff requirement still applies.</p><h4>Kill Switch 1</h4><p>If you see some users getting cross site scripting attacks and you want to clear all the site’s information on the user’s device, this Spec comes in handy and it’s called the Kill Switch —</p><p><a href="https://w3c.github.io/webappsec-clear-site-data/#example-killswitch">Clear Site Data</a></p><p>Sending the header ‘Clear-Site-Data’ is a useful way to mitigate these attacks. Also, from an example in the spec —</p><blockquote>Installing a Service Worker guarantees that a request will go out to a server every ~24 hours. That update ping would be a wonderful time to send a header like this one in case of catastrophe.</blockquote><h4>Don’t generate dynamic sw code</h4><p>If you’re going to generate dynamic sw code, say https://example.com/sw.js?foo=bar, don’t do it, because it brings in potential XSS attacks, say ‘bar’ is used in the script.</p><blockquote><strong>That’s all Folks!</strong></blockquote><p>There are a few other gotchas that I probably missed. Will write a Part-2 for the same. The epilogue is that there are some hidden things that are not obvious for the first timers, and it might require reading some parts of the Specification a few times. It helps both ways, you can improve your code as well as help improve the specification. Here is the spec —</p><p><a href="https://www.w3.org/TR/service-workers/"></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=44bec65eab3f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Flipkart Lite — The how?]]></title>
            <link>https://medium.com/@boopathi/flipkart-lite-the-how-f6eb311dc943?source=rss-bee523716728------2</link>
            <guid isPermaLink="false">https://medium.com/p/f6eb311dc943</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[flipkart-lite]]></category>
            <category><![CDATA[progressive-web-app]]></category>
            <dc:creator><![CDATA[Boopathi Rajaa]]></dc:creator>
            <pubDate>Fri, 18 Mar 2016 01:06:46 GMT</pubDate>
            <atom:updated>2016-03-21T13:13:23.637Z</atom:updated>
            <content:encoded><![CDATA[<p>To know what Flipkart Lite is, read this article by <a href="https://medium.com/u/eff0159032d0">Aditya Punjani</a> on the story behind building the Progressive Web App,</p><p><a href="https://medium.com/p/2c211e641883">Building Flipkart Lite: A Progressive Web App</a></p><p>Also, this article is cross posted here at the Official Flipkart Tech Blog — <a href="http://tech-blog.flipkart.net/2016/03/flipkartlite-the-how/">http://tech-blog.flipkart.net/2016/03/flipkartlite-the-how/</a></p><p>Well, where do I even start? The following is the list of most of the tech behind Flipkart Lite in NO particular order. Many thanks to all the authors and contributors of these tools, libraries, frameworks, specification etc…</p><h4>Front-end:</h4><ul><li><a href="https://github.com/facebook/react">React</a></li><li><a href="https://github.com/rackt/react-router">react-router</a></li><li><a href="https://github.com/flipkart-incubator/phrontend">phrontend</a> (+ <a href="https://github.com/facebook/flux">flux</a>)</li><li><a href="https://github.com/GoogleChrome/sw-toolbox">sw-toolbox</a></li></ul><h4>Tools — Build and Serve:</h4><ul><li><a href="https://nodejs.org/">NodeJS</a> + <a href="https://expressjs.org/">ExpressJS</a></li><li><a href="http://babeljs.io/">Babel</a></li><li><a href="https://webpack.github.io/">Webpack</a></li><li><a href="https://github.com/webpack/css-loader">css-loader</a> (for <a href="https://github.com/css-modules/css-modules">css-modules</a>) —</li><li><a href="https://github.com/postcss/postcss">Postcss</a> (+ <a href="https://github.com/postcss/autoprefixer">autoprefixer</a>, <a href="https://github.com/cssnext/cssnext">cssnext</a>)</li></ul><h4>Web platform:</h4><ul><li><a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">Service Workers</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch API</a></li><li><a href="https://developers.google.com/web/updates/2015/03/push-notifications-on-the-open-web">Push API</a></li><li><a href="http://www.html5rocks.com/en/tutorials/speed/layers/">GPU Accelerated Compositing</a></li><li><a href="https://developer.chrome.com/multidevice/android/installtohomescreen">Installable web apps - Add to HomeScreen</a></li><li><a href="https://developers.google.com/web/updates/2015/10/splashscreen">Splash Screen</a></li></ul><p>And a few more that I’m probably missing.</p><p>Some of the things listed above come with the tag “<strong>Experimental Technology</strong>”. But, trust me, take a leap of faith, play around, implement it in your app and push it to production. You’ll definitely feel proud.</p><h3>The Monolith</h3><p>The architecture decision started with choosing between “One big monolith” and “Split the app into Multiple Projects”. In our previous projects we had one big monolith repository and the experience getting one’s code to master wasn’t pleasant for many of the developers. The problem having all developers contributing to one single repository is — facilitating them to push their code to production quickly. New features flow in every day and the deployments kept slowing down. Every team wants to get its feature into master and effectively into production ASAP. The quintessential requirement of every single person pushing his/her code to his/her branch is that it should get reviewed and merged in the next hour, pushed to a pre-production like environment in the next 5 minutes and ultimately production on the same day. But how can you build such a complicated app from scratch right from the day 1.</p><blockquote>We started with a simple system and added complexity</blockquote><h4>Separate concerns</h4><p>The goal was to have the following DX(Developer Experience) properties,</p><ul><li>To develop a feature for a part of the application, the developer needs to checkout only the code for that particular application</li><li>One can develop and test one’s changes locally without any dependencies on other apps</li><li>Once the changes are merged to master, these changes should be deployed to production without depending/waiting on other applications</li></ul><p>So we planned to separate our app into different projects with each app representing a product flow — ex: Home-Browse-Product or the pre-checkout app, Checkout app, Accounts app, etc… but also not sacrificing on some of the common things that they can share with each other. This felt like restricting usage in technology. But everyone agreed to use React, Phrontend and webpack :). So it became easy to add simple scripts into each of the project and automate the build and deploy cycles.</p><p>Out of these different apps, one of them is the primary one — the Home-Browse-Product app. Since the user enters Flipkart Lite through one of the pages in this app, let’s call it the “main” app. I’ll be talking only about the main app in this article as the other apps use a subset of tooling and configuration the same as in the “main” app.</p><h3>Home-Browse-Product</h3><p>The “main” app takes care of 5 different entities. Since we use webpack, each of the entities just became a webpack configuration.</p><ul><li><strong><em>vendors.config.js</em></strong> : react, react-router, phrontend, etc…</li><li><strong><em>client.config.js</em></strong> : client.js → routes.js → root component</li><li><strong><em>server.config.js</em></strong> : server.js → routes.js → root component</li><li><strong><em>hbs.config.js </em></strong>: hbs-loader → hbs bundle → &lt;shell&gt;.hbs</li><li><strong><em>sw.config.js</em></strong> : sw.js + build props from client and vendor</li></ul><h4>vendors.config.js</h4><p>This creates a bundle of React, react-router, phrontend and a few other utilities.</p><pre>{<br>  entry: {<br>    react: &quot;react&quot;,<br>    &quot;react-dom&quot;: &quot;react-dom&quot;,<br>    &quot;react-router&quot;: &quot;react-router&quot;,<br>    phrontend: &quot;phrontend&quot;,<br>    ...<br>  },<br>  output: {<br>    library: &quot;[name]&quot;,<br>    libraryTarget: &quot;this&quot;,<br>    ...<br>  },<br>  plugins: [<br>    new webpack.optimize.CommonsChunkPlugin({ name: &quot;react&quot; }),<br>    new CombineChunksPlugin({ prelude: &quot;react&quot; })<br>  ]<br>}</pre><p>This is roughly the configuration for the vendors js. We tried different approaches and this worked for us. So the concept is to</p><ul><li>specify different entry points</li><li>use CommonsChunkPlugin to move the runtime to this chunk</li><li>use <a href="https://gist.github.com/boopathi/33a98faef4fef00d22a3">CombineChunksPlugin</a> (I’ve uploaded the source <a href="https://gist.github.com/boopathi/33a98faef4fef00d22a3">here</a>) to combine all the chunks to one single file with the runtime chunk at the top</li></ul><p>As a result, we get one single file — <strong><em>vendors.&lt;hash&gt;.js,</em></strong> which we then sync to our CDN servers.</p><p>The vendors list is passed down the build pipeline to other apps as well and each of them (including main) externalise the vendors so as to be used from vendors.bundle.js,</p><pre>{<br>  externals: vendors<br>}</pre><h4>client.config.js</h4><p>As the name says, it is the configuration to build the app. Here we do minification and extraction of css into a single file.</p><h4>server.config.js</h4><blockquote>Why do we even need a server.config.js ? Why do we need to bundle something for server?</blockquote><p>We use webpack heavily and we rely on some conventions — we add custom paths to module resolution, import css files, use ES6 code, and node cannot understand most of this natively. Also, we don’t want to bundle every single dependency into one single file and run it with node. Webpack provides a way to externalise those dependencies leaving the requires for those externals untouched and this is one way of doing it,</p><pre>var nodeModules = {};<br>fs.readdirSync(‘node_modules’).filter(function(m) {<br>  return [‘.bin’].indexOf(m) === -1;<br>}).forEach(function(m) {<br>  nodeModules[m] = ‘commonjs2 ‘ + m;<br>});</pre><p>and in the webpack configuration,</p><pre>{<br>  output: {<br>    libraryTarget: &quot;commonjs2&quot;,<br>    ...<br>  },<br>  externals: nodeModules,<br>  target: &quot;node&quot;<br>}  </pre><h4>sw.config.js</h4><p>The sw.config.js bundles sw-toolbox, our service-worker code and the Build versions from vendors.config.js and client.config.js. When a new app version is released, since we use [hash]es in the file names, the URL to the resource changes and it reflects as a new sw.bundle.js. Since we now have a byte diff in the sw.bundle.js, the new service worker would kick in on the client and update the app and this will work from the next Refresh.</p><h4>hbs.config.js</h4><p>We use two levels of templating before sending some markup to the user. The first one is rendered during the build time <strong><em>hbs</em></strong> → <strong><em>hbs</em></strong>. The second one is rendered during runtime <strong><em>hbs</em></strong> → <strong><em>html</em></strong>. Before proceeding further into this, I’d like to talk about HTML Page Shells and how we built them with react and react-router.</p><h3>HTML Page Shells</h3><p>Detailed notes on what HTML Page shells or Application Shells are are given here — <a href="https://developers.google.com/web/updates/2015/11/app-shell">https://developers.google.com/web/updates/2015/11/app-shell</a> . This is how one of our page shells look like —</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c_eoTUkqKcKCdPXd6hB5mg.png" /></figure><p>The left image shows the “pre-data” state — the shell, and the right one is the “post-data” state — the shell + content. One of the main things this helps us in achieving is this —</p><blockquote>Perceived &gt; Actual</blockquote><p>It’s been a thing for quite some time that what the user perceives is the most important in UX. For example, splashscreen — it informs that something is loading and gives the user some kind of progress. Displaying a blank screen is no use to the user at all.</p><blockquote>So I want to generate some app shells. I have a react application and I’m using react-router. How do I get the shells ?</blockquote><h3>Gotchas ? maybe.</h3><p>We did try some stuff and I’m going to share what worked for us.</p><h4>componentDidMount</h4><p>This is a lifecycle hook provided by React that runs ONLY on the Client. So on the server, the render method for the component is called but componentDidMount is NOT invoked. So, we place all our API calling Flux actions inside this and construct our render methods for all our top level components carefully such that once it renders, it gives out the Shell instead of throwing an empty container.</p><h4>Parameterised Routes</h4><p>We decided that we would create shells for every path and not a simple generic one that you can use for anything. We found all the paths that the application used and would use. We wrote a small script that iterated through all the routes we defined to react-router and we had this —</p><pre>/:slug/p/:itemid<br>/(.*)/pr<br>/search<br>/accounts/(.*)</pre><p>During build time, how can you navigate to a route (so as to generate HTML Page Shells for that route), with an expression in the route that is resolved only during run time ?</p><blockquote>Hackity Hack Hack Hack</blockquote><p>React-router provides a utility function that allows you to inject values to the params in the URI. So it was easy for us to simply hack it and just inject all the possible params in the URIs.</p><pre>function convertParams(p) {<br>  <strong>return</strong> PathUtils.injectParams(p, {<br>    splat: &#39;splat&#39;,<br>    slug: &#39;slug&#39;,<br>    itemId: &#39;itemId&#39;<br>  });<br>}</pre><p><em>Note</em>: We used react-router 0.13. The APIs might have changed in later versions. But something similar would be used by react-router.</p><p>And now we get this route table.</p><pre><strong>Route Defined     </strong>→ <strong>Route To Render</strong>    → <strong>HTML Page Shell<br></strong>/:slug/p/:itemid  → /slug/p/itemId     → product<br>/(.*)/pr          → /splat/pr          → browse<br>/search           → /search            → search<br>/accounts/(.*)    → /accounts/splat    → accounts</pre><p>It simply works because the shell we are generating does NOT contain any content. It is the same for all similar pages (say product page).</p><h4>Two-level templating</h4><p>We are back to <em>hbs.config.js</em>. So we have one single hbs file — <strong>index.js</strong> with the following content.</p><pre>// this is where the build time renderedApp shell goes in<br>// React.renderToString output<br>&lt;div id=&quot;root&quot;&gt;{{content}}&lt;/div&gt;</pre><pre>// and some stuff for second level<br>// notice the escape<br>&lt;script nonce=&quot;\{{nonce}}&quot;&gt;<br>&lt;script src=&quot;\{{vendorjs}}&quot;&gt;&lt;/script&gt;<br>&lt;script src=&quot;\{{appjs}}&quot;&gt;&lt;/script&gt;</pre><p><strong><em>Build time rendering</em></strong>: For each type of route, we generate a shell with $content injected into index.hbs and get the hbs for that particular route, example — product.hbs</p><p><strong><em>Runtime rendering</em></strong>: We insert all the nonce, bundle versions and other small variables into the corresponding app shell hbs and render it to the client.</p><p>The good thing is that the user gets a rendered html content before static resources load, parse and execute. And this will be faster than server-side rendering, as this is as good as serving a static HTML file. The only variables in the template are a few numbers that are fetched by in-memory access. This improves the response-time and the time to first paint.</p><h3>The end</h3><p>And with all this and a lot of gotchas that I missed out, we put Flipkart Lite into production successfully. Oh wait! This didn’t start as a story. Anyway. Thanks for reading till here.</p><h4>…</h4><p>All the solutions described above are NOT necessarily the best solutions out there. It was one of our first attempts at solving them. It did work for us and I’m happy to share it with you. If you find improvements, please do share it :).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f6eb311dc943" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[It’s the future]]></title>
            <link>https://medium.com/@boopathi/it-s-the-future-7a4207e028c2?source=rss-bee523716728------2</link>
            <guid isPermaLink="false">https://medium.com/p/7a4207e028c2</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[front-end-development]]></category>
            <dc:creator><![CDATA[Boopathi Rajaa]]></dc:creator>
            <pubDate>Tue, 09 Jun 2015 23:43:18 GMT</pubDate>
            <atom:updated>2015-06-20T08:43:52.534Z</atom:updated>
            <content:encoded><![CDATA[<p>This post is just for joke and means no harm to any of the tools and libraries mentioned below. I’m using them all the time, it’s amazing and I’d always recommend them.</p><p>This is heavily inspired from CircleCI’s blog post ‘It’s the Future’ and expresses the same in another perspective.</p><p><a href="http://blog.circleci.com/its-the-future/">It&#39;s The Future | The Circle Blog</a></p><p>Hey, I&#39;d like to learn to write rich web applications. I hear you&#39;ve got a bit of experience in that area.</p><p>:<em> Yeah. I&#39;m a front-end guy, using a couple of tools and techniques to build web applications.</em></p><p>Cool. I&#39;m building a simple web app at the moment — a normal TODO app using HTML, CSS and JavaScript, and I’m planning to use JQuery. Is that the way to go ?</p><p>: <em>Oh, no. That’s old school. JQuery is dead — no one uses it anymore. You need to use React now. That’s the future.</em></p><p>Oh. Okay. What’s that ?</p><p>: <em>React is the new way of building web apps. It uses a Virtual DOM implementation underneath and lets you write JSX code.</em></p><p>Virtual… what ? JSX ? What’s that ?</p><p>: <em>JSX — It’s HTML on steroids. It’s an extended version of JavaScript where you mix XML and JS in the same code. VirtualDOM — You’d have a tree of custom objects representing part of the DOM, and it gives the ability to manipulate these objects very quickly without touching the actual DOM.</em></p><p>What is mixing XML and JS ?</p><p>: <em>Ok. Look. React is the future. It lets you create components as reusable entities.</em></p><p>Oh. So you mean like Backbone views ?</p><p>: <em>No. Backbone is dead. Everything is going to be components now.</em></p><p>So. I don’t need to know about JSX or VirtualDOM ?</p><p>: <em>No. You still need to know the underlying concepts, so you can write code without worrying about operations being costly and optimize places where it ll actually be — like the component’s state.</em></p><p>Okay. I’m getting lost here. There is this thing to build components, called React. Can I use it with JQuery ?</p><p>:<em> Well. React does allow you to build only part of the application and the rest with your choice. But I told you, JQuery is dead. You&#39;d want to use webpack to bundle your components together.</em></p><p>OK. What’s that?</p><p>: <em>It’s a module bundler. You write a bunch of files as you&#39;d write node modules, and you just combine them to form a single file / chunks of files to serve to the client. Also, you don&#39;t even need react-tools, you just need babel to compile JSX.</em></p><p>Babel ?</p><p>: <em>Yeah. Babel. It’s this cool tool that can transpile your ES6+, JSX code to readable ES5 code with the support for sourceMaps, and it’s widely adopted even Facebook uses it.</em></p><p>ES6+ ?</p><p>: ES6/ES2015 is <em>the next version of EcmaScript where you have so many new features like classes, arrow functions, maps, sets, etc… Almost everyone uses ES6+ code to write their applications.</em></p><p>Is that good ?</p><p>: <em>Of course it’s good. ES6+ + transpiling is the future.</em></p><p>Okay. How do I use it ?</p><p>: <em>You start by installing Node…</em></p><p>Install Node? No no no… You were saying something about React and components.</p><p>: <em>Yeah. So you have the flux application architecture pattern and you create your actions, stores and components…</em></p><p>Flux ?</p><p>: <em>With flux, you build your app as stores, actions and views where data flow is in one direction. Views trigger actions, that runs through a dispatcher and stores listen to dispatcher and emit change events which the view again listens to.</em></p><p>Ah. Like MVC ?</p><p>:<em> No. MVC is dead. Flux is the future. There are many many flux implementations out there.</em></p><p>What? Flux implementation ?</p><p>: <em>Yeah. Flux is a pattern. Just look it up, #alt, #flummox, #marty, #fluxxor, #fluxible, etc… and there is a Dispatcher that is implemented by Facebook.</em></p><p>Why don&#39;t I just use the Facebook’s thing ?</p><p>: <em>It gets complex to write all the boilerplate code efficiently as a beginner, so you start with one of the existing implementations.</em></p><p>OK. Yeah. I really don&#39;t want to do hard boilerplate code.</p><p>: <em>Well. Yeah. As I said, there are some existing implementations.</em></p><p>What about angular?</p><p>:<em> Ew</em></p><p>Ew?</p><p>: <em>Ew</em></p><p>Look. I really don&#39;t want to go through the headache of bootstrapping complex code.</p><p>: <em>No. It’s really easy. There are some starter kits/repos, or there are some yeoman generators to do that for you.</em></p><p>I need a generator ? Yeoman ? What’s that ?</p><p>: <em>It can generate code for you, and you can use it to create multiple apps. Use webpack’s new DLL support to build every single app separately as well as together.</em></p><p>I’ll have only one app, page or component, whatever. Just one of them</p><p>: <em>No. Look into composable components. It’s how we do everything now. You need to break down into components — one for every small entity.</em></p><p>That seems excessive</p><p>: <em>It’s the only way to make sure it’s clean, developer friendly as well as performant. So you can do things like hot-reload…</em></p><p>Hot Reload ? Like livereload ?</p><p>: <em>No. Webpack supports this amazing feature called hot module replacement, and there is a react-hot-loader for react where you can tweak a single component in isolation without reloading the entire page. And with your flux actions, you can do crazy things like replay your actions with live editing your code seamlessly.</em></p><p>Okay. So I&#39;ve got dozens of tools and libraries for building, bundling, transpiling, whatever. Now what?</p><p>:<em> I was saying. Flux — It lets you architect your applications well. With Observables and Immutable data, it gets nicer and interesting.</em></p><p>Observable ? I need immutable data ?</p><p>: <em>You need observables to neatly handle events and a few other asynchronous calls and Immutable data for persistence, efficiency and simplicity. Observables are an asynchronous plural primitive analogous to arrays in the synchronous world. Observables are expected to be the return values of an ES2016 async-generator function.</em></p><p>What’s async generator ?</p><p>: <em>See. A generator function modifies a function and causes it to return multiple values, an async modifier causes a function to push their values in future. So an async generator function is a combination of both — yield multiple values in future. But the author, Jafar Husain, has withdrawn this proposal and is working with Kevin Smith towards a smaller-scoped es-observable proposal for ES7/ES2016.</em></p><p>Sigh. I just want to launch a simple app. How much deeper does it get ?</p><p>: <em>Well. You can use RxJS which is close to the observable spec. It’s widely used and production ready.</em></p><p>RxJS ? Why is this useful ?</p><p>: <em>It plays nice with your existing promises, events ecosystem. You can create an Observable from any asynchronous code, and treat it like a first class citizen, pass around, handle async values, handle errors etc… Well, if you&#39;re looking for something truly Reactive and interesting, check out cycle framework by Andre Staltz.</em></p><p>WTF. I just want to build a simple app and demo it. Will I be able to do it ?</p><p>: <em>Sure. I mean deploying it might be another interesting topic altogether, but you&#39;re basically there.</em></p><p>I see. Okay. I think I understood something. Thanks for explaining.</p><p>: <em>Great! No problem</em></p><p>Let me just repeat some of what I&#39;ve got it right.</p><p>: <em>Sure!</em></p><p>So I need to split my application code into actions, stores and components following one directional data flow, write ES6+ code which would allow me to use the latest features and let me write clean code, use babel to transpile this ES6+ code into ES5 code which all browsers can parse, use webpack to join all the files written as node modules, use ImmutableJS to represent all my data and RxJS for all my events and other asynchronous functions.</p><p><em>: Yes. Isn’t it glorious ?</em></p><p>I think I forgot about static content, and minification.</p><p>: <em>Not a problem at all. Webpack allows you to import them. All you have to do is configure some loaders, plugins and you&#39;re basically done. You can import component level stylesheets and images and use them with this setup. There are other alternatives to stylesheets where you can write CSS in JS.</em></p><p>I’m going back to JQuery.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7a4207e028c2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Promises in JavaScript]]></title>
            <link>https://medium.com/@boopathi/promises-in-javascript-6a4a70db7b67?source=rss-bee523716728------2</link>
            <guid isPermaLink="false">https://medium.com/p/6a4a70db7b67</guid>
            <category><![CDATA[asynchronous]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[promises]]></category>
            <dc:creator><![CDATA[Boopathi Rajaa]]></dc:creator>
            <pubDate>Fri, 29 May 2015 07:22:17 GMT</pubDate>
            <atom:updated>2015-05-29T07:25:43.782Z</atom:updated>
            <content:encoded><![CDATA[<p>In JavaScript, most of the code that we write falls under asynchronous programming. Whenever we pass an argument as a function and expect this function to run sometime in future, we’re dealing with something asynchronous. And it isn’t always nice to have callbacks as the preliminary entities for async. We frequently end up with this</p><pre>a(&#39;a&#39;, function() {<br>  b(&#39;b&#39;, function() {<br>    c(&#39;c&#39;, function() {<br>      d(&#39;d&#39;, function() {<br>        console.log(&#39;WTF!!!&#39;);<br>      });<br>    });<br>  });<br>});</pre><p>and it was never nice to add one more function to represent your idea into code via callbacks. Promises are a big step towards solving this issue. The following tutorial on Promises by <a href="https://twitter.com/jaffathecake">Jake Archibald(@jaffathecake)</a> is one of the best out there. I’d recommend reading it if you’re new to Promises.</p><p><a href="http://www.html5rocks.com/en/tutorials/es6/promises/">Learn</a></p><h4>The analogy</h4><p>In the synchronous world, the primitives are <strong>values</strong>.</p><pre>var foo= 5;<br>var bar = {};<br>var baz = &#39;dice&#39;;</pre><p>So, in the asynchronous world, we need something that can be used as a neat representation of <strong>async values</strong>. When an asynchronous function is invoked, instead of returning the value immediately, it returns a placeholder for the value — a Promise and this placeholder provides a way to ask for the actual value.</p><pre>var promise = asyncfn();</pre><p>That’s it and we can pass this value around. A better overview of this entire space can be found in the General Theory of Reactivity (gtor) by <a href="https://twitter.com/kriskowal">Kris Kowal</a>.</p><p><a href="https://github.com/kriskowal/gtor">kriskowal/gtor</a></p><h4>A Stateful Machine</h4><p>Promises are stateful objects themselves and can exist in one of these three states: <em>unfulfilled</em>, <em>resolved</em>, <em>rejected</em>. It’s state properties —</p><ul><li>When a promise is created, it is always in the unfulfilled state</li><li>Once a promise changes its state from unfulfilled to either resolved or rejected, it cannot change again</li><li>If you’re adding to the tip of a Promise chain, you’re creating a new Promise and the state properties apply</li></ul><h4>First class citizen</h4><p>A promise can be treated as a first-class citizen resolving to a JavaScript value in future. Once a promise has been created, the value it resolves to has the same properties as a normal JavaScript value. To understand this better, let’s take an example,</p><pre>var x = 1;<br>var y = x + 5;</pre><p>and,</p><pre>var x = delay1s(1);<br>var y = x.then(function(val) { return val + 5; });</pre><p>As you can see the analogy, in both the programs, x can be used even after y has consumed x. And the original value of x, sync or async, doesn’t change.</p><h4>Single output pattern</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/362/1*vy2Us0_DQleY-_-iXwfkwg.png" /></figure><p>This is a very common pattern (in structured programming) where you start with an async value (a Promise) and at every stage you’re storing only the tip of the chain. So all branches created eventually merge using <em>all / race</em>. Storing mid-references are not allowed or the notion of stored mid references becomes irrelevant. During branching you only store until all branches are merged back. The ES7 async/await enforces this single output pattern through its syntax.</p><h4>Concurrent usage pattern</h4><p>This is also a legitimate use case for Promise. With this, you can create custom concurrent executional paths and may expose any intermediate promise. Usually, this is hidden using some higher level abstractions and what gets exposed is determined by the abstraction rules. It uses branching and merging underneath.</p><h4>The Mutate anti-pattern</h4><p>Take this example — A promise that resolves to an <em>Object</em> after <em>100ms</em>.</p><pre>var promise = delay(100).then(_ =&gt; ({ a: 5 }))</pre><p>Objects are mutable in JavaScript and are passed by references. When you branch this promise out,</p><pre>var x = promise.then( v =&gt; { v.a = 6; return v })<br>var y = promise.then( v =&gt; { console.log(v); return v })</pre><p><em>The anti-pattern</em>: the tip <em>x</em> has a consumer that modifies v<br><em>Side-effect</em>: the tip y gets a value where <em>v.a</em> is <em>6</em>, where you’d expect <em>v.a</em> to be <em>5</em>.</p><p>I’d recommend further reading about Promise anti-patterns in bluebird’s documentation.</p><p><a href="https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns">petkaantonov/bluebird</a></p><h4>Epilogue</h4><p>Promises are the asynchronous primitives in JavaScript analogous to values which are synchronous primitives. There is a lot more to talk about promise based async programming patterns — I’d hopefully try that in my future posts after a few clarifications and learnings.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6a4a70db7b67" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The journey is the Reward]]></title>
            <link>https://medium.com/@boopathi/the-journey-is-the-reward-3e4100116c30?source=rss-bee523716728------2</link>
            <guid isPermaLink="false">https://medium.com/p/3e4100116c30</guid>
            <dc:creator><![CDATA[Boopathi Rajaa]]></dc:creator>
            <pubDate>Sat, 19 Jul 2014 17:57:31 GMT</pubDate>
            <atom:updated>2014-07-19T17:57:31.074Z</atom:updated>
            <content:encoded><![CDATA[<h4>A trek to Kumara Parvatha</h4><p>“Dae, vetti(jobless) fellow. It’s time to wake up. We reached”, said Chakra, my roommate. It was a 6 hour journey from Bangalore to Kukke. I was struggling to open my eyes to get a clear vision of the world outside. There weren’t anyone around, “Time’s up! Freshen up guys”, said Prassanna, our Trek coordinator. With a 15% awaken mood, I walked into the room at Kukke and lied down to take a nap for a few more minutes (…) and we reached the starting point of the trek. The coordinator was giving some insights of how it is going to be while I was observing the surroundings. There were fences all around, most of ‘em broken, and there was one tiny path which led to a picturesque view of sparsely dense forest. We started walking towards it and our journey began here.</p><p>It was around 7.30 in the morning, the climate was awesome — humid cold air, wet path and rising Sun which intermittently showed its face, and an exuberant team, where each one of us had a profound trekking experience. After 30 minutes, Chakra and I started racing towards the mid-point of the 14 KM trail to Kumara Parvatha — the summit. We didn’t want to stop anywhere inbetween because both of us believed that the challenge here was to do it as fast as possible and prove it to none but ourselves. We did observe all the intrinsic details of the charming scenery along the path. As people believe, “Words aren’t enough to explain the nuances of the experience.”</p><p>Immediately, after we crossed the forest, the trek became steeper and steeper. When we could no longer walk, we started increasing our speed. This scene from the movie, Ironman, striked my mind.</p><p>Sometimes you gotta run before you know you can walk.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F1VrHeInDwwg%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D1VrHeInDwwg&amp;image=http%3A%2F%2Fi1.ytimg.com%2Fvi%2F1VrHeInDwwg%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/92913b399855f943b741ac350d969f39/href">https://medium.com/media/92913b399855f943b741ac350d969f39/href</a></iframe><p>It was 10:15, and after these strenuous steep slopes, we reached an area where it was relatively flat. We had little instinct that we had reached the place called “Bhat’re manae” (Not sure if it’s spelt that way). It was a house owned by the Bhat brothers. They offer place to stay and food for the trekkers.</p><p>“How many of you are there?”, asked the elder Bhat brother. “Seven”, I replied. “Come in. Leave your footwear outside”, said the elder Bhat brother, watching a Kannada channel on his TV. We went in, removed backpacks, lied down, and waited for the others. Two more guys made it in a short span of time, and we were not ready to continue the breaktime. We started exploring the place. There was a tiny stream, which we drank the water from, and to us it had the perfect combination in perfect amounts of the essential minerals and it tasted so good. We filled our bottles and we were waiting for the Bhat brothers to finish cooking. A couple of other trekkers also arrived and they started introducing themselves.</p><p>As soon as the food arrived, like a quintessential meme would portray, we rushed towards forming the queue and started eating. Food never tasted so good amidst the fact that nothing fancy was served (plain rice with dal and pickle). The plan was to reach the peak and get back to Bhat’re manae on the same day before 06:00p.m. We started climbing uphill from Bhat’re manae at 12:00p.m. The path contained no trees around and the Sun showered its rays of intense heat upon us. We wet our heads with water and moved further uphill.</p><p>We crossed 3 hills and reached Shesha parvatha. From there, the trail went into a forest. We climbed downhill in the forest and then uphill along the side of a dry waterfall and some rocky paths. Our legs started sending signals that it can’t move further. Our consiousness acted thereupon, and replied to them about the trek becoming steeper. Then, out of nowhere, Prassanna started moving fast. We were determined to reach the peak in another 20 minutes. And consequently, we started running.</p><p>We reached the peak at 03:00p.m. and we were so tired that we just found some shade under a plant and waited there for the others to make it to this point. After they arrived, we started capturing some pictures with weird poses. I realized that the peak wasn’t that great. There were campfire stone rings, a lot of ‘em, and a temple built by stacking small stones. Infact, the view wasn’t as great as the view from the other peaks (local maximas) we crossed. As Steve Jobs says, “It’s never about the destination. The journey is the reward.”, holds true, literally.</p><p>We started trekking downhill to Bhat’re manae. Sunset in Kumara Parvatha happens so fast that in a span of 2-3 minutes, it becomes dark. Just when the Sun was setting, we were climbing down hill and the view was unreal. 1.5ft tall thin sparsely branched plants and grasses covered the entire region. The rays of the dawning Sun striking this setup resulted in a view — an Orange glow over the Green land.</p><p>We reached Bhat’re manae at 06:00p.m. and stayed in the nearby forest department building for the night. (…) It wasn’t too cold here that we woke up early and decided to start trekking downhill, back to Kukke, as soon as possible, to avoid the bright guy rising over our heads. We had breakfast at Bhat’re manae, and started moving downhill at around 7:45a.m. We didn’t spend too much time observing the scenery as our motive was to find how fast we could get to the end of the trail. After everyone reached Kukke, we jumped into a small stream of water and relaxed while the gentle stream of water was massaging our tired body. We ended the trek with a pint of beer, fried fishes and chickens, and biryani.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3e4100116c30" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>