<?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: Vaidotas Piekus</title>
    <description>The latest articles on DEV Community by Vaidotas Piekus (@vaidotas).</description>
    <link>https://dev.to/vaidotas</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%2F29177%2Fa03aa518-2087-46ef-97bf-7854875128c8.jpeg</url>
      <title>DEV Community: Vaidotas Piekus</title>
      <link>https://dev.to/vaidotas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vaidotas"/>
    <language>en</language>
    <item>
      <title>Frontend - the red-headed stepchild of product development</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Sun, 04 Feb 2024 00:09:44 +0000</pubDate>
      <link>https://dev.to/vaidotas/frontend-the-red-headed-stepchild-of-product-development-1k7a</link>
      <guid>https://dev.to/vaidotas/frontend-the-red-headed-stepchild-of-product-development-1k7a</guid>
      <description>&lt;p&gt;Producing a digital product is a funny business. Many, many people have to think and strategize, work together, and determine what to build and how to build it, launch, and market the product. It is hard to tell who is the most responsible for a successful product launch. Sales? would not happen without a killer app to sell. Engineering? would not even know what to build or how to market without talented designers/PMs and salespeople. So it is clearly a "it takes a village" type of endeavor, but recognition is not equal.&lt;/p&gt;

&lt;p&gt;Recognition is not equal in most aspects of life so why would it be equal in software development? On paper, tech work should be easier to tokenize the amount of work and show ROI on each development cycle. If you work on a piece of functionality like a new checkout component, ideally it should be easy to showcase your part of the work, how it fits in the business goals, and after a while what usage impacts it had. But reality is never that straightforward.&lt;/p&gt;

&lt;p&gt;From the perspective of C-Suite in mid-large startups, or even a small startup leadership, this is a rough approximation of how the "importance" pecking order shakes out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Architecture, data storage, and business logic (backend)&lt;/li&gt;
&lt;li&gt;Security and reliability (backend SRE/Security focus)&lt;/li&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;li&gt;Frontend&lt;/li&gt;
&lt;li&gt;QA&lt;/li&gt;
&lt;li&gt;Frontend niches -&amp;gt; Accessibility experts, CSS wizards, UX researchers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It may look unfair if you work in any of the 3-6 categories or have different ideas of what is valuable. But this is how it falls in almost all software product companies. This is not a reflection of how "hard" each field is, for example, frontend niche of accessibility is arguably harder than managing optimal database queries. You can study various accessibility topics for years and adapt the knowledge to multiple quirks of the browsers with never-ending spec changes and anti-patterns of developers. This is hard work and it is a moving target. How many new ways can you optimize MySQL queries each year? Not many, if any.&lt;/p&gt;

&lt;p&gt;Frontend devaluation hits close to home as I am mostly focused on frontend work. This has been documented for years by &lt;a href="https://twitter.com/swyx/status/1682748872047886337"&gt;Swyx&lt;/a&gt; who has spoken of a silent frontend ceiling. The basic idea is simple -&amp;gt; backend devs will likely never report to frontend devs. Looking at VP of eng roles, directors, and engineering managers, they are almost always filled with people with backend background, nobody comes from design or pure frontend background. This is often reflected in C-Suite company addresses or kudos given, at best you may get a shoutout because you were part of the team that was composed of backend engineers or great designers. I believe that most of the leadership thinks of frontend as a group of engineers who basically take designs in Figma and clumsily remake them in code. If Figma or another tool would have reliable exporting functionality they would take out the middleman -&amp;gt; frontend engineer and let their backend engineers template out the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are a frontend engineer, what do you do about this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are options. None of them easy, but you have to pivot to either the design side or backend/systems/data side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Become extremely good at design, UX and work very very closely with PMs/Designers. You may think you are already doing this but you are not, you have to become an advocate of the user, and your understanding of how business works and what brings revenue should be second to only PM. You are so good at executing and understanding what to build that they loop you in every decision and client/stakeholder conversation, you own the user experience and execute at a very high level. Your time of waiting for tickets to drop or Figma designs to be completed is over. This is the only path to positions like Director of Product.&lt;/li&gt;
&lt;li&gt;Intentionally move away from frontend focus to backend focus. Going fullstack is okay, temporarily, but learn how the current system works, what database is used and how we are talking to it. Learn everything about authentication and authorization, start contributing to backend in your company. Maybe you are waiting on somebody to build you a route, don't wait, build it yourself and ask for some eyes on it. People are usually happy to see initiative and if you don't completely mess up, you will get ahead. Talk to your manager, and get your frontend work done but start focusing your learning on backend systems and not the latest React canary versions of yet another way to render a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; on a webpage. This is the path to EM/Director of Eng role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is there anything else besides these two options? What if you are passionate about QA, can create CSS masterpieces, or can teach best accessibility practices? If your goal is career progression at a mid to large company I suggest going either the product or backend/security engineering route. If you can monetize your frontend niche and do not care about roles like director/VP - don't worry about it and get even better, there is always a niche to explore and teach. But if you are a generalist frontend engineer, you are on shaky ground.&lt;/p&gt;

&lt;p&gt;Plan accordingly.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>“Best Practices” as an anti-pattern</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Sun, 06 Feb 2022 11:59:03 +0000</pubDate>
      <link>https://dev.to/vaidotas/best-practices-as-an-anti-pattern-mo2</link>
      <guid>https://dev.to/vaidotas/best-practices-as-an-anti-pattern-mo2</guid>
      <description>&lt;h2&gt;
  
  
  A Short Story of How Best Practices come to be
&lt;/h2&gt;

&lt;p&gt;Imagine a beautiful green field, full of untapped potential, things to do, systems to build and happy customers to serve. You work alone, maybe with a team, slow or fast but you build a system, an application, maybe it is a website. Along the way you accumulate “dos” and “don’ts”. Perhaps you write it down, share it with the new folks who are joining no longer green but browning field. You are wise and some people call you “senior” or even “staff” something. You write down your ideas and call it &lt;em&gt;Best Practices by Staff or Senior Somebody&lt;/em&gt;. That feels nice, you bestowed your hard earned knowledge to the next person, helping and guiding them for months/years to come.&lt;/p&gt;

&lt;p&gt;Let’s unpack this a little bit. Okay maybe you did not actually wrote the &lt;em&gt;Best Practices by Staff or Senior Somebody&lt;/em&gt; but you were recommended to read it or it was passed down as onboarding document or it came about some other way. In its origin these are a set of rules and ideas written at some point in people’s careers at a particular time in project’s lifecycle. They had some real or perceived value, and got shared across blogs, Twitter threads and internal Slack rooms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what is the problem?&lt;/strong&gt;&lt;br&gt;
The problem is that people take &lt;em&gt;some&lt;/em&gt; ideas codified by &lt;em&gt;some&lt;/em&gt; team that applied at &lt;em&gt;some&lt;/em&gt; point in time to a specific project they were working on. It is very unclear if those suggestions will work out for you and your team. You need to know the context with which those trade-offs were made and what alternatives were considered. You will not know that information, but people will push to make dogmatic choices because they perceive it being a &lt;em&gt;best practice&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  DRY
&lt;/h2&gt;

&lt;p&gt;The prime example of best practice that gets too much attention is &lt;strong&gt;Don’t Repeat Yourself&lt;/strong&gt;. Coined by Andy Hunt and Dave Thomas in their seminal programmers bible &lt;a href="https://media.pragprog.com/titles/tpp20/dry.pdf"&gt;The Pragmatic Programmer&lt;/a&gt;. If you read the linked chapter fully it actually makes a lot of sense. Most people stop reading at what authors call “a tiny and fairly trivial part” - don’t copy-paste lines of code. Duplication is considered a bad way of writing code but they stress that duplication of knowledge and intent is much worse than any other types of duplication. Code duplication is a symptom that rears its ugly head but it is certainly not the only one. If you are changing a single thing but have to make changes in multiple places - that’s bad.&lt;/p&gt;

&lt;p&gt;The problem is that people since 1999 (and probably earlier) have been telling other developers to adopt “clean code” practices and “DRY it up”. Without the nuanced context of WHY and HOW this should be done, I find such comments to be about the most useless and lazy dogma out there. By taking this advice to the extreme logical conclusion, code base becomes a completely messy function soup where logic is stretched out into dozens of small files with tiny functions peppered across all of it. Typical day debugging such code involves searching globally for tokens and jumping from definition to implementation in your IDE until it gets dizzy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the problem?
&lt;/h2&gt;

&lt;p&gt;The problem is that people take &lt;em&gt;some&lt;/em&gt; ideas codified by &lt;em&gt;some&lt;/em&gt; team that applied at &lt;em&gt;some&lt;/em&gt; point in time to a specific project they were working on. It is very unclear if those suggestions will work out for you and your team. You need to know the context with which those trade-offs were made and what alternatives were considered. You will not know that information, but people will push to make dogmatic choices because they perceive it being a &lt;em&gt;best practice&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  What do we do?
&lt;/h2&gt;

&lt;p&gt;The has been &lt;a href="https://qntm.org/clean"&gt;good&lt;/a&gt; &lt;a href="https://overreacted.io/goodbye-clean-code/"&gt;articles&lt;/a&gt; written about revisiting “clean code” and stop recommending it. I’d agree with all of those points raised and add that we should discover our own approaches and, instead of enshrining them into some immutable document, create a culture around mutability when it comes to “best practices”.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let’s encourage new folks to the codebase to be asking questions of why it has been done this way.&lt;/li&gt;
&lt;li&gt;let’s rename “best practices” to “a set of ideas we have about the way we communicate in code based on current context” (maybe find a more catchy name).&lt;/li&gt;
&lt;li&gt;let’s not be afraid to revisit and change those set of ideas as they should change with the changes to requirements, team size, team seniority levels and tech stack.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cleancode</category>
      <category>dry</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Selling Refactoring</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Wed, 21 Oct 2020 16:11:11 +0000</pubDate>
      <link>https://dev.to/vaidotas/selling-refactoring-21ie</link>
      <guid>https://dev.to/vaidotas/selling-refactoring-21ie</guid>
      <description>&lt;p&gt;“Refactoring” is one of those words that are loved by developers and dreaded by project managers. As a developer I love the idea of it, I love initiating, planning and executing a well meaning refactoring. I love making code simpler and easier to understand. So why do we get groans and resistance from PMs and product owners when we bring it up? Don’t they love efficient and clean code practices that lead to a better software product too?&lt;/p&gt;

&lt;p&gt;Fundamentally the problem comes from two things: &lt;strong&gt;misunderstanding the process&lt;/strong&gt; and &lt;strong&gt;communication of intent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In order to unpack these concepts we need to briefly remind ourselves what is refactoring. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.” (M.Fowler, “Refactoring”)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Okay, so the key concepts to highlight is that refactoring does not change observable behavior and that it makes it easier to understand and change the codebase. This sounds straightforward and “good”. Who does not want code that is easy to change and add new features? However selling such idea to the stakeholders, by itself, is a losing battle. The value proposition of “code will be better internally, but with no changes to functionality will be made “ sounds like developers complaining about current codebase and doing work to improve it with no tangible benefits to the clients/stakeholders. It is the classic trope of developers complaining about existing system and wanting to do a total rewrite.&lt;/p&gt;

&lt;p&gt;This is where communication breakdown happens most often. Developers trying to sell the idea of large scale refactoring and product owners hearing “a bunch of work for nothing to show for”.&lt;/p&gt;

&lt;p&gt;So how do we sell idea of refactoring code in the most effective manner? &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;We don’t sell it at all, we just do it!&lt;/strong&gt;
&lt;/h1&gt;

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

&lt;p&gt;Before the accusations of mutiny let me explain. Refactoring is part of the work we do everyday, it is an integral part of delivering high quality software. Think about it as tending a garden, first we make sure the plot of land where we were asked to plant flowers is ready for it and then we plant flowers. We don’t need to sell the idea of preparing the plot for planting because it is part of the job.  In software, we implement tasks by first making sure we understand the context and then adding the functionality. If we find it hard to add a feature or fix a bug, we start the process by making appropriate changes to it is easier to accomplish said task (refactoring).&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-250733358307500032-818" src="https://platform.twitter.com/embed/Tweet.html?id=250733358307500032"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-250733358307500032-818');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=250733358307500032&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Obviously caveats apply here as they do everywhere, we cant just rewrite the whole system if we find it tricky to add one small feature, we also cant spend all the budget in order to “understand the system”. We need to use our heads and figure out the most effective solution with the time we have. As a general rule, if we think we need a very large scale refactoring (1-2 weeks or more) this is generally full blown software rewrite and not refactoring, as latter consists of small, incremental changes that are done in order to make implementation of feature or a bug fix easier to do.&lt;/p&gt;

&lt;p&gt;So next time you are presented with a task to accomplish think and evaluate if context around that task is easy to understand and if you find it hard to accomplish, you may need to be doing a little bit of garden tending  in order to make the change easier for you and others who will be finding themselves in that particular plot of land in the future.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>refactoring</category>
      <category>communication</category>
    </item>
    <item>
      <title>Get Faster - VSCode navigation without a mouse</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Tue, 26 May 2020 14:06:36 +0000</pubDate>
      <link>https://dev.to/vaidotas/get-faster-vscode-navigation-without-a-mouse-3d0m</link>
      <guid>https://dev.to/vaidotas/get-faster-vscode-navigation-without-a-mouse-3d0m</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Why should you care about mouseless experience when VSCode is a GUI editor tuned to a great mouse experience? The answer is speed.&lt;br&gt;
If you can do make tasks that you do every day but faster it will save you time and keep you in the "flow" longer. It is worth just looking through common default keybindings for VSCode and get a great view of what is possible and what is already available: &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer"&gt;MAC&lt;/a&gt; / &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the real value proposition is not to try and memorize dozens of keyboard shortcuts but to optimize the "hottest path" for your daily workflow. You want the least friction possible for things you do constantly and that means avoiding mouse/trackpad for most navigation and code editing. Let's dive in.&lt;/p&gt;

&lt;h3&gt;
  
  
  VSCode Navigation between panels, files, and tooltips
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;(1) Activity Bar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F96s7tr13l12dvb6fs5ii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F96s7tr13l12dvb6fs5ii.png" alt="VSCode Activity Bar"&gt;&lt;/a&gt;&lt;br&gt;
Depending on the number of extensions and settings your activity bar can look different than mine. All menus in Activity Bar can be reached with keyboard, however, we do not need to work on remembering that obscure extension you maybe use once a month. Let's focus on the most important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File Explorer &lt;code&gt;CMD+SHIFT+E&lt;/code&gt; - we use this all the time, navigate between files and explore project file tree structure. One annoyance of default VSCode behavior in File Explorer is when you have file highlighted and hit &lt;code&gt;ENTER&lt;/code&gt; it defaults to renaming a file. If you want to open it instead (which is what I want almost 100% of the time) you have to use &lt;code&gt;CMD+Down_Arrow&lt;/code&gt;. This is funky but worth remembering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Project Search &lt;code&gt;CMD+SHIFT+F&lt;/code&gt; - extremely helpful to find anything within your project, open it up, enter search string hit &lt;code&gt;ENTER&lt;/code&gt; and you are good to go. If you want to jump down to results without a mouse, hit &lt;code&gt;CMD+Down_Arrow&lt;/code&gt; and now you can navigate through the files in results.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Source Control &lt;code&gt;CTRL+SHIFT+G&lt;/code&gt;. I typically just launch this panel with the keyboard but switch to interacting with the mouse as I like to click through the files, take a look at the changes and commit them right in the panel I find mouse be a little more useful but you can do everything with the keyboard too if you so wish.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, now that we got those down you should never need to break away from your keyboard to launch File Explorer or search within your project!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(2) Navigation between your code, activity bar and terminal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These 3 sections of VSCode are definitely the most used and important for anybody's workflow. I jump around Activity Bar, edit my code and go over to the terminal to restart the server or do any other action all the time. It is very frustrating to keep cycling between these panels with the mouse just to do a quick command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus Left Panel (can be anything from Activity Bar selections) &lt;code&gt;CMD+0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Focus Middle Panel (open files) &lt;code&gt;CMD+1&lt;/code&gt; This technically focuses the first file that you have open, if you have another file opened in the split, you can do &lt;code&gt;CMD+2&lt;/code&gt; and just jump the second file you've got opened.&lt;/li&gt;
&lt;li&gt;Show terminal &lt;code&gt;CMD+J&lt;/code&gt; or &lt;code&gt;CTRL+`&lt;/code&gt;. Notice that this only shows terminal. If we have it already opened and want to focus it, it does not seem that VSCode provides default keybinding for such action. We can define it ourselves. Open Command Palette &lt;code&gt;CMD+SHIFT+P&lt;/code&gt; and type "keyboard" and select the one with the JSON "Open Keyboard Shortcuts (JSON)", now we can add any keybinding for any action. Here is what I have: 
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;{ "key": "ctrl+l", "command": "workbench.action.terminal.focus" },&lt;br&gt;
  { "key": "ctrl+l", "command": "workbench.action.focusActiveEditorGroup", "when": "terminalFocus" },&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You can change that "key" string to whatever feels good, but the objective here is with these two settings you can cycle through editor focus and terminal focus with one keybinding. That is super nice!

**(3) Navigating within a file super fast**
Once you have a file that is opened it is tempting to reach for a mouse and start scrolling up and down the file to find the relevant spot in code or just to gauge the shape of the file. Here are a few key techniques to get you around any file with more efficiency:
  * `CMD+Up_Arrow/Down_Arrow` Jump to the beginning/end of the file. This is very useful when you need to quickly jump to the import section of the file or the export section which is usually at the end.
  * `CMD+SHIFT+O` Navigate between **symbols** within a file. This is the most useful command that nobody uses! It gives you a quick panel to cycle through function definitions/methods defined within a file.
![navigation](https://dev-to-uploads.s3.amazonaws.com/i/e7k17pvybh9f814u90cb.gif)
  * `CMD+F` Find in File. Very powerful and useful command. We all know how to use it but you can actually use this one to quickly jump to a certain section in the file. Say you have function called `adder` you hit `CMD+F` type `add` and with a quick ESC your cursor is already there, ready to edit. Handy!

---
That is it folks! General advice learning these keybindings is to start small, start wherever your "hottest path" is and try and optimize that a little to be more comfortable and faster. Don't try and do too much, memorize all the things, you will struggle to remember it all.

In Part2 of this series, we will be talking about fast code editing!
Let me know below your favorite shortcut and other tips and tricks you discovered.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>vscode</category>
      <category>keyboard</category>
      <category>productivity</category>
    </item>
    <item>
      <title>On Salary Negotiations</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Thu, 28 Mar 2019 13:02:19 +0000</pubDate>
      <link>https://dev.to/vaidotas/on-salary-negotiations-4o2o</link>
      <guid>https://dev.to/vaidotas/on-salary-negotiations-4o2o</guid>
      <description>&lt;h3&gt;
  
  
  "Negotiate your salary  - ask for more!"
&lt;/h3&gt;

&lt;p&gt;This is one of those mantras that all of us hear all the time, but when push comes to shove, we rarely do it. Doubt besets us, we do not know what to ask or how to ask for it and we start fooling ourselves that company will offer us a fair compensation because "we are awesome and they will see it". We may be awesome, but we still need to market ourselves, work hard at presenting value and fight to get paid fairly. &lt;/p&gt;

&lt;p&gt;In fact, as far as choices go, the choice to ask for more or not is one of the most impactful ones you can make in your career. Once you are hired, your salary is likely going to remain the same, with marginal adjustments based on inflation, promotions or bonuses (which are not guaranteed). If you are changing jobs every 2-5 years, the base salary that you sign on, will be the most important metric directly impacting your every day life. Do not waste the chance to significantly improve your situation. Having said that, successful salary negotiation is not as simple as "ask for more and they will give it to you". You need to approach it strategically, purposefully and with preparation. This article attempts to set you on the right path.&lt;/p&gt;

&lt;p&gt;Before you start negotiating there are 3 pillars upon which you have to build your case: 1. Understand the market 2. Understand your leverage 3. Apply negotiation tactics.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understand the market
&lt;/h2&gt;

&lt;p&gt;Do your research - The worst thing you can do going into any sort of negotiations is to arrive without doing your homework. You must have a sense of what salary range is reasonable for your experience, qualifications, tech stack and area.  Have a number of absolute minimum salary you would need to live comfortably, take into consideration your personal situation and existing commitments (family, parents, kids, pets, etc). You must have a number below which you will not take the offer. &lt;/p&gt;

&lt;p&gt;Next step is to find out what other developers in your area with similar experience and qualifications to yours are getting paid. Here are some of the tools you should be using, use all of them and arrive to a range of salary. Just know that no tool is perfect and they all provide a glimpse into reality but not exact numbers, simply approximations. Use these to approximate and balance your expectations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your network&lt;/strong&gt; - this is the most accurate and reliable source of information. If you are part of local tech network you can ask your fellow devs what should be your salary expectations. It is way more likely that you will get an answer to a question "Given that I have 2 year experience developing Full Stack applications in Rails, what do you think would be reasonable to ask for compensation?". You may not get far by asking directly how much other developers are making. Even though sharing salaries could do a lot of good for the community, a lot of people find it uneasy to talk about.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.glassdoor.com/Salaries/index.htm"&gt;https://www.glassdoor.com/Salaries/index.htm&lt;/a&gt; - Salary info is pretty accurate for larger companies and for more junior positions, going higher on the experience ladder, results will wary.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hired.com/state-of-salaries-2018"&gt;https://hired.com/state-of-salaries-2018&lt;/a&gt; - It has reasonable estimations but only for major city averages, take it with a grain of salt.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/jobs/salary"&gt;https://stackoverflow.com/jobs/salary&lt;/a&gt; - it can filter out to your level of experience and area which is neat. They also have a good number of data, even if it is all self-reported.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.payscale.com/research/US/Job=Software_Developer/Salary"&gt;https://www.payscale.com/research/US/Job=Software_Developer/Salary&lt;/a&gt; - can be a decent resource but I find that the range will vary wildly.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.roberthalf.com/salary-guide"&gt;https://www.roberthalf.com/salary-guide&lt;/a&gt; - This one has a nice report you can access, gives you a good idea of what to expect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your objective at this stage is to arrive to a salary range that applies to your situation. Top end will be something of a dream salary while bottom end will be your absolute minimum you would need to even consider accepting the offer. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understand your leverage.
&lt;/h2&gt;

&lt;p&gt;Leverage is very powerful when applied correctly, in a nutshell it is your unique value proposition and the reason why your should be paid more than you are being offered. This is highly personal and entirely dependent on your story and how well you can tell it, here are some of the most common value propositions you can apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Passion" - I personally dislike that word and the connotation it has because it usually means extra work outside of your "normal" job or studies. This can take shape into multiple ways: Blogging, Tweeting helpful content, personal projects, participation in local tech community via meetups, open source contributions, etc. If you are doing some of these activities - great, build on that and advocate for yourself as an active and passionate community member. However, it can be hard to do this if you do not have ample time, maybe you are learning to code on the side, have dependents or demanding life in general. Not everybody can do most of these things but you certainly can blog or share what you are learning once in a while (even if it is once or twice a month).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Previous experience. A lot of us are career changers, going through the path of being self- thought or intensive bootcamp experience. It is likely that you currently have or use to have a non-technical day job. Do not discount that, leverage it to increase your prospects. Worked in a grocery shop? Great! You have good work ethic, handling difficult situations and remaining calm when the storm hits (somebody is yelling at you because they cannot find their favorite yogurt). Think long and hard about transferable skills that you honed in your previous job and that would apply to the tech field. You will be surprised how much will apply.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Current job achievements. If you already have a dev job and are simply moving to another - even better, you are half way there. But your resume should be full of evidence of your personal contributions, value that you brought to the company and projects and how productive you were. This is not a time to be shy and put your team first, this is time to take ownership and showcase that any company would be lucky to have you!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple, competing offers. This one is uncommon and hard to get, but if you are actively interviewing and have a few offers on the table that you are considering, you can share that fact with the company you really want to work for and create leverage that way. Something along the lines of "I would love to make this happen and arrive to the offer that would be agreeable to both of us. If you would consider offering base salary of $XXX instead, it would make it easier to decline other offers I have from X and Y companies at the moment." Work with them on this, do not bluff, do not lie about what you have, ask them how can you work together to arrive at the agreement that is mutually agreeable and reasonable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Negotiating tactics and pitfalls
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Being uneasy about negotiations&lt;/strong&gt;&lt;br&gt;
This stuff comes naturally to almost nobody. You are in a warped asymmetrical power situation, you operate under limited amount of information, you really want this job and the person on the other line has been negotiating as their full time job (if they are recruiter).  Having said that, with the research you have done, and the information you have at hand and understanding your leverage you are not hopeless, push past uneasiness and go for it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What ifs that are in your head:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;What if they retract the offer?&lt;/em&gt;&lt;br&gt;
That hardly ever happens and if it does, you likely just dodged a bullet. Company that does not respect individuals who know their self worth and are not afraid to ask for it, may not be best environments to thrive.&lt;br&gt;
What if I appear "difficult" and destroy my chances? &lt;br&gt;
You won't. Unless you are being unreasonable and unprofessional, there is nothing wrong about discussing compensation and other benefits.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if I am [insert your underrepresented minory which which you identify here], I am lucky enough to get an offer!&lt;/em&gt;&lt;br&gt;
You got the offer because you are qualified and you convinced company that you would be a productive employee. Your next objective is to convince them that you are worth more then they are offering. Where one falls on privileged/unprivileged scale is irrelevant. Ask for what you think you are worth.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if [insert anything else]?&lt;/em&gt;&lt;br&gt;
The worst that can happen is that they will not budge on compensation question. You may want to give them an out and discuss other perks and benefits instead. Some companies have strict guidelines about base salary, but are okay discussing things like flexible work schedule, vacation days, commuting reimbursement and other perks. If they are not flexible, then that is just that, consider the offer as it stands and make the judgement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ultimatums are bad&lt;/strong&gt;&lt;br&gt;
There is a difference between confidence and reckless demands. Saying "I will not consider anything less than $80k" will hurt you in the long run, if company actually cannot offer that number, you just closed the door to negotiate other benefits and perks that would be part of the whole offer package. As a general rule - avoid using phrases like "I will not", "I do not", "I cannot". Always leave room for conversation and negotiation, always leave an out. On the flip side, if company was actually consider paying you something in the range of $70k-$90k, you just made a mistake that is called anchoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anchoring is a thing&lt;/strong&gt;&lt;br&gt;
It is often the case that you will be asked very early in your application process the dreadful question - "what is your salary expectations?". It is hard question for two reasons: a) You may not have a good idea b) Your answer will most likely &lt;em&gt;anchor&lt;/em&gt; you to the number you say and above which it will be hard or impossible to go. Let's say you answer with $60,000 as your wish right at the begging of conversation with recruiter, you will not be offered more than that at the end (offer stage). And if you ask for more at the that step in the process, you will look rather bad because they are meeting your expectations in the offer letter. You just boxed yourself in.&lt;br&gt;
How to avoid anchoring? You will need to competently and professional deflect the question for as long as seems reasonable. If you are being asked right of the gate by the requiter - deflect it by stating that "I would like to see if this position will be a good fit for me before discussing compensation".  Hopefully, by the time you arrive to the last step (final interview and offer) you will have a good idea what you should be asking and that question will not be so doubting. &lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts and further reading
&lt;/h2&gt;

&lt;p&gt;Negotiation is hard and for most people it is neither enjoyable experience or something they are good at. Unfortunately, for the most part in this world, if you want something, you have to ask for it. So do you research, understand your self worth and go into this with the confidence and objective of getting offer that matches your perceived worth. &lt;br&gt;
Here are some further resources that will be helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://stephaniehurlburt.com/blog/2016/7/12/tips-for-negotiation"&gt;http://stephaniehurlburt.com/blog/2016/7/12/tips-for-negotiation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://medium.com/@mogest/negotiating-your-salary-a-developer-howto-38196fe695a5"&gt;https://medium.com/@mogest/negotiating-your-salary-a-developer-howto-38196fe695a5&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stackoverflow.blog/2017/10/16/developers-can-best-negotiate-salary/"&gt;https://stackoverflow.blog/2017/10/16/developers-can-best-negotiate-salary/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hackernoon.com/maximizing-you-next-salary-4e3aa2af2f8e"&gt;https://hackernoon.com/maximizing-you-next-salary-4e3aa2af2f8e&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>salary</category>
      <category>compensation</category>
      <category>devjob</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building Weather Forecast CLI tool Part 2</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Fri, 15 Mar 2019 00:34:05 +0000</pubDate>
      <link>https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-2-2288</link>
      <guid>https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-2-2288</guid>
      <description>&lt;h1&gt;
  
  
  Building Weather Forecast CLI tool Part 2
&lt;/h1&gt;

&lt;p&gt;This is the second part of the Building CLI tools series that will go into detail how to call DarkSky API from your command line and print out the results and then publish our CLI to npm.&lt;/p&gt;

&lt;p&gt;Just to recap from the &lt;a href="https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-1-2mdj"&gt;Part 1&lt;/a&gt; - We will be building something that will look similar to this image:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Part A - Call the API and retrieve info
&lt;/h2&gt;

&lt;p&gt;Let's get the invocation of today's weather forecast from our main entry file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.ts&lt;/span&gt;
&lt;span class="nx"&gt;program&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;today&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="nf"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;t&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="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Show weather information for today&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="nf"&gt;action&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;weatherActions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&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;Our weather API logic we will be sitting in a single file - &lt;code&gt;weatherActions.ts&lt;/code&gt; where we will be calling DarkSky API, normalizing the data and printing it out. Calling API will be done through &lt;code&gt;axios&lt;/code&gt; package and printing it out to the console will be done with &lt;code&gt;chalk&lt;/code&gt;, be sure to have those installed before continuing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//weatherActions.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chalk&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;chalk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Configstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;configstore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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;conf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Configstore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;weather-cli&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DARKSKY_API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DARKSKYAPIKEY&lt;/span&gt;&lt;span class="dl"&gt;"&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;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.darksky.net/forecast/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DARKSKY_API&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/38.889102,-77.050637?exclude=minutely`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;200&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`DarkSky API error &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;//deconstruct current weather data&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentSummary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentTemperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentHumidity&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currently&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//deconstruct today's weather data&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dailySummary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperatureHigh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dailyTempHigh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperatureHighTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dailyTempHighTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperatureLow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dailyTempLow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;apparentTemperatureLowTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dailyTempLowTime&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;daily&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, let's unpack what is going on in the file above. We are importing previously mentioned dependencies, and API key which we set up in the &lt;a href="https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-1-2mdj"&gt;Part 1&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;configstore&lt;/code&gt; has a handy method &lt;code&gt;.get&lt;/code&gt; to retrieve whichever key you have set previously. We will be using it to call our API endpoint. You will notice that I hardcoded longitude and latitude to my location, we can implement city search as a future goal but for now you can just put your own coordinates instead.&lt;/p&gt;

&lt;p&gt;Axios works as normal, after we check that response status is &lt;code&gt;200&lt;/code&gt; (meaning everything is OK), we proceed to extract relevant data fields from the response payload. We are using object destructuring and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" rel="noopener noreferrer"&gt;rename feature&lt;/a&gt; of ES6.&lt;/p&gt;

&lt;p&gt;Now if we simply &lt;code&gt;console.log&lt;/code&gt; that received information, results will not be great, you may see something like this:&lt;/p&gt;

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

&lt;p&gt;We clearly need to do some time conversion, temperature adjustments to include Celsius and Fahrenheit and basically make it much more appealing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part B - Pretty print please
&lt;/h2&gt;

&lt;p&gt;First up - let's make this data presentable.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Temperature needs to be converted to Celsius for convenience to display both C and F.&lt;/li&gt;
&lt;li&gt;Humidity needs to be shown in percentage&lt;/li&gt;
&lt;li&gt;Time indications need to be shown in human readable form
&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;const&lt;/span&gt; &lt;span class="nx"&gt;currentTemperatureC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nx"&gt;currentTemperature&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;9&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;dailyTempHighC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nx"&gt;dailyTempHigh&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;9&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;dailyTempLowC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nx"&gt;dailyTempLow&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;9&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;currentTimeConverted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&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;humidityPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentHumidity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&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;highTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dailyTempHighTime&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&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;lowTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dailyTempLowTime&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We are doing a few conversions and rounding results with a handy &lt;code&gt;Math.round()&lt;/code&gt; method. Time conversions are done with built-in &lt;code&gt;new Date()&lt;/code&gt; object. You may notice something strange next to the variable declarations &lt;code&gt;const currentTemperatureC: string = ...&lt;/code&gt;. Those are TypeScript types. We indicate that the result of that particular assignment should always be a string. It seems trivial at this point, but if we ever want to change our program and how we calculate temperature, this will help us to make sure we do not change the type from &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;number&lt;/code&gt; for example. You may also be asking why are we forcing some of the numbers to be converted to strings with &lt;code&gt;String()&lt;/code&gt; -&amp;gt; that is needed because to print out the results we will be using JavaScript template literals (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&lt;/a&gt;) which will make TypeScript yell at us if we try to pass &lt;code&gt;number&lt;/code&gt; to a string literal like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someCalculation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Print my calculation &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;someCalculation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//TS yelling at us here!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am not entirely sure why that is so if you have idea, do let me know in the comment below! 👇&lt;/p&gt;

&lt;p&gt;Our last step in this part is to print the results in a nice and presentable fashion. &lt;code&gt;chalk&lt;/code&gt; module comes to the rescue!&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="s2"&gt;`
|-|  {blue ╦ ╦┌─┐┌─┐┌┬┐┬ ┬┌─┐┬─┐}
|-|  {blue ║║║├┤ ├─┤ │ ├─┤├┤ ├┬┘}
|-|  {blue ╚╩╝└─┘┴ ┴ ┴ ┴ ┴└─┘┴└─}
|-|   🌎 {blue Washington DC, USA} &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentTimeConverted&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;            
|-|   🐡 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentSummary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;                                        
|-|   ☀️ {yellow.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentTemperature&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;F}/{blue.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentTemperatureC&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;C}                       
|-|   🌊 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;humidityPercent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%                              
|-|   📇 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dailySummary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;                                    
|-|   📈 High: {yellow.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dailyTempHigh&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;F}/{blue.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dailyTempHighC&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;C} At: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;highTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
|-|   📉 Low : {yellow.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dailyTempLow&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;F}/{blue.bold &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dailyTempLowC&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;C} At: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lowTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89fopmm9lehlmql0rmem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89fopmm9lehlmql0rmem.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No magic going on here, we are simply injecting our variable values into template literal which we can shape and organize however we like. I added "weather" letters up top and some of the emojis to denote various measurements like temperature, humidity and so on. If it all goes according to the plan, we should be seeing result similar to the image at the top of this post.&lt;/p&gt;

&lt;p&gt;Some of the things we could do but is out of scope for this post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hook up Google API to set any location based on name&lt;/li&gt;
&lt;li&gt;implement &lt;code&gt;-week&lt;/code&gt; command showing forecast for the week&lt;/li&gt;
&lt;li&gt;introduce some tests to make our program more robust&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Part C - Publish to NPM
&lt;/h2&gt;

&lt;p&gt;If we want to make this program truly reusable and available for others to install via npm registry, we need to publish it.&lt;/p&gt;

&lt;p&gt;For that to happen we need to do a few things to make it "publishable":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure the name is unique or publish under scoped package (meaning that it would go under your username/module-name naming convention).&lt;/li&gt;
&lt;li&gt;Add version number to the app. npm uses &lt;a href="https://docs.npmjs.com/about-semantic-versioning" rel="noopener noreferrer"&gt;semantic versioning&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Because this project is written in TypeScript, we need to make sure that A) We are not sending over transpiled javascript folder ("lib" folder in our case), add "types" to our package.json and &lt;code&gt;"declaration": true&lt;/code&gt; to the &lt;code&gt;tsconfig.json&lt;/code&gt; file. Take a look at the required changes below:
&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="c1"&gt;//package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vaidotasp/weather-cli&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//-&amp;gt; publishing under our username let's us not worry about unique naming&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//-&amp;gt; you cannot publish without version number&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//-&amp;gt; note that this points to our transpiled .js entry file&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib/index.d.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//-&amp;gt; that will be generated by TypeScript&lt;/span&gt;
  &lt;span class="p"&gt;.....&lt;/span&gt;
  &lt;span class="c1"&gt;//other entries are the same as in Part 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;//tsconfig.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exclude&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//-&amp;gt; required step to generate .d.ts file&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commonjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;types&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rootDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src&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;p&gt;Once ready to publish, make sure you have an account with npm, if so, you can go ahead and login through your terminal&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that's left is to run &lt;code&gt;npm publish --access=public&lt;/code&gt; command to push this little program out in the wild and have it accessible to the public.&lt;/p&gt;

&lt;p&gt;If all goes well you can navigate to &lt;code&gt;https://www.npmjs.com/package/@username/module-name&lt;/code&gt; and find you module!&lt;/p&gt;

&lt;p&gt;That is it!&lt;/p&gt;

&lt;p&gt;Here is the code if you want to take a look and compare notes. I will still continue to tinker with it so by the time this post is published some of the functionality may have already been changed!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vaidotasp/weather-cli-tool" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@vaidotasp/weather-cli" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>cli</category>
      <category>api</category>
    </item>
    <item>
      <title>Building Weather Forecast CLI tool Part 1</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Mon, 11 Mar 2019 13:09:43 +0000</pubDate>
      <link>https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-1-2mdj</link>
      <guid>https://dev.to/vaidotas/building-weather-forecast-cli-tool-part-1-2mdj</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekms98cbv6wqphlfzyi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekms98cbv6wqphlfzyi9.png" width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The goal and the setup
&lt;/h2&gt;

&lt;p&gt;Our goal is to build a CLI weather forecast app that shows the local weather information.&lt;/p&gt;

&lt;p&gt;Disclaimers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This will be a step by step guide aimed at beginners that are interested in building CLI tools and learning along the way&lt;/li&gt;
&lt;li&gt;There are existing weather CLI tools that are full featured and robust: &lt;a href="https://github.com/chubin/wttr.in" rel="noopener noreferrer"&gt;https://github.com/chubin/wttr.in&lt;/a&gt;, &lt;a href="https://github.com/genuinetools/weather" rel="noopener noreferrer"&gt;https://github.com/genuinetools/weather&lt;/a&gt;. This guide does not come close to feature completion, it merely provides an introduction&lt;/li&gt;
&lt;li&gt;If you notice any mistakes or have suggestions - let me know in the comments below. I am still learning!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements for our app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;User is able to invoke weather CLI tool with a single command - "weather-cli"&lt;/li&gt;
&lt;li&gt;User is able to set API key via command line (we will be using Darksky API for weather)&lt;/li&gt;
&lt;li&gt;User is able to see the following information: time, location, temperature, high temp for the day, low temp for the day, humidity and weather conditions summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools we will be using
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node - it will be running our program&lt;/li&gt;
&lt;li&gt;Typescript - No reason in particular except to learn a little bit about Typescript :)&lt;/li&gt;
&lt;li&gt;Commander(&lt;a href="https://www.npmjs.com/package/commander" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/commander&lt;/a&gt;) - this is a great solution to help us build node based CLI's.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step A -Program Init
&lt;/h2&gt;

&lt;p&gt;Let's get setup and started.&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="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;weather&lt;/span&gt; &lt;span class="c1"&gt;//let's create a directory to work in&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;yes&lt;/span&gt; &lt;span class="c1"&gt;//initialize project and skip the typical questionnaire&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="c1"&gt;//we want to make sure we can go back when invebitable disaster hits :)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have empty working directory and billions of NPM packages at our disposal, we can begin with few crucial dependencies&lt;/p&gt;

&lt;p&gt;To use typescript for this project we will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;typescript&lt;/code&gt; - we will be writing TS so this one is obvious.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ts-node&lt;/code&gt; - typescript executable for Node.js that we will run our files on&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@types/node&lt;/code&gt; - type definitions for Node.js
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt; &lt;span class="nx"&gt;typescript&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;types&lt;/span&gt;&lt;span class="sr"&gt;/nod&lt;/span&gt;&lt;span class="err"&gt;e
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next up - create &lt;code&gt;tsconfig.json&lt;/code&gt; in your root folder for minimal configuration. That's what TypeScript will be using to inform itself about the intent of our program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//tsconfig.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exclude&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commonjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;types&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rootDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src&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;p&gt;Noteworthy things about tsconfig file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"include" points to the directory that will hold our .ts source files, same as the rootDit&lt;/li&gt;
&lt;li&gt;"outDir" is where TS compiler will output files that will have the target of "es5".&lt;/li&gt;
&lt;li&gt;Setup implies that we will have to have two folders at our root directory, namely "src" and "lib".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, we create our source and output folders&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;lib src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step B - index.ts - first lines of code
&lt;/h2&gt;

&lt;p&gt;We need to make sure our setup worked and TS compiler works as instructed. Let's create entry file in our "src" folder.&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="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;

&lt;span class="c1"&gt;//index.ts content&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sayHello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hey there&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="nf"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;code&gt;package.json&lt;/code&gt; to include the typescript run and compile step. "run" we will use for running our program using ts-node and "build" we will utilize TypeScript compiler to convert .ts files to .js so it can be executed later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//package.json&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ts-node src/index.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tsc -p .&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;//-p invokes the project command that compiles based on tsconfig setup,&lt;/span&gt;
    &lt;span class="c1"&gt;//do not forget the "." to indicate the whole directory&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test that these two commands work:&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="c1"&gt;// should output "hey there"&lt;/span&gt;
    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="c1"&gt;// should not output anything but create index.js file in /lib&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you navigate to /lib/index.js after running "build" this is what you should see:&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;var&lt;/span&gt; &lt;span class="nx"&gt;sayHello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hey there&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="nf"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this code is transformed to ES5 version of JS like we indicated in tsconfig.json. Typescript not only adds types to JS but can also make your .ts file that target earlier versions of JS (super handy!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Step C - Everybody do the shebang
&lt;/h2&gt;

&lt;p&gt;We need to make our program executable, meaning that we can invoke it simply by calling shorthand "weather-cli", without any of that &lt;code&gt;node lib/index.ts&lt;/code&gt; nonsense. To do this we need to add what's called shebang at the top of the file- &lt;code&gt;#!/usr/bin/env node&lt;/code&gt; which instructs bash to treat the file as an executable in node environment. Next we crack open our package.json file and the &lt;code&gt;bin&lt;/code&gt; configuration just like shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bin&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;weather-cli&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./lib/index.js&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;npm will help us out here and create symlink between our index.js file and /usr/local/bin/weather-cli/lib/index.js which will be needed for the &lt;code&gt;npm link&lt;/code&gt; command that we will be running next. It creates a link between local package and global folder. Also, if you are running windows, it is very important that you run this as it will help you with correctly setting up the PATH.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;At this point we are all set and in our terminal typing &lt;code&gt;weather-cli&lt;/code&gt; should execute the program. We can move on to the actual program logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step D - Set and Get API keys
&lt;/h2&gt;

&lt;p&gt;We will need npm package &lt;code&gt;commander&lt;/code&gt; (&lt;a href="https://www.npmjs.com/package/commander" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/commander&lt;/a&gt;) to help us with interact with the command line.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Replace contents of src/index.ts with the following 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="c1"&gt;// src/index.ts&lt;/span&gt;&lt;span class="cp"&gt;
#!/usr/bin/env node
&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commander&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;program&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//arbitrary version - let's go with 1.0.0&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Weather Forecast CLI&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// name of your program goes here&lt;/span&gt;

&lt;span class="nx"&gt;program&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;today&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//keyword or command to invoke the program feature that goes after "weather-cli"&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;t&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//alias or shortening of the command&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Show weather information for today&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="nf"&gt;action&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Today is a nice day&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//actual logic that will be executed&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//parses passed arguments to command line&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you type &lt;code&gt;weather-cli today (or just t)&lt;/code&gt; you should see it print out &lt;code&gt;Today is a nice day&lt;/code&gt;. Pretty cool! You can probably see how we can build out feature set of commands from this point on but let's keep going.&lt;/p&gt;

&lt;p&gt;To get the weather information we will need an API key from &lt;a href="https://darksky.net/dev" rel="noopener noreferrer"&gt;DarkSky&lt;/a&gt;. Feel free to use any other free API provider, but I like Darksky because it has accurate information and more than generous free tier.&lt;/p&gt;

&lt;p&gt;Once we have this key we need to store it somehow in our program. It is typically kept in environment variables, which would be the best option, but we will be using an npm module &lt;code&gt;configstore&lt;/code&gt; which creates a json file in your computer root directory (&lt;code&gt;/Users/username/.config/configstore&lt;/code&gt;). I use it because it makes convenient not only to keep API keys but also other config for the tool (like custom settings).&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Here is a basic implementation of commands that will retrieve API key and will set the key. As you will see below we are using Configstore module to access, and store values. You will notice that instead of simple console.log method we are using something called &lt;code&gt;chalk&lt;/code&gt; which is a great little tool that helps us with terminal styling. You can find the docs here &lt;a href="https://www.npmjs.com/package/chalk" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/chalk&lt;/a&gt; but API is a simple one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Print out red text in the terminal&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="s2"&gt;`{red Warning This Text Is Very Red}`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Main file describing the commands, take a look at "getdarkkey" and "setdarkkey" commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.ts file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiActions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./apiActions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;program&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;getdarkkey&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="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Show Darksky API key if set&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="nf"&gt;action&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;apiActions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;darksky&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="nx"&gt;program&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;setdarkkey&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="nf"&gt;description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Set Darksky API key&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="nf"&gt;action&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;apiActions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;darksky&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&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="c1"&gt;//pass the first argument as key&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the implementation of those two commands in a separate file. We print the feedback/output using chalk.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//apiActions.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chalk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chalk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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;Configstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;configstore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//initialize key with null value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Configstore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;weather-cli&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="na"&gt;DARKSKYAPIKEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DARKSKYAPIKEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="s2"&gt;`
    {green DarkSky API Key: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DARKSKYAPIKEY&lt;/span&gt;&lt;span class="dl"&gt;"&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;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="s2"&gt;`
    {yellow Api key for Darksky is not set, use setdarkkey [key] command to set it up.}
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concludes the Part 1 of the implementation. We've done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project setup with core dependencies (TypeScript, Commander, Chalk, Configstore)&lt;/li&gt;
&lt;li&gt;Created executable and linked the files so we can invoke &lt;code&gt;weather-cli&lt;/code&gt; directly in the terminal&lt;/li&gt;
&lt;li&gt;Implemented functionality to &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; API key for DarkSky&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far we have done a lot of prep. All this work will help to build weather forecast logic in Part 2.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>cli</category>
      <category>api</category>
    </item>
    <item>
      <title>Learn to code like a pro in 30 days</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Wed, 23 Jan 2019 14:16:48 +0000</pubDate>
      <link>https://dev.to/vaidotas/learn-to-code-like-a-pro-in-30-days-3afm</link>
      <guid>https://dev.to/vaidotas/learn-to-code-like-a-pro-in-30-days-3afm</guid>
      <description>&lt;p&gt;There are no shortcuts. Next time you see an article like this - skip it!&lt;/p&gt;

&lt;p&gt;But while I have you fooled, let's talk about patience and deliberate improvement.&lt;/p&gt;

&lt;p&gt;Coding, like any other skill, takes time to learn and a lifetime to master. The bad news is that time alone is not going to cut it. If you keep writing &lt;code&gt;for&lt;/code&gt; loops for 12 months, you will become really good at writing &lt;code&gt;for&lt;/code&gt; loops but not much else. So how do you become a "pro"? You develop a plan.&lt;/p&gt;

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

&lt;p&gt;Your plan must be designed to stretch your understanding to the very cusp where familiar turns into scary. That is where the learning happens. In the simplest example it goes like this: A) Learn to change the color of a button B) Introduce pseudo-class to make button really pop on hover C) Animate the transitions so it looks amazing&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aim -&lt;/strong&gt; Incremental addition to complexity building upon base understanding&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid -&lt;/strong&gt; Building the same (in terms of complexity) thing over and over again.&lt;/p&gt;

&lt;p&gt;As far as actual plan goes for your goal - there are many to choose from depending on what you are after. First understand your goals, then pick a plan and &lt;strong&gt;stick to it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patience
&lt;/h2&gt;

&lt;p&gt;So you've got a plan and some time set aside to execute it. Now what?&lt;/p&gt;

&lt;p&gt;Keep at it. This is the hardest part, it is inevitable that distraction will creep in. After the first few days or weeks (if you are lucky) doubts, insecurities and distractions will start seeping into your conscience.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What if I drop React and start learning Vue instead? I heard Vue is cool on a podcast.&lt;/li&gt;
&lt;li&gt;Maybe I should play with Golang, everybody is talking about it.&lt;/li&gt;
&lt;li&gt;Is development even for me? I may be too (dumb, old, marginalized, busy, lazy ⇒ insert your self-sabotage go-to reason here) for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These thoughts are very dangerous, I think that is where 90% of good intentions and project ideas and self-improvement goals fail. You have to be pushing through this noise and executing on your plan no matter what. Ignore the distractions and doubts, drown those pesky thoughts with the noise of your fingers hitting the keyboard.&lt;/p&gt;

&lt;p&gt;Success will come. But not in 30 days. Be patient.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>motivation</category>
    </item>
    <item>
      <title>10 Podcasts for Developers in 2019</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Fri, 18 Jan 2019 20:28:05 +0000</pubDate>
      <link>https://dev.to/vaidotas/10-podcasts-for-developers-in-2019-2l13</link>
      <guid>https://dev.to/vaidotas/10-podcasts-for-developers-in-2019-2l13</guid>
      <description>&lt;p&gt;There are very few good things about having a commute to work every day. Dev podcasts is one of them. You can learn something new, keep up with the latest and greatest and even in some cases be entertained (looking at you Soft Skills Engineering!). Here my list of top 10 podcasts I listen to today in no particular order.*&lt;/p&gt;

&lt;p&gt;*I subscribe to way more podcasts than this, but in the spirit of brevity I am cutting the list to 10.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://shoptalkshow.com" rel="noopener noreferrer"&gt;Shoptalk Show&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Dave Rupert, Chris Coyier&lt;/em&gt;&lt;br&gt;
Front end focused show about design and development of modern websites. Dave and Chris are always worth listening whether they have a guests or not. In fact, their "rapid fire" episodes where they answer questions of their listeners are one of my favorites.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://reactpodcast.simplecast.fm/" rel="noopener noreferrer"&gt;The React Podcast&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Chantastic, Michael Jackson&lt;/em&gt;&lt;br&gt;
You can probably guess what this show is about. That's right, it is about VueJS (jk). Chantastic and Michael does a great job talking to a wide variety of guests directly or tangentially related to React ecosystem. In fact, they recently did a great episode with React core team about its future. It is a must for those of us who are in React world!&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://postlight.com/trackchanges" rel="noopener noreferrer"&gt;Track Changes&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Paul Ford, Rich Ziade&lt;/em&gt;&lt;br&gt;
Not strictly speaking development podcasts, however, it is one of my favorites. Paul (of &lt;a href="https://www.bloomberg.com/graphics/2015-paul-ford-what-is-code/" rel="noopener noreferrer"&gt;What is Code&lt;/a&gt; fame) and Rich are co-founders of Postlight digital product studio in NYC. Their musings about current state of technology, weird rants about social media and ever so interesting guests makes it a delight to listen.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://dotnetrocks.com/" rel="noopener noreferrer"&gt;.NET Rocks&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Carl Franklin, Richard Campbell&lt;/em&gt;&lt;br&gt;
If you are in JS ecosystem, do not be put off by the title of the podcast. It is one of the longest running shows in town, focusing on all sides of technology. It can be a little Microsoft centric in terms of guests but it always delivers high quality content, great conversations and "geekouts" which delve deeply in a topic that expand your horizons. Carl and Richard are pros at what they do and other podcasts have a lot to learn from them.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://changelog.com/podcast" rel="noopener noreferrer"&gt;The Changelog&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Adam Stacoviak, Jerod Santo&lt;/em&gt;&lt;br&gt;
What makes Changelog special is high production quality and excellent guests. Focusing mostly on Open Source, Adam and Jerod delivers every time. If you want to be in the know of what is going on in the industry I think this is a great way to do so. One of the recent episodes with Dominic Tarr (event-stream incident for those who do not know) was excellent. &lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://syntax.fm/" rel="noopener noreferrer"&gt;Syntax&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Scott Tolinski, Wes Bos&lt;/em&gt;&lt;br&gt;
This is one of the youngest podcasts in the list. Scott and Wes covers JS ecosystem and latest and greatest technologies, frameworks, libraries, you name it. If you are familiar with their courses, you can expect the same quality work in this podcasts (watch out for those sick sponsor transitions by Scott).&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://darknetdiaries.com/" rel="noopener noreferrer"&gt;Darknet Diaries&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Jack Rhysider&lt;/em&gt;&lt;br&gt;
Story driven podcast that dives into the "dark" side of tech. Jack delivers a great insight into data breaches, hacks and other malicious actors and actions of the cyber space. It is a great little gem of a podcast that I discovered fairly recently.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://changelog.com/jsparty" rel="noopener noreferrer"&gt;JS Party&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Suz Hinton, Kevin Ball, Jerod Santo, Christopher Hiller, Safia Abdalla, others&lt;/em&gt;&lt;br&gt;
Second entry from the Changelog family. JS Party is JS centric (duh!) podcast covering a lot of new and more mature technology. Show hosts are great and provide a good variety of opinions.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="http://frontendhappyhour.com/" rel="noopener noreferrer"&gt;Front End Happy Hour&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Ryan Burgess, Stacy London, Jem Young, Augustus Yuan&lt;/em&gt;&lt;br&gt;
While Front End is in the name, hosts cover a lot more topics than that. There is a good balance of opinions and excellent guests. You get the feeling that hosts do come with a lot of experience in the industry and valuable insights.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  &lt;a href="https://softskills.audio/" rel="noopener noreferrer"&gt;Soft Skills Engineering&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Dave Smith, Jamison Dance&lt;/em&gt;&lt;br&gt;
This podcast is a delight, especially when jokes do not land that well, it still makes you giggle. Dave and Jamison focus on other aspects of development (salary negations, navigating company culture, dealing with coworkers and bosses, etc). Write-in questions give you an insight into how other companies operate and what other developers have troubles with.&lt;/p&gt;




&lt;p&gt;That is it folks! There are many more, but if you are new to podcasting, these are great to start with! &lt;br&gt;
&lt;strong&gt;Share your favorites below!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>podcast</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Resistance and Learning To Code</title>
      <dc:creator>Vaidotas Piekus</dc:creator>
      <pubDate>Sun, 16 Dec 2018 16:27:33 +0000</pubDate>
      <link>https://dev.to/vaidotas/resistance-and-learning-to-code-2bgh</link>
      <guid>https://dev.to/vaidotas/resistance-and-learning-to-code-2bgh</guid>
      <description>&lt;h2&gt;
  
  
  What is Resistance?
&lt;/h2&gt;

&lt;p&gt;Do you know the feeling of sitting down to write code and ending up on YouTube/Twitter/Egghead/Pluralsight watching tutorials and "learning", feeling productive but not actually writing any &lt;em&gt;new&lt;/em&gt; code? Some people call it Tutorial Hell, some say it is simply procrastination.&lt;/p&gt;

&lt;p&gt;There is another word for it - Resistance. &lt;/p&gt;

&lt;p&gt;Steven Pressfield in his book &lt;a href="https://www.amazon.com/War-Art-Winning-Creative-Battle/dp/1501260626"&gt;The War of Art&lt;/a&gt; describes resistance as something that is self-generated, self-perpetuated, a feeling, a pull that a person experiences when they visualize who they are (a writer, a painter, an entrepreneur) but they do not take the steps to achieve that vision.&lt;/p&gt;

&lt;p&gt;In the first passages he describes it well: "Are you a writer who doesn't write, a painter who doesn't paint, an entrepreneur who never starts a venture? Then you know what Resistance is." Adjusting this to the topic at hand - "Are you a programmer who does not program?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Recognizing the pull of Resistance
&lt;/h2&gt;

&lt;p&gt;As a person who is switching between careers, from known to unknown, from something I am competent in to something that is frightening, I feel the pull of Resistance every day as I sit down to write a line of code. You might too. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your time is being hijacked by the gravitational pull towards Twitter with the self justification that you will actually learn something while scrolling through the infinite expanses of self actualization - that is a sign.&lt;/li&gt;
&lt;li&gt;If you are constantly distracted by new and shiny technologies and have dozens of half baked personal projects that never see the light of day - that is another sign.&lt;/li&gt;
&lt;li&gt;If you are constantly googling developer salaries and trying to figure out if the career switch is worth it and is a smart move - well, you are basically me.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing this post is, in some sense, Resistance telling me to do this instead of my work. You reading this post is the same. It aligns with our internal fear, fear of success, fear of hard work, fear of pursuing what we were meant to pursue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conquering Resistance
&lt;/h2&gt;

&lt;p&gt;Fighting this force in our heads is something that becomes easier with discipline. However, it does not mean that it will ever go away. Every day we will come up with an excuse of doing something else than work, exploring something that is tangentially related to the craft but not the craft itself. We will find justifications, and damn good ones too.&lt;/p&gt;

&lt;p&gt;The one answer I found was the commitment to the craft full-time. Not dabbling in and out, but in our heads making the seal of unbreakable pact with ourselves. Steven Pressfield calls it "turning pro". &lt;/p&gt;

&lt;p&gt;We show up to work everyday no matter what. We &lt;a href="https://johnresig.com/blog/write-code-every-day/"&gt;write code everyday&lt;/a&gt;. We focus on the long term gains and not the short term gratification. Putting in the work is what matters, success is a side effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules for success
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Show up to work every day for set time. Do not wander during that time, stay focused and practice the craft.&lt;/li&gt;
&lt;li&gt;Ignore what others are telling you about the risk, uncertainty or choices. If you feel alive and immersed in the practice of coding, listen to that voice.&lt;/li&gt;
&lt;li&gt;Do not focus on immediate metrics as tweet likes, blog post shares, downloads or job offers. Keep you mind on the work itself and the needed steps to reach your future goal. Success will come later, it is irrelevant while you work.&lt;/li&gt;
&lt;li&gt;Finish what you stated and move on to the next objective. Do not look back and second guess yourself.&lt;/li&gt;
&lt;li&gt;That's it.&lt;/li&gt;
&lt;/ol&gt;

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