<?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: Sasha Koss</title>
    <description>The latest articles on DEV Community by Sasha Koss (@kossnocorp).</description>
    <link>https://dev.to/kossnocorp</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%2F91465%2F1f56402d-525e-455f-9449-88ac955c4586.jpeg</url>
      <title>DEV Community: Sasha Koss</title>
      <link>https://dev.to/kossnocorp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kossnocorp"/>
    <language>en</language>
    <item>
      <title>Write plain CSS while reaping the benefits of CSS-in-JS</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Thu, 08 Aug 2019 13:50:57 +0000</pubDate>
      <link>https://dev.to/kossnocorp/write-plain-css-while-ripping-the-benefits-of-css-in-js-apc</link>
      <guid>https://dev.to/kossnocorp/write-plain-css-while-ripping-the-benefits-of-css-in-js-apc</guid>
      <description>&lt;p&gt;Modern CSS land is divided into CSS-in-JS followers and plain CSS adherents with an ongoing controversy about which approach is superior. Despite the fight, it benefits us by advancing the ecosystem and making it more vibrant.&lt;/p&gt;

&lt;p&gt;While plain CSS users get established tooling, simplicity, performance, and portability, the CSS-in-JS users enjoy the reliability and tight integration with the app code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why don't we have both?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/nyancss/nyancss" rel="noopener noreferrer"&gt;Nyan CSS&lt;/a&gt; is a convention that allows to write good ol' CSS and import the styles as components (React/Preact/Vue.js).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's how it works&lt;/strong&gt;. First, you define CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.Header&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.Text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.Header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.Header-size-large&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.Text-italic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;italic&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;Then you import it as components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./style.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Announcement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h1"&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"large"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Welcome Nyan CSS!
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"marquee"&lt;/span&gt; &lt;span class="na"&gt;italic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Please, welcome Nyan CSS!
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so you get:&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%2Fraw.githubusercontent.com%2Fnyancss%2Fnyancss%2Fc928384e8878e492c24f330b1ce49d66a89808bd%2Fdocs%2Fdemo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnyancss%2Fnyancss%2Fc928384e8878e492c24f330b1ce49d66a89808bd%2Fdocs%2Fdemo.gif" alt="A page in a browser with large "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essentially Nyan CSS is a convention plus family of libraries that provides tight integration with frameworks (React, Preact, Vue.js, class names). You don't need to install anything to use Nyan CSS with HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  The convention
&lt;/h2&gt;

&lt;p&gt;The convention is simplisitic and consist just of three rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;.Button&lt;/code&gt; is a CSS class which represents a component (other examples are &lt;code&gt;.ListItem&lt;/code&gt; , &lt;code&gt;.UI&lt;/code&gt; , etc.) and can be used as &lt;code&gt;&amp;lt;Button&amp;gt;Content&amp;lt;/Button&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.Button-disabled&lt;/code&gt; generates a component with a boolean prop (e.g. &lt;code&gt;.Button-fullWidth&lt;/code&gt;, &lt;code&gt;.Window-inactive&lt;/code&gt;) and can be used as &lt;code&gt;&amp;lt;Button disabled /&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.Button-color-red&lt;/code&gt; represents a component with an enum prop (e.g. &lt;code&gt;.Spacing-direction-column&lt;/code&gt;, &lt;code&gt;.Window-mode-alert&lt;/code&gt;) and can be used as &lt;code&gt;&amp;lt;Button color='red' /&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Universal design system
&lt;/h2&gt;

&lt;p&gt;Because Nyan CSS is just CSS, it can be used across different projects built using different technologies with no code changes. Use the same styles for a static landing page with no JS as for React SPA.&lt;/p&gt;

&lt;p&gt;Web technologies envolve, fashion and passion changes, and just a few things remain HTML, CSS, and JS. CoffeeScript made our lives better with its legacy, but the language itself became history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero overhead
&lt;/h2&gt;

&lt;p&gt;With no runtime that manipulates CSS in a browser, Nyan CSS ensures maximum performance by reducing JavaScript build size and leaving CSS management to the browser.&lt;/p&gt;

&lt;p&gt;I was inspired by Styled Components myself, but I was working on a widget and didn't want to add extra 15Kb, so I created Nyan CSS that is not 5x size of &lt;a href="https://preactjs.com/" rel="noopener noreferrer"&gt;the framework I use&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You don't need to install plugins for your editor, transpile before use or parse it anyhow. It's just CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Battle-tested
&lt;/h2&gt;

&lt;p&gt;I incrementally improve the approach for the &lt;a href="https://medium.com/dailyjs/js-in-css-df4cf8b9b96c" rel="noopener noreferrer"&gt;last two years&lt;/a&gt;. I &lt;a href="https://gist.github.com/kossnocorp/653f032f4a7cf469c982aa06c290d559" rel="noopener noreferrer"&gt;developed 6 different applications&lt;/a&gt; (demo: &lt;a href="https://diaryemail.com/" rel="noopener noreferrer"&gt;Diary Email&lt;/a&gt;) using Nyan CSS and confident that &lt;strong&gt;it just works&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's talk
&lt;/h2&gt;

&lt;p&gt;What do you think? &lt;a href="https://github.com/nyancss/nyancss" rel="noopener noreferrer"&gt;Give it a try&lt;/a&gt;. And then you can tell me if it's good or not ;-)&lt;/p&gt;

</description>
      <category>nyancss</category>
      <category>cssinjs</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>date-fns v2 beta is out!</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Wed, 26 Jun 2019 11:31:41 +0000</pubDate>
      <link>https://dev.to/kossnocorp/date-fns-v2-beta-is-out-497g</link>
      <guid>https://dev.to/kossnocorp/date-fns-v2-beta-is-out-497g</guid>
      <description>&lt;p&gt;For those who don't know, date-fns is a modern JavaScript date utility library. It's focused on build size and performance. It's tree-shakable so only used functionality will be included in your build. The minimal build size is just 295 B that makes it the smallest date library in JS world! Unlike other date libraries, date-fns uses native &lt;code&gt;Date&lt;/code&gt; object and embraces the functional approach.&lt;/p&gt;

&lt;p&gt;It took us two years to develop v2, and during the time we reworked every bit of the library. We've merged nearly 500 pull requests from a hundred contributors! Today I invite you to give it a try:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;date-fns@next &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;span class="c"&gt;# or using Yarn:&lt;/span&gt;
yarn add date-fns@next
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's stable, and we don't plan to change the API. It could have been a final release, but as it introduces plenty of breaking changes in the upcoming days, we're going to work on making the upgrade process as smooth as possible. In meanwhile, you can help us by testing the library and sharing your feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new?
&lt;/h2&gt;

&lt;p&gt;Here some most exciting features, for the full list of changes (it's enormous!) see the changelog: &lt;a href="https://date-fns.org/v2.0.0-beta.1/docs/Change-Log"&gt;https://date-fns.org/v2.0.0-beta.1/docs/Change-Log&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EcmaScript Modules&lt;/strong&gt;. With v2 we ship both ESM and CommonJS, so if your bundler supports tree-shaking you can import functions directly from the root of the package and still get slim build:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatDistance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatRelative&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'date-fns'&lt;/span&gt;

&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s2"&gt;"'Today is a' iiii"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; "Today is a Wednesday"&lt;/span&gt;

&lt;span class="nx"&gt;formatDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; "3 days ago"&lt;/span&gt;

&lt;span class="nx"&gt;formatRelative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; "last Friday at 7:26 p.m."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also, we adopted the camelcase naming scheme:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before v2.0.0&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;addDays&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'date-fns/add_days'&lt;/span&gt;

&lt;span class="c1"&gt;// v2.0.0 onward&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;addDays&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'date-fns/addDays'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Another feature I'm sure FP fans will love is new &lt;strong&gt;FP submodule&lt;/strong&gt;. It introduces copies of regular functions which accept arguments in inverse order and curryied by default. They could be imported from date-fns/fp and used along with regular functions.&lt;/p&gt;

&lt;p&gt;The main advantage of FP functions is the support of &lt;a href="https://medium.com/making-internets/why-using-chain-is-a-mistake-9bc1f80d51ba"&gt;functional-style function composing&lt;/a&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;differenceInDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;regularDifferenceInDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'date-fns'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;differenceInDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fpDifferenceInDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'date-fns/fp'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;regularDifferenceInDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&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;//=&amp;gt; 17815&lt;/span&gt;

&lt;span class="nx"&gt;fpDifferenceInDays&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 17815&lt;/span&gt;

&lt;span class="nx"&gt;fpDifferenceInDays&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 17815&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;daysSinceUnixEpoch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fpDifferenceInDays&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="nx"&gt;daysSinceUnixEpoch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 17815&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We added dozens of new functions, but one requires special attention: &lt;code&gt;parse&lt;/code&gt;. It allows parsing a string using arbitrary format:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'date-fns'&lt;/span&gt;

&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'02/11/2014'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'MM/dd/yyyy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; Tue Feb 11 2014 00:00:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That was possibly the most requested feature and to make it happen we completely rewrote I18n code.&lt;/p&gt;

&lt;p&gt;Also, we carefully refined every function to make date-fns consistent, predictable, and reliable. We made it work in edge cases like ECMAScript would work. You can &lt;a href="https://dev.to/kossnocorp/date-fns-v2-api-design-2jig"&gt;read more about v2 API design in a DEV post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;After we ship the final version, there are few initiatives that we want to focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UTC versions of functions.&lt;/li&gt;
&lt;li&gt;Durations support.&lt;/li&gt;
&lt;li&gt;Time zones (right now TZ functionality is provided by &lt;a href="https://www.npmjs.com/package/date-fns-tz"&gt;date-fns-tz&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Integration with Intl API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Neither v2 nor date-fns, in general, would not be possible without &lt;a href="https://github.com/date-fns/date-fns/graphs/contributors"&gt;153 contributors&lt;/a&gt; that helped to make date-fns awesome. I wish I could mention everyone but the list would be too big. But I can't skip my brother, &lt;a href="https://twitter.com/leshakoss"&gt;Lesha Koss&lt;/a&gt; that wrote the bulk of date-fns code. You're amazing!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you for reading! I hope you'll love v2. Join &lt;a href="https://spectrum.chat/date-fns"&gt;date-fns community at Spectrum&lt;/a&gt; and &lt;a href="https://twitter.com/date_fns"&gt;follow us on Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datefns</category>
      <category>javascript</category>
      <category>dates</category>
    </item>
    <item>
      <title>If you want to ship a side project, start with unlearning the best practices</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Mon, 13 May 2019 12:36:00 +0000</pubDate>
      <link>https://dev.to/kossnocorp/if-you-want-to-ship-a-side-project-start-with-unlearning-the-best-practices-5b1l</link>
      <guid>https://dev.to/kossnocorp/if-you-want-to-ship-a-side-project-start-with-unlearning-the-best-practices-5b1l</guid>
      <description>&lt;p&gt;Two years ago was my last week as a software engineer at Toptal where I was leading team of 12 people. Since then I work on my projects full-time. That was my the most productive and satisfying years for the whole decade-long+ career. While I still far from achieving my goal of building a sustainable business I learned a lot about product development, copy, marketing, and sales. &lt;strong&gt;In this article, I share lessons I learned as a developer while I was working on a dozen projects.&lt;/strong&gt; If you like me, have an itch for making stuff and seeking for independence, this piece is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning the best practices
&lt;/h2&gt;

&lt;p&gt;My first years as a professional developer was rough. After I failed as an indie game developer for a few years I was working as a freelancer making various web projects. &lt;em&gt;I was a developer you wouldn't want to see in your team.&lt;/em&gt; I worked long hours on low-budget projects with unrealistic estimations that were making both my clients and me disappointed in the outcome if there was one at all. Bugs, missed deadlines, features that didn't meet the expectations, I saw it all. I didn't know positive examples I but was sure that there's a better way to develop projects.&lt;/p&gt;

&lt;p&gt;After yet another flopped project I opened for myself Ruby world that felt like a different realm. The community greatly influenced my views on development, project management, and business. I read &lt;a href="https://basecamp.com/books/getting-real"&gt;Getting Real&lt;/a&gt; and all books I could find on business and project management. I religiously studied and tried all known methodologies that suppose to improve the code quality and productivity. SOLID, TDD, BDD, GTD, SCRUM, you name it. &lt;em&gt;It took another few years before I became a developer that you would want to see on your team.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During all that time I was always working on side projects. I started dozens of them of all kinds, from todo lists, ticket trackers to social networks. They were taking all my free time, but I never managed to finish any of them. At first, I got excited about the idea, came up with a new shiny stack of technologies, and then developed it applying the best methodologies I learned the hard way. Then I would be stuck, lost interest or came up with a new, better idea. When I quit my job and started investing my own money into projects, I quickly realized what I was doing wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do your worst
&lt;/h2&gt;

&lt;p&gt;The practices that are vital in teams might be poisonous when you work alone. Paradoxically, &lt;strong&gt;to do your best you must do your worst!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When there's dozen of people working on a single code base, it's necessary to ensure that the systems are designed well, the code is easy to read and have decent test coverage. Pull requests should be reviewed and merged only when they satisfy the team standards. "I'll refactor it later" never works in the teams because there's too much going on and more likely the next person that touches your code won't be you.&lt;/p&gt;

&lt;p&gt;When you work alone, following the best practices slow you down. When you're the single code owner, you can defer writing tests until you met a critical part that can't break at any cost. Even then just couple end-to-end test could be enough. It doesn't mean that I avoid tests altogether. If the code is easy to write thought unit tests or too hard to test manually, I do it. &lt;/p&gt;

&lt;p&gt;There's nothing worse in code design than a poorly chosen abstraction. When I develop my products, I prefer to copy-paste code two, three and even more times until I see a common pattern and if and only if I change it frequently. It doesn't matter if you have 3 repeating pieces in the code if you are never going to change it. After all, the whole point of refactoring is to make it easy to modify. I think this realization still applies to teams, but you must be systematical about it and keep a ticket in your backlog or notes in the comments.&lt;/p&gt;

&lt;p&gt;Focusing on performance is another mistake I was repeatable making. We all the time see tweets and articles about the importance of small code bundle, fast response time or small memory print. Developers often shame companies for their sloppy work, and you might think that your small business won't survive without providing the top-notch experience. The truth is not that important if you never ship your project. People won't buy your product only because it loads in less than a second, but if it solves their problem, they will wait 5 seconds and even more. If your page has poor performance if the user created a lot of content that is a great problem to have because that means somebody actually uses it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It doesn't matter how well your code is written, what is test coverage or how fast is it if it never shipped or has no users.&lt;/strong&gt; Also, your first customers will be early adopters that want to have an advantage of being the first using it, and too polished product might signal them that it's too late.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stick to the tech you already know
&lt;/h2&gt;

&lt;p&gt;The whole career I was chasing the better programming languages, newest frameworks and most efficient ways to manage infrastructure. I tried at least one new tech in every side project I started, and because most of the time I was wrapping my head around and learning new concepts I never managed to get to shipping. No doubts it was beneficial for my career as I learned much more than the average engineer. It made my truly full-stack developer that can do everything from infrastructure to front-end. It also helped me to satisfy my passion for new tech without hurting my employer by experimenting in the production code.&lt;/p&gt;

&lt;p&gt;When I started my indie maker adventure I wanted to ship instead of learning so I decided to stick to the stack, I know the best — JavaScript both on back-end and front-end. Even though I was capable of managing infrastructure myself, I choose the Firebase platform that provided everything from static website hosting, servers to a managed database. It wasn't optimal, most efficient and elegant, but because of my prior experience, it all helped me to start and focus on products quickly.&lt;/p&gt;

&lt;p&gt;At the end of the day, I don't use most of the technologies I learned, and there's plenty of excellent examples of founders without prior programming experience that taught them self to code by doing and started making more money and much faster than me. It made me wonder if it was worth it all.&lt;/p&gt;

&lt;p&gt;If your only goal is to learn new stuff, you can ignore my advice, but if you want to ship, &lt;strong&gt;avoid using new technologies unless necessary.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Be lean
&lt;/h2&gt;

&lt;p&gt;For many years I worked in companies where quality was the priority. It wasn't acceptable to deploy half backed product that doesn't provide up to standard experience on all levels from the core functionality to small details. If the user enters their name, there must be a setting for that. If there's a list, there must be pagination. And so on and so forth.&lt;/p&gt;

&lt;p&gt;When you are small, even a standard feature like name settings or password recovery could take the time that might be spent on more important things. When I was working on designs for my first big project, &lt;a href="https://askuser.xyz/"&gt;Ask User&lt;/a&gt; a widget for web sites, I noticed that I spend too much time on details that aren't necessary for the first release. I started cutting features until I left with the functionality that solves the main problem. During the development, I decided to step further and skipped things that seemed absolutely necessary at first, like the ability to remove created sites. I was planning to introduce that after the release but to my surprise, users didn't care. They wanted utterly different features that I didn't even think of initially.&lt;/p&gt;

&lt;p&gt;Then I spend weeks writing a billing system only to learn that people don't ready to pay for the problem I solve. For the next project, &lt;a href="https://telepost.io/"&gt;Telepost&lt;/a&gt;,  I decided to ask users to send me money to PayPal, and it worked out. Later I added a button "Activate the Pro plan" that does nothing but shows the message "We'll contact you soon" and sends me an email (using Zapier) with the user details. Then I'd talk with each interested customer individually. During the conversation, I was able to pitch my product and hear objections about why they aren't ready to pay. That not only saved me time but also helping to shape my project for users' needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting feedback as soon as possible and changing your product according to it, must be your top priority, so optimize for shipping fast. Cut as many features as possible, then cut more.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Thank you for reading my article. I hope it was useful for you. I tried to outline the most important lessons I learned as a developer, but there's so much more to cover! If you liked it, please let me know. I'm planning to publish more articles on the topic including more business-oriented and if you're interested in reading them first, &lt;a href="https://twitter.com/kossnocorp"&gt;follow me on Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The photo for cover is kindly provided by &lt;a href="https://unsplash.com/photos/9cCeS9Sg6nU"&gt;chuttersnap&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>business</category>
      <category>sideprojects</category>
      <category>bootstrapping</category>
      <category>lessons</category>
    </item>
    <item>
      <title>date-fns v2 API design</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Wed, 12 Dec 2018 16:00:09 +0000</pubDate>
      <link>https://dev.to/kossnocorp/date-fns-v2-api-design-2jig</link>
      <guid>https://dev.to/kossnocorp/date-fns-v2-api-design-2jig</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://date-fns.org/" rel="noopener noreferrer"&gt;date-fns&lt;/a&gt; is JavaScript library for working with dates. It's a modern alternative to Moment.js.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For almost two years we've been working on a new major release — v2. We've reworked nearly every aspect of the library and added many exciting features. One of the most critical changes in v2 is the new API design. We carefully refined every function to make date-fns consistent, predictable and reliable. In this post, I tell about goals and values that helped us to design simple API that is pleasant to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals and values
&lt;/h2&gt;

&lt;p&gt;When we just started working on date-fns, our only goal was to build a library for working with dates in functional style. For years we were adding more and more functions, often copying and adapting Moment.js API without second look on it.&lt;/p&gt;

&lt;p&gt;After a while, we realized that our API and behavior is not as consistent as we want them to be. Arguments in functions doing a similar job were not always in the same order and had a different naming scheme. Sometimes functions were throwing exceptions where they shouldn't and weren't throwing when they should. I'm not talking about coercion logic; it was behind even our understanding.&lt;/p&gt;

&lt;p&gt;The need for changes was obvious, but first, we had to define goals and values, that would help us make decisions in ambiguous cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stick to JavaScript behavior whenever possible&lt;/strong&gt;. We want date-fns to be an extension of the language and its standard library but not a substitute. We believe that it will ensure a long life of the library in the rapidly changing ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stick to existing standards&lt;/strong&gt;. Instead of reinventing the wheel and relying on our subjective opinion we decided to look for current standards and well-established practices. That will provide the best compatibility with other languages and save us from mistakes that others made years if not decades ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt;. We want date-fns to be as predictable and easy to understand as possible. Function names, the order of arguments and the behavior must be consistent across the whole library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explicitness&lt;/strong&gt;. date-fns should prefer explicitness over implicitness. Sometimes the latter helps to make code look cleaner. You know that feeling when a library does what you wanted it to do without saying a word. But more often it causes bugs that are hard to debug or even worse to notice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convenience&lt;/strong&gt;. We want date-fns to be pleasant to use. We should help developers to avoid mistakes.&lt;/p&gt;

&lt;p&gt;While the last three are self-explanatory, the first two requires deep dive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stick to JavaScript behavior whenever possible
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why
&lt;/h3&gt;

&lt;p&gt;The initial idea of the library was to create a set of helpers that will work with the native &lt;code&gt;Date&lt;/code&gt; object. We avoided introducing functionality that already existed in the standard library and named functions as they are part of it. In v2 we decided to go further and made date-fns behave like JavaScript in every aspect.&lt;/p&gt;

&lt;p&gt;JavaScript and its behavior is often a subject of just critique. Because of the need for backward compatibility over the years, it accumulated nuances that nowadays considered as a bad language design. Yes, I'm talking about its coercion rules, &lt;code&gt;NaN&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; and so on.&lt;/p&gt;

&lt;p&gt;However, behind every strange looking behavior stands logic consistent across the language. It might be covering weak parts of JavaScript, but it's consistent and if you learn it once it starts making sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exceptions
&lt;/h3&gt;

&lt;p&gt;In v2 we made date-fns throw &lt;code&gt;TypeError&lt;/code&gt; and &lt;code&gt;RangeError&lt;/code&gt; in cases when standard JavaScript functions do it.&lt;/p&gt;

&lt;p&gt;Whenever an argument is required, JavaScript throws &lt;code&gt;TypeError&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; TypeError: 1 argument required, but only 0 present.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;From now all functions check if the passed number of arguments is less than the number of required arguments and throw &lt;code&gt;TypeError&lt;/code&gt; exception if so:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;addDays&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; TypeError: 2 arguments required, but only 0 present&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Whenever an argument value is not in the set or range of allowed values, JavaScript throws &lt;code&gt;RangeError&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; RangeError: toFixed() digits argument must be between 0 and 100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;From now on functions throw &lt;code&gt;RangeError&lt;/code&gt; if optional values passed to options are not &lt;code&gt;undefined&lt;/code&gt; or have expected values:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatDistanceStrict&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;formatDistanceStrict&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2014&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2015&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;roundingMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;qwe&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; RangeError: roundingMethod must be 'floor', 'ceil' or 'round'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Coercion
&lt;/h3&gt;

&lt;p&gt;Just like JavaScript date-fns coerce passed arguments to the expected type.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;addDays&lt;/span&gt;&lt;span class="p"&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="mi"&gt;1987&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;42&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; Wed Mar 25 1987 00:00:00 GMT+0530 (+0530)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Despite being the most hated aspect of the language, coercion is quite straightforward and consistent, although it leads to unexpected results in combination with arithmetic operators. &lt;/p&gt;

&lt;p&gt;Here are the rules that we use to coerce the arguments:&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%2F5zg2bzi4b8nd7xjdll3w.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%2F5zg2bzi4b8nd7xjdll3w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the columns are what type we expect the argument to be and the rows what we actually supply as an argument — for example, in addDays the first argument will be transformed by the rules from the “date” column, and the second argument by the rules from the “number” column, so &lt;code&gt;addDays(1, '1')&lt;/code&gt; is equivalent to &lt;code&gt;addDays(new Date(1), 1)&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Invalid date
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Date&lt;/code&gt; internally represented by a number so just like   with &lt;code&gt;Number&lt;/code&gt;, incorrect operations on dates results in &lt;code&gt;Invalid Date&lt;/code&gt; (an invalid date is a date which time value is &lt;code&gt;NaN&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&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;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nope&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; NaN&lt;/span&gt;

&lt;span class="nx"&gt;date&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; Invalid Date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;date-fns reflects this behavior and will return &lt;code&gt;Invalid date&lt;/code&gt; when you pass unconvertable values:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addDays&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns/addDays&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;addDays&lt;/span&gt;&lt;span class="p"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nope&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; 'Invalid date'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This was one of the trade-offs that were particularly hard to make:&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;On the one hand, we would expect to have an exception when an argument has a wrong value. On the other hand, the exception would force us to wrap every function call into try-catch blocks that is bad developer experience. The standard JavaScript's approach to the problem is to expect the developer to be responsible for validating the user input. In the worst case scenario, the application will print &lt;code&gt;Invalid Date&lt;/code&gt; and keep working that wouldn't happen if we'd throw exceptions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ongoing work
&lt;/h3&gt;

&lt;p&gt;While writing the post, I found an inconsistency that we didn't consider. While &lt;code&gt;toString&lt;/code&gt; called on an invalid date returns &lt;code&gt;Invalid Date&lt;/code&gt;, &lt;code&gt;toISOString&lt;/code&gt; as well as Intl API throws &lt;code&gt;RangeError&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 'Invalid Date'&lt;/span&gt;

&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; RangeError: Invalid time value&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; RangeError: Invalid time value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We incorrectly applied &lt;code&gt;toString&lt;/code&gt; behavior to &lt;code&gt;format&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&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;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHours&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yyyy-MM-dd&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; 'Invalid Date'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I've opened an issue that we plan to fix before the first beta release:&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/date-fns/date-fns/issues/987" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        format functions must throw exceptions on attempt on processing invalid dates
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#987&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/kossnocorp" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars1.githubusercontent.com%2Fu%2F52201%3Fv%3D4" alt="kossnocorp avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/kossnocorp" rel="noopener noreferrer"&gt;kossnocorp&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/date-fns/date-fns/issues/987" rel="noopener noreferrer"&gt;&lt;time&gt;Nov 20, 2018&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;See JavaScript's &lt;code&gt;toISOString&lt;/code&gt; and Intl API for the reasoning:&lt;/p&gt;
&lt;div class="highlight highlight-source-js js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;date&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Date&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;

&lt;span class="pl-s1"&gt;date&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;setHours&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'nope'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;
&lt;span class="pl-c"&gt;//=&amp;gt; NaN&lt;/span&gt;

&lt;span class="pl-s1"&gt;date&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getYear&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;
&lt;span class="pl-c"&gt;//=&amp;gt; NaN&lt;/span&gt;

&lt;span class="pl-s1"&gt;date&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;toString&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;
&lt;span class="pl-c"&gt;//=&amp;gt; Invalid date&lt;/span&gt;

&lt;span class="pl-s1"&gt;date&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;toISOString&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;
&lt;span class="pl-c"&gt;//=&amp;gt; RangeError: Invalid time value&lt;/span&gt;

&lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Intl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'en-US'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;format&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;date&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;
&lt;span class="pl-c"&gt;//=&amp;gt; RangeError: Invalid time value&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/date-fns/date-fns/issues/987" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Stick to existing standards
&lt;/h2&gt;

&lt;p&gt;v2 started with the change of the filenames naming scheme. I come from the Ruby world, so I thought it's a good idea to have file names in underscore format. JavaScript renaissance just started, so there wasn't a common standard. Initially, it was irritating to see so many JavaScript'ers using the camel case format for files. But eventually, I accepted the difference and decided to prioritize common practices over personal taste and adopted camel case as well.&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;// v1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addDays&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="s1"&gt;date-fns/add_days&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// v2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addDays&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="s1"&gt;date-fns/addDays&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;This breaking change was a turning point that allowed us to abstract from our points of views and habits and embrace existing standards and well-established practices.&lt;/p&gt;

&lt;p&gt;One of the most significant changes was adopting Unicode Technical Standard #35 for &lt;code&gt;format&lt;/code&gt; and &lt;code&gt;parse&lt;/code&gt;. It caused a lot of confusion, but I believe it's worth it. &lt;a href="https://blog.date-fns.org/post/unicode-tokens-in-date-fns-v2-sreatyki91jg" rel="noopener noreferrer"&gt;You can read about that in a dedicated post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another standard that caused us to revisit naming schema was ISO 8601. Starting with &lt;code&gt;isWithinRange&lt;/code&gt; function we used the word "range" for time spans:&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;isWithinRange&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="s1"&gt;date-fns/is_within_range&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;isWithinRange&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2014&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// the date to check&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="mi"&gt;2014&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// start&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="mi"&gt;2014&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="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// end&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It turned out that ISO 8601:2004 defines term "interval":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;time interval: part of the time axis limited by two instants&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We adopted this terminology and made interval a separate entity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isWithinInterval&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;isWithinInterval&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2014&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2014&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2014&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="mi"&gt;7&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;It also made the code easier to read!&lt;/p&gt;

&lt;p&gt;When a string is passed to &lt;code&gt;new Date()&lt;/code&gt;, the JavaScript engine tries to do its best parsing it. In v1 we relied on the mechanism but then quickly learned that different browsers have different parsers and it leads to bugs that hard to find.&lt;/p&gt;

&lt;p&gt;Starting with v2, whenever a string represents a date it must be a valid ISO 8601 string overwise you'll get &lt;code&gt;Invalid Date&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you for reading! I hope this is interesting and fits DEV community. Feedback is welcome!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datefns</category>
    </item>
    <item>
      <title>I pay $1 every hour I spend working on open-source</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Thu, 06 Dec 2018 13:07:12 +0000</pubDate>
      <link>https://dev.to/kossnocorp/i-pay-1-every-hour-i-spend-working-on-open-source-27e7</link>
      <guid>https://dev.to/kossnocorp/i-pay-1-every-hour-i-spend-working-on-open-source-27e7</guid>
      <description>&lt;p&gt;Open source saves a shit ton of money for modern companies. It's used on every level starting with software that powers infrastructure and ending with the libraries that developers use to build the company products. Yet, maintaining an open-source project is undoubtedly the most underpaid job in our industry. I will be shocked if the average hourly rate is more than a dollar.&lt;/p&gt;

&lt;p&gt;It's certainly less for me. Actually, it's negative. I pay $1 for every hour I spend on &lt;a href="https://date-fns.org/"&gt;date-fns&lt;/a&gt;, a JavaScript library for working with dates that have 8M+ monthly downloads on npm. &lt;a href="https://opencollective.com/date-fns"&gt;Our estimated annual budget on Open Collective is $371&lt;/a&gt;. On average I work 20 hours per month and pay about $50/mo for the website hosting. I'm not even talking about my hourly rate and thousands of dollars I invested into the development so we can get on par with Moment.js functionality.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The average household spends an average of $3,008 per year on dining out, the Bureau of Labor Statistics reports&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If &lt;a href="https://www.cnbc.com/2017/09/27/how-much-americans-waste-on-dining-out.html"&gt;a family spends $3K on dining out&lt;/a&gt; then &lt;a href="https://www.usatoday.com/story/money/2017/06/22/tipping-etiquette-when-how-much/412098001/"&gt;given the average tip size 20%&lt;/a&gt;, an adult spends at least $300 on tips. Then why every developer doesn't spend $25 monthly on donations to open source teams or individuals? That should be minimal considering that the average developer salary is at least twice as big as the average income of an American household and we're using low-skilled labor as an example.&lt;/p&gt;

&lt;p&gt;Furthermore, if you'd try to calculate how much money companies save using open source, I won't be surprised if the number would overcome the total company funding. However, most companies suck on giving back to open source. Why's that? I think the problem is in developers again.&lt;/p&gt;

&lt;p&gt;Developers are notoriously bad at estimating practically everything, starting with hours they need for a feature and ending with the value they bring to the company. So no surprise they don't value the time of open source contributors as well. When an open source maintainer asks for money, they either ignore them or &lt;a href="https://twitter.com/ITBeHa/status/1041955686240985089"&gt;label them as beggars&lt;/a&gt; or &lt;a href="https://twitter.com/MartinLClifford/status/1066758300241281024"&gt;salesman&lt;/a&gt;. &lt;a href="https://github.com/moment/moment/issues/3979#issuecomment-304533266"&gt;Some developers that employers should fund open source&lt;/a&gt;, but they look at the problem from the point of view of a Microsoft employee. And as a result, they get things such as &lt;a href="https://github.com/dominictarr/event-stream/issues/116"&gt;event-stream&lt;/a&gt;. How many dramas do we need to start waking up?&lt;/p&gt;

&lt;p&gt;Developers are responsible for communicating the value they get from open source and convincing their managers to pay to open source they use. Managers won't realize it by themselves unless they use it as a marketing opportunity.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://opencollective.com/"&gt;Open Collective&lt;/a&gt;, their &lt;a href="https://backyourstack.com/"&gt;Back Your Stack&lt;/a&gt; and &lt;a href="http://patreon.com"&gt;Patreon&lt;/a&gt; it's easy as never to support the open source, so what do you waiting for?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Just go and donate to your favorite projects and maintainers and then bother your manager until they pay too. Let's make open source sustainable.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>What makes a company culture great?</title>
      <dc:creator>Sasha Koss</dc:creator>
      <pubDate>Tue, 27 Nov 2018 08:26:24 +0000</pubDate>
      <link>https://dev.to/kossnocorp/what-makes-a-company-culture-great-ndb</link>
      <guid>https://dev.to/kossnocorp/what-makes-a-company-culture-great-ndb</guid>
      <description>&lt;p&gt;Corporate culture plays a huge role in the success of businesses. No matter how cool is the product or how challenging is the problems, if the working environment is toxic, the employees will find another job. Business might try using financial motivation, but it's not a secret that is the worst kind of motivation for creative professions. The only way to attract and keep the top talent is providing a working environment that allows realizing themselves maintaining life-work balance.&lt;/p&gt;

&lt;p&gt;But what's that means? I've decided to find the answer to this question, so I've built &lt;a href="https://cultural.fit/" rel="noopener noreferrer"&gt;Cultural Fit&lt;/a&gt;. It's a collaborative list of corporate culture traits that people love or disapprove.&lt;/p&gt;

&lt;p&gt;I invite DEV community to help me find the answer: please vote for your favorite traits and downvote the ones you don't approve. Add missing traits and share your opinion here, in the post, or on the site:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cultural.fit/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mrgmxnzuhlif95llzdc.png" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've build this project for &lt;a href="https://www.producthunt.com/makers-festival-2018" rel="noopener noreferrer"&gt;Product Hunt Makers Festival 2018&lt;/a&gt;. This is universal Preact app. It's build using TypeScript on top of Firebase (Firestore, Firebase Hosting, Firebase Functions). &lt;/p&gt;

&lt;p&gt;Any kind of feedback is welcome!&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

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