<?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: Francesco Leardini</title>
    <description>The latest articles on DEV Community by Francesco Leardini (@paco_ita).</description>
    <link>https://dev.to/paco_ita</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%2F183068%2F9f59ae0e-2b1c-475c-ad6d-8db6ee5544d4.jpg</url>
      <title>DEV Community: Francesco Leardini</title>
      <link>https://dev.to/paco_ita</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paco_ita"/>
    <language>en</language>
    <item>
      <title>Pushing the Boundaries of Web Apps: Exploring Advanced Features and Hardware Integration</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Wed, 26 Jun 2024 08:54:28 +0000</pubDate>
      <link>https://dev.to/paco_ita/pushing-the-boundaries-of-web-apps-exploring-advanced-features-and-hardware-integration-d00</link>
      <guid>https://dev.to/paco_ita/pushing-the-boundaries-of-web-apps-exploring-advanced-features-and-hardware-integration-d00</guid>
      <description>&lt;p&gt;Today, web applications seamlessly integrate with external services, and can directly interact with a device's hardware to deliver dynamic, more advanced experiences. At the heart of this revolution lies a powerful tool: the Web Application Programming Interfaces, or Web APIs.&lt;/p&gt;

&lt;p&gt;There are plenty of APIs we can use in our web projects, some are well-established and supported by many browsers, while others are still in an experimental phase and supported only by a subset of browsers (typically Chrome and Edge).&lt;/p&gt;

&lt;p&gt;This article delves into a selection of web APIs, showcasing their diverse functionalities and the transformative impact they can have on web application development.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Device Orientation API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Smartphones, and other mobile devices, are equipped with built-in sensors that track their position in space. &lt;/p&gt;

&lt;p&gt;With the DeviceOrientationEvent we can detect when a user tilts or rotates the device and create features triggered by these patterns. When the device's accelerometer senses a change in orientation, this event fires, providing us with the data to react accordingly. &lt;/p&gt;

&lt;p&gt;There are three orientations we can listen to:&lt;/p&gt;

&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%2Fzcvjh6b0iymv5g5sdog1.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%2Fzcvjh6b0iymv5g5sdog1.png" alt="Planes Examples" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, the native app of Revolut allows you to toggle on/off the credit card details by moving the device forward and backward. Similarly, web applications can now explore alternative interaction methods beyond traditional UI elements, generating increased interest and engagement.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Page Visibility API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Designed to enhance web application responsiveness, the Page Visibility API equips developers with tools to track a page's visibility. It provides events for detecting visibility changes and properties for retrieving the current state, allowing for optimized resource management and user experience adjustments.&lt;/p&gt;

&lt;p&gt;While not the newest API, the Page Visibility API remains remarkably underutilized despite its potential to effortlessly optimize application resource usage.&lt;/p&gt;

&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%2Fia4fqnh1u79301lgatr2.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%2Fia4fqnh1u79301lgatr2.png" alt="play" width="800" height="753"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fx93o6jk77t3s9x8akcgu.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%2Fx93o6jk77t3s9x8akcgu.png" alt="pause" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the screenshots above the tab's title changes when the API detects that the content is not visible anymore (play/pause values are displayed accordingly).&lt;/p&gt;

&lt;p&gt;Imagine a scenario where a client continuously polls the server for fresh data. &lt;br&gt;
With the Page Visibility API, we can automatically pause these requests when the user minimizes the browser or switches tabs, resuming them only when the page regains focus. This is particularly valuable in situations demanding bandwidth and data transfer optimization or when we want to stop mandatory video advertisements when the tab is not in focus.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. Ambient Light (Sensors API)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The AmbientLightSensor interface empowers information the hosting device captures regarding the surrounding area's light level. The amount of light detected is provided in terms of &lt;em&gt;luminance&lt;/em&gt; value (an integer), and developers can implement any logic around this information. &lt;/p&gt;

&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%2Fbxae3znkjod8xn2rcmc4.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%2Fbxae3znkjod8xn2rcmc4.png" alt="AmbientLightImage" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can implement environmentally responsive web solutions, allowing applications to react to their surroundings. With the Ambient Light interface, we can design applications that adjust their user interface (UI) elements dynamically. It ensures a comfortable viewing experience for users in different lighting conditions, whether they're basking in bright sunlight or relaxing in a dimly lit room. &lt;/p&gt;

&lt;p&gt;Context-aware APIs have already been available for mobile apps for a long time, this is exactly what native apps like Google Maps offer, switching to dark mode while we drive through a gallery or use the app at night. But we can now provide this feature to our web users too.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pacoita.github.io/modern-web/home"&gt;Here is the live demo&lt;/a&gt; to some of the APIs described in the article and new ones. Each section covers a separate use case and can be tested with a mobile or desktop device (not all APIs are cross-compatible).&lt;/p&gt;

&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%2Fv0odq46ddyqdvlrabhe2.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%2Fv0odq46ddyqdvlrabhe2.png" alt="demo" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/pacoita/modern-web"&gt;Github repo&lt;/a&gt; (if you like it, leave a ⭐️ )&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While each Web API offers individual benefits, their combined potential is truly transformative. With careful design and creativity, web developers can craft web solutions that rival the functionality and user experience of native Android and iOS apps.&lt;/p&gt;

&lt;p&gt;To exemplify a personal experience, the native camera app on my Android phone lacks a self-shot feature. &lt;br&gt;
Instead of downloading a third-party solution, I built a web project using the Media Capture and Streams API to access the camera. Here's where I needed to inject some creativity: I combined the camera API with a predefined motion pattern from the Device Orientation API to trigger the camera shutter. By rotating the device forward and then backward a three-second timer is triggered before taking the shot. This allows for a more comfortable self-portrait experience compared to a traditional on-screen button press. &lt;br&gt;
Once captured, the Share API lets users seamlessly share the photo through their preferred native apps like WhatsApp, Gmail, or Twitter.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>api</category>
    </item>
    <item>
      <title>How Progressive Web Apps Can Benefit our Business</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Fri, 14 Jun 2024 10:43:38 +0000</pubDate>
      <link>https://dev.to/paco_ita/how-progressive-web-apps-can-benefit-our-business-4kni</link>
      <guid>https://dev.to/paco_ita/how-progressive-web-apps-can-benefit-our-business-4kni</guid>
      <description>&lt;p&gt;In an increasingly mobile-first world, optimizing the time to access our content and the user experience for our users can be the success of our business. &lt;br&gt;
However, native mobile apps can be expensive to develop, require downloads from app stores, and take up valuable storage space on phones.  This is where Progressive Web Apps (PWAs) shine - offering a powerful and user-friendly alternative.&lt;/p&gt;

&lt;p&gt;This article cuts through the technical jargon to focus on the big picture.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do you wish to learn all the secrets behind PWAs? &lt;br&gt;Check my &lt;a href="https://www.educative.io/courses/zero-to-hero-with-progressive-web-apps"&gt;PWA course&lt;/a&gt; teaching you in detail how to develop and optimize PWAs with ease.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What are Progressive Web Apps (PWAs)?
&lt;/h2&gt;

&lt;p&gt;A PWA is a web application that, thanks to modern technologies, can provide extended and rich features to users.&lt;/p&gt;

&lt;p&gt;Below is a screenshot of the Twitter/X native app for Android and its PWA version. Once a PWA is installed on a device, it is almost impossible to distinguish it from a native app. &lt;/p&gt;

&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%2Fw2bx0suwv1sj0et6qy2h.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%2Fw2bx0suwv1sj0et6qy2h.png" alt="native-pwa-comparison" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the goals of Progressive Web Apps is exactly to combine the accessibility and discoverability of a website with the functionality and user experience (UX) of a native app.  Our customers can access the PWA directly from their web browser, without any download required from an app store.&lt;/p&gt;

&lt;h2&gt;
  
  
  PWAs Core Parts
&lt;/h2&gt;

&lt;p&gt;Two key components can make PWAs installable and working offline: the &lt;strong&gt;web manifest&lt;/strong&gt; file and &lt;strong&gt;service workers&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Manifest
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A web manifest file can be seen as a blueprint for our PWA. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It instructs the browser agent that our PWA can be installed on the home screen, just like a native app. An &lt;em&gt;install banner&lt;/em&gt; (named A2HS - Add To Home Screen) is automatically displayed on the user's device. It also specifies essential visual details like the app's name, icon, and if we want to display the application in portrait (vertical) or landscape (horizontal) mode. The latter is the preferred option for media-rich content or web games.&lt;/p&gt;

&lt;p&gt;Thanks to the &lt;code&gt;display&lt;/code&gt; property of the manifest file we can instruct whether the browser's UI elements (e.g. URL address bar) should be rendered or less. &lt;br&gt;&lt;/p&gt;

&lt;p&gt;Three main values are possible (in the pictures below from left to right respectively): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;browser&lt;/em&gt; (default mobile experience)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;standalone&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;fullscreen&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&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%2Fgfa0fmons2r2rxn8qp9u.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%2Fgfa0fmons2r2rxn8qp9u.png" alt="display property example" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, with these properties it is possible to remove some UI elements of the browser or even use the whole device's viewport. All these aspects help to create a familiar and app-like feel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Workers
&lt;/h3&gt;

&lt;p&gt;Let's delve into the engine that powers offline functionality and allows for drastic performance improvements – service workers (SW). These are essentially scripts that run in the background, separate from your PWA's main thread, and can offload our application from heavy tasks. &lt;br&gt;&lt;/p&gt;

&lt;p&gt;They act as intermediaries between the app and the network, offering several advantages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching:&lt;/strong&gt; Service workers can intelligently cache essential static resources like HTML pages, JS or CSS files, and HTTP responses as well. This means that when a user visits our PWA, even without an internet connection, the cached resources can be used to deliver a functional, albeit potentially limited, experience. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Performance:&lt;/strong&gt; This aspect relates tightly to the previous point. Responses from the local cache are provided almost instantaneously since no network roundtrip is needed. We can implement multiple caching strategies to cover wide scenarios and ensure that, if needed, the provided cached data is not stale but in an up-to-date state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push Notifications:&lt;/strong&gt; SW enables push notifications, a powerful tool for keeping users engaged. Web notifications were for a long time precluded to iOS devices, but since v16.4 are now available for Apple users as well). &lt;br&gt;
Even when the PWA is not actively running, service workers can receive and display notifications, prompting users to revisit your app. This is possible because Service workers run in the background and, therefore do not require the user to be actively on the PWA to perform actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background Syncing:&lt;/strong&gt; This web API allows to register actions (sync tags) that, in case the user does not have a valid internet connection, will be kept &lt;em&gt;on hold&lt;/em&gt; for later execution.&lt;br&gt;
Once the user regains internet connectivity, service workers are notified by the API and seamlessly synchronize any offline actions taken within the PWA. &lt;br&gt; Imagine we are building an e-commerce website where users can add items to their cart and submit orders. A user adds items to their cart and proceeds to checkout. While filling out the order form, the user's internet connection drops (maybe because of commuting from/to work). Without Background Sync API, the user would lose their order progress, leading to frustration and a new order for our company. This combination of web APIs and service workers ensures data consistency and a smooth user experience in these scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Native Apps
&lt;/h2&gt;

&lt;p&gt;PWAs offer a multitude of advantages over traditional mobile apps, making them a compelling option for businesses of all sizes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduced Development Costs&lt;/strong&gt;: PWAs leverage existing web development technologies, making them significantly cheaper and faster to develop than native apps. There is no need to have dedicated developer teams to create iOS or Android apps. This translates into substantial cost savings for your business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduced Time To Market&lt;/strong&gt;: PWAs bypass the app store approval process, avoiding potential delays in the release date due to the restrictions or controls imposed by app stores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extended Functionalities&lt;/strong&gt;: Thanks to Web APIs, all web apps, PWAs included, can benefit from new and modern features out of the box. For instance, we can interact with the hardware of the hosting mobile phone to detect the amount of light in the surroundings. This allows the development of smart capabilities and switching automatically from a light to a dark theme if the user is in a room with insufficient light. The native app Google Maps has the same behavior, switching to the dark mode when we cross a tunnel while driving, for instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Conversion Rates&lt;/strong&gt;: By providing a seamless, app-like experience, PWAs can significantly improve conversion rates, leading to more sales and increased revenue for your business. The website &lt;a href="https://www.pwastats.com/"&gt;PWA Stats&lt;/a&gt; collects several success stories of companies that adopted PWAs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search Engine Optimization (SEO) Friendly&lt;/strong&gt;: PWAs are indexed by search engines like websites, making it easier for potential customers to discover our business online.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy to Maintain&lt;/strong&gt;: Updates to PWAs happen automatically in the background, ensuring users always have access to the latest features and bug fixes without the need to download a new patched version. Differently from a native app, PWAs have only one version live to be maintained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small Memory Footprint&lt;/strong&gt;: PWAs do not come with 3rd party libraries as native apps and, therefore require much less space on the hosting device. This can be a crucial aspect for our business if a portion of our user base does not have modern devices or the cost for mobile data is significantly high in their country. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, opting for a progressive web app over a native app can represent a strategic advantage for our business. &lt;br&gt;&lt;br&gt;
PWAs offer a user experience that rivals native apps, reaching a wider audience without the burden of individual app store downloads for a fraction of the development costs. This streamlined approach translates to broader customer accessibility and increased engagement, ultimately driving growth for our company.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>pwa</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Add logic to run *before* current Material Tab changes</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Mon, 23 Aug 2021 14:56:28 +0000</pubDate>
      <link>https://dev.to/paco_ita/add-logic-to-run-before-current-material-tab-changes-kif</link>
      <guid>https://dev.to/paco_ita/add-logic-to-run-before-current-material-tab-changes-kif</guid>
      <description>&lt;p&gt;&lt;a href="https://material.angular.io/components/categories" rel="noopener noreferrer"&gt;Angular Material&lt;/a&gt; offers a wide, feature-rich set of UI Components that we can easily introduce in our projects. &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%2Fuploads%2Farticles%2Fkov7h5j5e13m8i5vps2a.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%2Fuploads%2Farticles%2Fkov7h5j5e13m8i5vps2a.PNG" alt="Angular Material Gallery"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although the proposed functionalities already cover many common scenarios, it can be that we need to implement a special requirement in our current project.&lt;/p&gt;

&lt;p&gt;In my last project I needed to store in a NgRx UI State the vertical scroll position of the content of Angular Material Tabs. The client wanted to restore the last scroll position of each tab, while navigating among them.&lt;/p&gt;

&lt;p&gt;There are multiple approaches to fulfill this requirement, but I wanted to avoid costly event listeners that get triggered multiple times while scrolling through the page.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All I wanted, was the possibility to target the scrolling element  in the template and register its position just &lt;em&gt;before&lt;/em&gt; navigating to the next tab, at the end of the interaction with the current tab.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
This functionality can also be useful in other situations. Let's imagine the case where we want to prevent switching to a different tab if a form is not in a valid state, for instance.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;MatTabGroup&lt;/code&gt; object provides a public event that gets triggered when a new Tab is selected:&lt;/p&gt;

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

@Output()
selectedTabChange: EventEmitter&amp;lt;MatTabChangeEvent&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;The problem is that it gets triggered &lt;em&gt;too late&lt;/em&gt; for our needs. We want to be able to detect the content's state of the current tab &lt;em&gt;before&lt;/em&gt; navigating to a different one.&lt;/p&gt;

&lt;p&gt;Luckily we can use a private event handler &lt;code&gt;_handleClick&lt;/code&gt; from the &lt;code&gt;_MatTabGroupBase&lt;/code&gt; abstract class to intercept a Tab click and then apply our logic accordingly:&lt;/p&gt;

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

/** Handle click events, setting new selected index if appropriate. */
_handleClick(tab: MatTab, tabHeader: MatTabGroupBaseHeader, index: number): void;


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

&lt;/div&gt;




&lt;p&gt;To describe the solution, we start from the template, where we simply define the material tab component:&lt;/p&gt;

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

&amp;lt;mat-tab-group mat-align-tabs="start"&amp;gt;
  &amp;lt;mat-tab label="First"&amp;gt;Content first tab&amp;lt;/mat-tab&amp;gt;
  &amp;lt;mat-tab label="Second"&amp;gt;Content second tab&amp;lt;/mat-tab&amp;gt;
  &amp;lt;mat-tab label="Third"&amp;gt;Content third tab&amp;lt;/mat-tab&amp;gt;
&amp;lt;/mat-tab-group&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;All the logic happens on the component side:&lt;/p&gt;

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

import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ViewChild,
} from '@angular/core';
import { MatTabChangeEvent, MatTabGroup } from '@angular/material/tabs';
@Component({
  selector: 'app-component',
  templateUrl: './app-component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements AfterViewInit {

// Get a reference of the MatTabGroup form the template
@ViewChild(MatTabGroup)
tabs?: MatTabGroup;

private currentTabIndex = 0;

ngAfterViewInit() {
  this.registerTabClick();
}

registerTabClick(): void {
  // Get the handler reference
  const handleTabClick = this.tabs._handleClick;

  this.tabs._handleClick = (tab, header, index) =&amp;gt; {  
    // Get tab content reference for the current Tab -&amp;gt; currentTabIndex
    // since index here is already the "new" tab index
    const tabContent = this.getTabContentElement(this.currentTabIndex);

    const scrollPosition = Math.round(tabContent.scrollTop) || 0;

    this.store.dispatch(
       setTabScrollPosition({
         scrollPosition: scrollPosition,
         // ... other props
       })
    );

   // If you want to prevent the user to navigate to the new tab,
   // you can avoid invoking the 'apply' method below 
   handleTabClick.apply(this.tabs, [tab, header, index]);

   // We update the currentIndex, as we need it again when
   // another tab is clicked
   this.currentTabIndex = index;
  };
}

 // Returns the &amp;lt;mat-tab-body-content&amp;gt; with the tab content scroll 
 position given the target tab index
 private getTabContentElement(tabIndex: number) {
   return document.getElementsByClassName('mat-tab-body-content')[tabIndex];
 }
}


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

&lt;/div&gt;

&lt;p&gt;The code above is pretty straightforward. When the user clicks on a new tab, the code inside &lt;code&gt;this.tabs._handleClick&lt;/code&gt; is invoked and this gives us the possibility to handle the current state according to our needs.&lt;/p&gt;

&lt;p&gt;Even if probably &lt;code&gt;selectedTabChange&lt;/code&gt; will cover all your needs, it is still useful to know that we have further possibilities to cover also edge cases. &lt;/p&gt;

&lt;p&gt;Do you know even more customizations or other special cases you needed to face? If so, feel free to add your experience in the comments below!!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ux</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Avoid These Terrible Web Notifications Mistakes! 🤦‍♂💥</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Wed, 03 Feb 2021 09:18:47 +0000</pubDate>
      <link>https://dev.to/paco_ita/avoid-these-terrible-web-notifications-rules-1n82</link>
      <guid>https://dev.to/paco_ita/avoid-these-terrible-web-notifications-rules-1n82</guid>
      <description>&lt;p&gt;This article is a brief introduction to some best practices about web notifications and some typical mistakes we should avoid. &lt;/p&gt;

&lt;p&gt;We have several instruments to measure users engagement, such as downloads or clicks. Highly engaged users tend to be more profitable as typically they conclude purchases and share the website content within their network.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we consider push notifications, engagement can be measured as the average number of sessions the recipients generated by receiving the message within a defined period of time. &lt;/p&gt;
&lt;/blockquote&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%2Fmyslu3jc5phbzcpcsf80.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%2Fmyslu3jc5phbzcpcsf80.PNG" alt="engagement"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Push notifications are a powerful channel to keep an interactive contact with our users and reach out to them even when they aren't visiting our web site.&lt;/p&gt;

&lt;p&gt;Commercial newsletters allow for fake user data (do you always provide your real information in any newsletter? 😄).&lt;br&gt;
Conversely, it is not possible to falsify credentials with web notifications, but they can be a double-edged sword.&lt;/p&gt;

&lt;p&gt;We can build an amazing web app but if we do not use notifications properly, we flood the users with irrelevant information. Either they will be annoyed or the message we wanted to send across will be swallowed by too much information.&lt;br&gt;
 &lt;/p&gt;

&lt;h1&gt;
  
  
  The benefits of push notifications
&lt;/h1&gt;

&lt;p&gt;Push notifications can bring benefits to different business fields.&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%2Fyl132dobm4jktlikgaaz.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%2Fyl132dobm4jktlikgaaz.png" alt="push-benefits"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  E-commerce: a practical case
&lt;/h2&gt;

&lt;p&gt;Let's take a common scenario. A potential customer browses among our e-shop articles and puts one item in the cart for the purchase. However at the very last checkout step additional costs - shippings costs, gift options, express delivery - might pile on top of the original price. At this point the customer second-guesses his/her choices and aborts the purchase.&lt;br&gt;&lt;br&gt;
 A study by &lt;a href="https://hostingfacts.com/internet-facts-stats/" rel="noopener noreferrer"&gt;hosting facts&lt;/a&gt; says that 66 percent of shoppers have decided not to buy an item they were considering buying due to shipping costs.&lt;/p&gt;

&lt;p&gt;We can track these "abandoned" items left in the shopping cart. At a certain point our marketing department might decide to launch a new sales campaign. This would be the perfect time to send a message to all those users who left some articles in the cart. If those objects are now 30% - 40% cheaper, it is more likely that the user is going to conclude the purchase this time.&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%2Fw4owuzdw38qxz582dwrz.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%2Fw4owuzdw38qxz582dwrz.png" alt="usefuls_notification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just one possible example, but there are many more opportunities: shopping websites can send an email when a piece of clothing that was out of stock is available again or when a parcel has been handed over to the shipping courier.&lt;br&gt;
 &lt;/p&gt;

&lt;h1&gt;
  
  
  Common mistakes to avoid
&lt;/h1&gt;

&lt;p&gt;As we mentioned earlier, the misuse of web notifications results into a negative user experience.&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%2Fvp2mu3pe6106tjbhs7g5.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%2Fvp2mu3pe6106tjbhs7g5.PNG" alt="push-spam"&gt;&lt;/a&gt; &lt;/p&gt;
source: https://vwo.com/ebooks/push-notifications-report-2018



&lt;p&gt; &lt;/p&gt;

&lt;p&gt;What can go wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Wrong timing&lt;/strong&gt;. You should be able to collect geographical details to segment the audience according to their location. This allows for so called &lt;em&gt;geo-push&lt;/em&gt; notifications. If you want to inform that your latest tech article has been published, probably the best time to reach your readers is between 6am and 9am when many people are commuting to work. In order to do this, the server push logic needs to take into account the recipients time zone.&lt;br&gt;
 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Impersonal data&lt;/strong&gt;. Provide information tailored to the recipient, addressing him/her by name or references to previous interactions. For this reason we should always record the transactions with our users in order to create a detailed context allowing for a more precise customers segmentation.&lt;br&gt;
 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unclear actions&lt;/strong&gt;. The context and interaction option of a notification have to be immediately clear and accessible. In the example below, the type of notification and the actions that can be taken are easily identified:&lt;br&gt;
 &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%2Fix5pzmu6bsrw0krhlw3h.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%2Fix5pzmu6bsrw0krhlw3h.PNG" alt="push_action"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too many&lt;/strong&gt;. Even if we can provide information of interest for our recipients, we should carefully evaluate the frequency of a notification. Otherwise our messages will be simply perceived as annoying spam.&lt;br&gt;
 &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%2Fmbf5z8s9e7gt71ljrxoq.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%2Fmbf5z8s9e7gt71ljrxoq.png" alt="too_many"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these concepts in mind, you should be ready to plan your notifications strategy with the most effective impact on your target users.&lt;/p&gt;

&lt;p&gt;Do you have any further methods or measures you adopt in your web notifications strategy? Share them with us in the comment below!&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Enhance your web apps with a vibration!!</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Wed, 16 Dec 2020 14:06:55 +0000</pubDate>
      <link>https://dev.to/paco_ita/enhance-your-web-apps-with-a-vibration-43pl</link>
      <guid>https://dev.to/paco_ita/enhance-your-web-apps-with-a-vibration-43pl</guid>
      <description>&lt;p&gt;Nowadays we are used to receive a tactile feedback when we receive a text message or when we play a game on our phone. &lt;/p&gt;

&lt;p&gt;Until now, native apps had the advantage of providing a deep experience to the users, being able to tightly interact with the hosting hardware.&lt;/p&gt;

&lt;p&gt;However, thanks to the &lt;strong&gt;Vibration API&lt;/strong&gt; we can enrich our web apps with a new functionality and let a device vibrate through our browser!&lt;br&gt;
It's a further step to close the feature gap with native applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Vibration API simply won't do anything if the hosting device doesn't support it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This goes along with the &lt;em&gt;progressive enhancement&lt;/em&gt; strategy. That is, if the user has a modern browser and a device capable of vibrating, then we can offer a richer experience. On the other side, our web app must keep working correctly for all other users even without advanced features.&lt;/p&gt;
&lt;h2&gt;
  
  
  API Syntax
&lt;/h2&gt;

&lt;p&gt;We use the &lt;code&gt;navigator.vibrate&lt;/code&gt; to define a &lt;em&gt;pattern&lt;/em&gt;, made of a single vibration or a sequence of vibrations and pauses. The method accepts as parameter an integer or an array of integers, expressing the length in milliseconds of a vibration or sequences of vibrations and pauses, respectively.  The return value type is &lt;code&gt;boolean&lt;/code&gt;: &lt;em&gt;false&lt;/em&gt; in case we pass wrong parameters, &lt;em&gt;true&lt;/em&gt; otherwise.&lt;/p&gt;

&lt;p&gt;As mentioned previously, if the device doesn't support vibration, this method won't have any effect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var success = window.navigator.vibrate(pattern);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;pattern&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Provides a pattern of vibration and pause intervals. Each value indicates a number of milliseconds to vibrate or pause, in alternation. You may provide either a single value (to vibrate once for that many milliseconds) or an array of values to alternately vibrate, pause, then vibrate again. (&lt;em&gt;Source: MDN Web&lt;/em&gt;)&lt;br&gt;
The method returns a boolean if we pass wrong parameters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To generate a single vibration lasting 300ms we can use the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.navigator.vibrate(300);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While to create a pattern composed by 300ms vibration, 100ms pause, 300ms vibration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.navigator.vibrate([300, 100, 300]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cancel a running vibration
&lt;/h2&gt;

&lt;p&gt;It is possible to interrupt a running vibration any time by passing a value of 0 or an empty array to the &lt;code&gt;navigator.vibrate()&lt;/code&gt; method.&lt;br&gt;
Similarly, if we pass a new valid pattern as parameter, while a vibration is going on, this will replace the old, running pattern.&lt;/p&gt;




&lt;p&gt;Follow me on Twitter if you want to know about new articles or future updates &lt;a href="https://twitter.com/paco_ITA" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607094167287%2F6eROzoiWz.png" alt="Twitter-Logo-2010–2012.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;p&gt;We can think of different scenarios where this API might come handy. Probably the most intuitive one is for web games, where we can provide a further grade of engagement to the users.&lt;/p&gt;

&lt;p&gt;It can be useful also for web quizzes to underline a wrong answer or to give a tactile feedback for errors while filling a form. The latter case can be particularly useful with long forms on mobile devices, since the displayed keyboard could cover some error messages or invalid form fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser support
&lt;/h2&gt;

&lt;p&gt;The API is well supported by most (modern) browsers, with the exception of IE and Safari.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607090902022%2FNV-qg2mbE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1607090902022%2FNV-qg2mbE.png" alt="Screenshot 2020-12-04 at 15.08.04.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, the target device must also have a vibration hardware in order to work correctly!&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;You can test the API on your phone with the following  &lt;a href="https://pacoita.github.io/vibration_api_demo/home" rel="noopener noreferrer"&gt;DEMO&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here the &lt;a href="https://github.com/pacoita/vibration_api_demo" rel="noopener noreferrer"&gt;Github REPO&lt;/a&gt;  with the source code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Vibration API is another interesting possibility to enrich our web projects and offer an improved experience to our users that, until now, was reserved only to native applications.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Create an Angular Rest API Mock with Deno</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Tue, 09 Jun 2020 07:52:51 +0000</pubDate>
      <link>https://dev.to/paco_ita/create-an-angular-rest-api-mock-with-deno-598b</link>
      <guid>https://dev.to/paco_ita/create-an-angular-rest-api-mock-with-deno-598b</guid>
      <description>&lt;p&gt;In one of our Angular courses we are currently using a Node Express server to provide mock data to an Angular application.&lt;/p&gt;

&lt;p&gt;As Deno has been released with the official version 1.0 (mid May 2020), I decided to experiment it and write a new web server for the course. The final layout looks like the screenshot below (as you can see nothing fancy from the layout perspective):&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%2F7lxybbz4tj6o0ax1w9ox.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%2F7lxybbz4tj6o0ax1w9ox.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is a step-by-step, practical guide focused on creating a Rest API, with full CRUD actions, for an Angular application. I will not cover too many details about Deno though, as it would make the post way too long, and there are already plenty of good introductions to Deno already. &lt;br&gt; Below are the topics that we will cover, feel free to follow along or jump directly to the topic of interest if you prefer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deno:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Deno&lt;/li&gt;
&lt;li&gt;Install Deno&lt;/li&gt;
&lt;li&gt;Create a server&lt;/li&gt;
&lt;li&gt;Start the server&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Angular:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an Angular service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Repo&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Github Repo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  What is Deno &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://deno.land" rel="noopener noreferrer"&gt;Deno&lt;/a&gt; has been created by Ryan Dahl, the same creator of Node.js.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are already familiar with Node, then Deno is able to do exactly the same things, but faster.&lt;/p&gt;

&lt;p&gt;Deno can be seen as a way to &lt;em&gt;rewamp&lt;/em&gt; Node.js, solving  different aspects that the same Ryan considered his "regrets". &lt;br&gt; Below is his talk at the JSConf EU 2018, where he exposes these points:&lt;/p&gt;

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

&lt;h1&gt;
  
  
  Install Deno &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;We can choose to use a package manager or execute directly a command in the shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install via command
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;With Shell (Mac):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://deno.land/x/install/install.sh | sh


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;With PowerShell (Windows):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;iwr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://deno.land/x/install/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-useb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Install via Package Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;With &lt;a href="https://formulae.brew.sh/formula/deno" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; (Mac):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;deno


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;With &lt;a href="https://chocolatey.org/packages/deno" rel="noopener noreferrer"&gt;Chocolatey&lt;/a&gt; (Windows):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;choco&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;deno&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;After Deno is downloaded and setup locally, run &lt;code&gt;deno --version&lt;/code&gt; in the shell to verify the installation. We should get a similar output:&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;deno &lt;span class="nt"&gt;--version&lt;/span&gt;
deno 1.0.3
v8 8.4.300
typescript 3.9.2


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

&lt;/div&gt;

&lt;p&gt; &lt;br&gt;
If we want an overview about the available commands, we can invoke the instruction &lt;code&gt;deno --help&lt;/code&gt;, showing all the available sub-commands. &lt;br&gt; We can even get further details for each single command simply appending the &lt;code&gt;--help&lt;/code&gt; flag, like: &lt;code&gt;deno run --help&lt;/code&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%2F2gp4uh5si8elx5hltxia.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%2F2gp4uh5si8elx5hltxia.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Available modules
&lt;/h4&gt;

&lt;p&gt;Deno provides a list of &lt;strong&gt;standard modules&lt;/strong&gt;, reviewed by the core team and guaranteed to work with the specific Deno version. These standard modules are hosted at &lt;a href="https://deno.land/std" rel="noopener noreferrer"&gt;https://deno.land/std&lt;/a&gt; and provide functionalities for most of the basic tasks like: uuid generation, http calls and file system access, for instance.&lt;/p&gt;

&lt;p&gt;Aside these, deno.land website also provides a public hosting service for &lt;strong&gt;third party modules&lt;/strong&gt; that are compatible with Deno at &lt;a href="//deno.land/x"&gt;deno.land/x&lt;/a&gt;. &lt;br&gt;We can search among an exhaustive collection of modules.&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%2Fw1r66nqkkzfweys440ht.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%2Fw1r66nqkkzfweys440ht.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Server
&lt;/h1&gt;

&lt;p&gt;Now that everything is in place, let's start writing some code. Define a root folder for your server:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;mkdir &lt;/span&gt;webServer &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;webServer 


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Server.ts &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;server.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; we can use plain JavaScript instead of typescript, but we would lose many of the benefits that typescript offers. Moreover, being Deno written on top of Rust and Typescript, it compiles directly .ts files for us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Use the standard http module
&lt;/h4&gt;

&lt;p&gt;To create an HTTP server we could import the &lt;code&gt;server.ts&lt;/code&gt; file from the &lt;code&gt;http&lt;/code&gt; standard module:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;serve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std@0.125.0/http/server.ts&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;server_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;req_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;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="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Received a request...&lt;/span&gt;&lt;span class="se"&gt;\n&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I am a DENO server 🦕&lt;/span&gt;&lt;span class="dl"&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;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;content-type&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;application/json; charset=utf-8&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="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req_handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;server_port&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;Listening on PORT: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;server_port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; you might have noticed that we import from a url here rather than from a local path. &lt;br&gt;This is a new concept in Deno, we don't need to have the  packages already installed locally. We can import their latest version and cache it, making it available even while offline. Deno uses ES Modules to import packages, where from Node uses npm. This translates in the absence of the &lt;code&gt;node_modules&lt;/code&gt; folder and  &lt;code&gt;package.json&lt;/code&gt; file (we don't have any trace of them in our webServer folder). With Deno we directly import the packages we want through its url.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Use third party module
&lt;/h4&gt;

&lt;p&gt;Alternatively we can opt for &lt;a href="https://deno.land/x/oak" rel="noopener noreferrer"&gt;&lt;code&gt;oak&lt;/code&gt;&lt;/a&gt;, a middleware framework for Deno's http server, including a router middleware. This middleware framework is inspired by Koa, therefore already familiar to many Node.js developers. For our mock server I decided to use oak.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/x/oak/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;oakCors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/x/cors/mod.ts&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;router&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;./src/routes.ts&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8280&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;app&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;Application&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;oakCors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allowedMethods&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;listen&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;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secure&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="s2"&gt;`--- Listening on: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secure&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://&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;http://&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;
        &lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&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;port&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;br&gt;
If you already used Express the code above should be already very familiar. After creating an instance of the &lt;code&gt;Application&lt;/code&gt; class, we can stack multiple middleware using the &lt;code&gt;use()&lt;/code&gt; method and then activate the server (&lt;code&gt;listen()&lt;/code&gt; method), waiting for incoming requests.&lt;/p&gt;

&lt;h4&gt;
  
  
  CORS
&lt;/h4&gt;

&lt;p&gt;We can define CORS for our application otherwise we would get a client-side error every time we try to reach our server from the Angular app. Deno provides a cors module (&lt;code&gt;https://deno.land/x/cors/mod.ts&lt;/code&gt;) with default settings that already capture many common cases. We can enable CORS with the following call: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;oakCors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The default configuration, hence without parameters like in the snippet above, translates in the following set of options:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET,HEAD,PUT,PATCH,POST,DELETE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"preflightContinue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"optionsSuccessStatus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;204&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Routes.ts
&lt;/h3&gt;

&lt;p&gt;As our mock server is pretty simple, I decided to create just a folder &lt;code&gt;src&lt;/code&gt; to host all the business logic and keep it separated from the &lt;code&gt;server.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The routes file contains all the endpoints that we want to expose to the Angular client and in our case implement the classic CRUD operations. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/x/oak/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;getAllEmployees&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getEmployeeById&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateEmployee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addEmployee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteEmployee&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./employeeApis.ts&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;router&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;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;router&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;/employees&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getAllEmployees&lt;/span&gt;&lt;span class="p"&gt;)&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;/employees/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getEmployeeById&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/employees/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateEmployee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/employees&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addEmployee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/employees/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteEmployee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Employee.ts
&lt;/h3&gt;

&lt;p&gt;We need to define a generic model for our domain. Here we design an &lt;code&gt;Employee&lt;/code&gt; object with some static data and no database storage, as it would be beyond the course scope, focusing on Angular and client side development only.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Larry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Potter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;larry.potter@hotmail.com&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;id&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="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mara&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Croft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mara.croft@gmail.com&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;id&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="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Thomas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Müller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thomas123@gmail.com&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Karl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fritz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Karl_great@microsoft.com&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;id&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="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Paolo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rossi&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; &lt;/p&gt;

&lt;h3&gt;
  
  
  EmployeeApis.ts
&lt;/h3&gt;

&lt;p&gt;In this file we implement the real logic behind each endpoint. Any data mutation will affect the local data structure &lt;em&gt;EmployeeData&lt;/em&gt;, seen above. &lt;br&gt; The code is very simple and self-explanatory therefore I won't go in detail about it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Employee&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;./employee.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;// Returns all available employees&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAllEmployees&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Returns one employee by its Id or 404 if not found&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getEmployeeById&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;selectedEmployee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedEmployee&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selectedEmployee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&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;404&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Add a new employee to the list&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;request&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasBody&lt;/span&gt;&lt;span class="p"&gt;)&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;400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;newEmployee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;newEmployee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getNextEmployeeId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newEmployee&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;201&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//Provides the next number to be used as employee Id&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getNextEmployeeId&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&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;maxId&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="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&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;maxId&lt;/span&gt; &lt;span class="o"&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;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxId&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="nx"&gt;maxId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Removes an employee by its Id or 404 if not found&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;params&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newEmployeeList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;targetId&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;newEmployeeList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;replaceCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newEmployeeList&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;else&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;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Updates en existing employee&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="nl"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;employeeToUpdate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;targetId&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;employeeToUpdate&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;newEmployeeData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;updatedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;newEmployeeData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nf"&gt;replaceCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EmployeeData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatedData&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;else&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;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Replaces the employee data structure with a new collection&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;replaceCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;originalData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&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;originalData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;originalData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Start the server &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we created all the needed files, it is time to start the server. Execute the following command in the shell from the path hosting your server file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

deno  run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; server.ts


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; if you didn't add the Deno install root ($HOME/.deno/bin) to your environment variables, then you have to prepend the file path to server.ts&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;br&gt;
By running the command, different modules are downloaded, but no folder inside our solution is created for them. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Compile file:///.../server.ts
Download https://deno.land/x/oak/mod.ts
Download https://deno.land/x/oak/application.ts
Download https://deno.land/x/oak/context.ts
Download https://deno.land/x/oak/cookies.ts
Download https://deno.land/x/oak/httpError.ts
Download https://deno.land/x/oak/middleware.ts
Download https://deno.land/x/oak/request.ts
Download https://deno.land/x/oak/response.ts
Download https://deno.land/x/oak/router.ts
Download https://deno.land/x/oak/send.ts
Download https://deno.land/x/oak/types.ts
Download https://deno.land/x/oak/deps.ts
Download https://deno.land/x/oak/keyStack.ts
Download https://deno.land/x/oak/tssCompare.ts
Download https://deno.land/std@v1.0.0-rc1/http/server.ts
...


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

&lt;/div&gt;

&lt;p&gt;These modules are cached from now on and we do not need to download them again, unless we explicitly want to, using the &lt;code&gt;--reload&lt;/code&gt; option, for instance. By default, the cached modules are stored in Deno's base directory: $HOME/.deno (DENO_DIR), but we can change this location if we need, typically in the case of a production environment.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DENO_DIR&lt;/code&gt; contains the following files and directories:&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%2Fr6qlhbazqxdu4bdc6xwq.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%2Fr6qlhbazqxdu4bdc6xwq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; in Deno, you need to give explicit permissions before running a program. In the command above we had to grant network access with the option: &lt;code&gt;--allow-net&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we omit this option, we get the following error after downloading all the modules:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

error: Uncaught PermissionDenied: network access to &lt;span class="s2"&gt;"127.0.0.1:8280"&lt;/span&gt;, run again with the &lt;span class="nt"&gt;--allow-net&lt;/span&gt; flag
    at unwrapResponse &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$deno$/&lt;/span&gt;ops/dispatch_json.ts:43:11&lt;span class="o"&gt;)&lt;/span&gt;
    at Object.sendSync &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$deno$/&lt;/span&gt;ops/dispatch_json.ts:72:10&lt;span class="o"&gt;)&lt;/span&gt;
    at Object.listen &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$deno$/&lt;/span&gt;ops/net.ts:51:10&lt;span class="o"&gt;)&lt;/span&gt;
    at listen &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$deno$/&lt;/span&gt;net.ts:164:18&lt;span class="o"&gt;)&lt;/span&gt;
    at Application.serve &lt;span class="o"&gt;(&lt;/span&gt;server.ts:261:20&lt;span class="o"&gt;)&lt;/span&gt;
    at Application.listen &lt;span class="o"&gt;(&lt;/span&gt;application.ts:106:31&lt;span class="o"&gt;)&lt;/span&gt;
    at server.ts:18:11


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

&lt;/div&gt;

&lt;p&gt;And that was all we need to create a simple http server to use as a mock for our client application. Let's create now an Angular project that uses our REST APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Deno supports V8 Inspector Protocol. We can debug Deno programs with Chrome DevTools or other clients that support the protocol.&lt;/p&gt;

&lt;p&gt;As most probably we are using Visual Code to implement our Angular application, let's see how we can debug the Deno server directly from our IDE. An official plugin is currently under construction, but for the time being we can create a &lt;code&gt;launch.json&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deno"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"runtimeExecutable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deno"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"runtimeArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--inspect-brk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server.ts"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9229&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; if you named your script file differently than &lt;code&gt;server.ts&lt;/code&gt; you have to adapt the last item of "runtimeArgs"  accordingly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the configuration above, VS Code debugger will run at: &lt;code&gt;127.0.0.1:9229&lt;/code&gt; and intercept all the breakpoints we set.&lt;/p&gt;

&lt;h3&gt;
  
  
  More about Deno
&lt;/h3&gt;

&lt;p&gt;If you are interested in knowing more about Deno, I recommend the official &lt;a href="https://deno.land/v1" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; about the v 1.0 release.&lt;/p&gt;

&lt;p&gt;Keep also an eye on the &lt;a href="https://droces.github.io/Deno-Cheat-Sheet/" rel="noopener noreferrer"&gt;Deno Cheat Sheet&lt;/a&gt; as it is a great resource to have always an overview about all available commands.&lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Create an Angular service&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;For the Angular part, I will describe only the http service calling our REST server. All the code is available on the &lt;a href="https://github.com/pacoita/deno-api-mock" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; anyway and you can download the whole project.&lt;/p&gt;

&lt;p&gt;If you don't have already an existing Angular application and you need instructions on how to create one, have a look at my post &lt;a href="https://dev.to/paco_ita/create-progressive-web-apps-with-angular-workbox-pwa-builder-step-4-27d#angular"&gt;about it&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  EmployeeService.ts
&lt;/h3&gt;

&lt;p&gt;Thanks to schematics, generate files in Angular is very easy:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

ng g service employee


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

&lt;/div&gt;

&lt;p&gt; &lt;br&gt;
This command creates the &lt;code&gt;EmployeeService.ts&lt;/code&gt; and its unit test file. In the service, we define the methods implementing the CRUD operations and that will call the endpoints of the Deno server that we implemented before. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Employee&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;./../model/employee.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&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;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&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;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="nx"&gt;throwError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;_throw&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&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;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;environment&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;../../../environments/environment&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;getEmployees&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&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="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/employees`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;_throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="nf"&gt;getEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/employees/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;_throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;createEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/employees`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;_throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;updateEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/employees/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;_throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;removeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/employees/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;_throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

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



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

&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Environment.ts
&lt;/h3&gt;

&lt;p&gt;In the file &lt;code&gt;environment.ts&lt;/code&gt; we can save the base url for the server and eventually other configuration keys. &lt;code&gt;environment.prod.ts&lt;/code&gt;, reserved for prod builds, typically has keys with different values, to target the production server instead of the staging one.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiBaseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8280&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; &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As we saw, it is very easy to create a web server with Deno and use it as a mock for our client application.&lt;/p&gt;

&lt;p&gt;This architecture is very convenient because it allows to decouple our web app from the server mocks. We can execute real network calls from our client without need to apply any change to our Angular app before deploying it to production.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Github Repo &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The sample code (Angular and Deno server) is available on Github: &lt;a href="https://github.com/pacoita/deno-api-mock" rel="noopener noreferrer"&gt;https://github.com/pacoita/deno-api-mock&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>deno</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Be more productive with these tools! ⛄️ February picks for you</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Mon, 03 Feb 2020 14:51:46 +0000</pubDate>
      <link>https://dev.to/paco_ita/be-more-productive-with-these-tools-february-picks-for-you-ign</link>
      <guid>https://dev.to/paco_ita/be-more-productive-with-these-tools-february-picks-for-you-ign</guid>
      <description>&lt;p&gt;Already started some new year proposals or are you still wondering which one has the highest priority on your list (like me 😄)? &lt;br&gt;
In any case don't lose the focus, you still have plenty of time ahead to model your resolutions path!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/cmzp1CfhZRkMtlCuVj/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/cmzp1CfhZRkMtlCuVj/giphy.gif" alt="go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;



&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fheqd4epid77hhgc003p8.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%2Fheqd4epid77hhgc003p8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue paycard enhances a payment form with smooth micro-interactions, like number formatting, validation and automatic card type detection. &lt;/p&gt;

&lt;p&gt;It is built with vuejs (the React version is on the way 😄) and fully responsive.&lt;/p&gt;

&lt;p&gt;Give it a try with the sample below:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/JavaScriptJunkie/embed/YzzNGeR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/muhammederdem/vue-interactive-paycard" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fm4wgd3nu40i1116nrvfg.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%2Fm4wgd3nu40i1116nrvfg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Freezeframe.js is a library allowing to pause and re-enable animated gif images. You can choose for mouse hover or click events, touch event or with a manual toggle functions. &lt;br&gt;
Thanks to the library you can activate the animation only in specific cases (mouse hover, for instance) making the image much more catchy.&lt;/p&gt;

&lt;p&gt;1 - Dowload the library&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;freezeframe

or

yarn add freezeframe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - Import it in your 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;// es6&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Freezeframe&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;freezeframe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Commonjs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Freezeframe&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;freezeframe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Save a reference to your freezeframe instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ff&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;Freezeframe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Add event listeners to the instance&lt;/span&gt;
&lt;span class="nx"&gt;ff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&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;items&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="c1"&gt;// do something on start&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;ff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stop&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;items&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="c1"&gt;// do something on stop&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;ff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggle&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;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something on start&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something on stop&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;3 - Bind the library to an element in your template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"freezeframe"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image.gif"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- We can target a parent element if we need to wrap multiple images --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"freezeframe"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image1.gif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image2.gif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image3.gif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="http://ctrl-freaks.github.io/freezeframe.js/" rel="noopener noreferrer"&gt;Examples&lt;/a&gt;&lt;/p&gt;

&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe5kl8gukn3551brmy53h.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%2Fe5kl8gukn3551brmy53h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the last month collection, &lt;a href="https://dev.to/aweysahmed"&gt;Aweys Ahmed&lt;/a&gt; suggested &lt;code&gt;humaaans&lt;/code&gt; library as alternative to unDraw. 🎉 Many thanks Aweys for the hint! 😄&lt;/p&gt;

&lt;p&gt;Humaaans is a free library to manipulate and compose illustrations focusing on people (from here the name "humaaans").&lt;br&gt;
It's available on &lt;a href="https://www.invisionapp.com/studio" rel="noopener noreferrer"&gt;InVision Studio&lt;/a&gt;, which grants designers full control over the illustrations and mixing the different body parts, colours, clothing and hairstyles. A &lt;a href="https://www.dropbox.com/sh/grfucsjeaxe811s/AAABFGXFyqCNmF5gmijgJzOxa?dl=0" rel="noopener noreferrer"&gt;dropbox folder&lt;/a&gt; contains the illustrations (as .png files), a .studio and a .sketch project file that you can freely download. &lt;/p&gt;

&lt;p&gt;The amount of interchangeable elements is great, making it easy to create different scenes fitting a wide spectrum of projects and situations:&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%2F2fu0uaw6iz0wmm6ax220.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2fu0uaw6iz0wmm6ax220.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting with different pre-generated templates, you can apply several backgrounds to your illustration in order to give some more context details.&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%2Fx4tkskku0883ynq67lbu.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx4tkskku0883ynq67lbu.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are a professional designer or simply interested in a cool instrument to enhance your creativity, probably humaaans will be a good  add-on to your tool set.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://humaaans.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1k283bh86tfnsp3i4ae6.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%2F1k283bh86tfnsp3i4ae6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scene.js is an interesting JavaScript library for creating animated websites. It offers many different features to create advanced and appealing animations with few lines of code.&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%2Fhrqhhatozt5c50o9wsbt.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%2Fhrqhhatozt5c50o9wsbt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple usage can be the case when you need to animate some text:&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%2F8fflfrd4walxb4di7ljp.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8fflfrd4walxb4di7ljp.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.overflow .text span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&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="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;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0%&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="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;easing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ease-in-out&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;selector&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="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other side, if you need to develop more advanced scenarios, you can use the scenejs timeline library, where you can have full control over time, properties and items:&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%2Fgn4jrgpy3qeczx6j2go8.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgn4jrgpy3qeczx6j2go8.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;clapperScene&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;Scene&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.clapper&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: translate(-50%, -50%) rotate(0deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(-15deg)&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(0deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(-10deg)&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;.clapper-container&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zoomIn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;duration&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.clapper .circle&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="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zoomIn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;duration&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.clapper .play&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: translate(-50%, -50%)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zoomIn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;duration&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.top .stick1&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(0deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(-20deg)&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(0deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: rotate(-10deg)&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;.stick1 .rect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: scale(0) skew(15deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: scale(1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&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;.stick2 .rect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: scale(0) skew(-15deg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transform: scale(1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;easing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ease-in-out&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-timeline] &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;,&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;Timeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;clapperScene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#timeline .example_result&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;keyboard&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;On their &lt;a href="https://daybrush.com/scenejs/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; you can find other examples, like the counter below with a different animation for each step, making it much fancier:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/daybrush/embed/zWMeJW?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4y1hpq87glv5m3hh6pkz.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%2F4y1hpq87glv5m3hh6pkz.png" alt="Sortable"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sortable is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. &lt;br&gt;
It offers different features to use with a list or a grid, like the obvious drag &amp;amp; drop and sorting, but also the possibility to move items between list or to clone an element from one group to another.&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%2F6a4v9dsp194c07ktjwny.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6a4v9dsp194c07ktjwny.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the code used in the example above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"example2-left"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 5&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 6&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"example2-right"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 5&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item tinted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 6&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Sortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;example3Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shared&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// To clone: set pull to 'clone'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&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;Sortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;example3Right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shared&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Below another example, showing how the library can be used also with grid elements:&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%2Fcw5mti3bboycb5ha7ymm.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcw5mti3bboycb5ha7ymm.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;It also supports different javascript frameworks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vue&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/Vue.Draggable" rel="noopener noreferrer"&gt;Vue.Draggable&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/react-sortablejs" rel="noopener noreferrer"&gt;react-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/ngx-sortablejs" rel="noopener noreferrer"&gt;ngx-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jQuery&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/jquery-sortablejs" rel="noopener noreferrer"&gt;jquery-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knockout&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/knockout-sortablejs" rel="noopener noreferrer"&gt;knockout-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meteor&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/meteor-sortablejs" rel="noopener noreferrer"&gt;meteor-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polymer&lt;/strong&gt; &lt;a href="https://github.com/SortableJS/polymer-sortablejs" rel="noopener noreferrer"&gt;polymer-sortablejs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://sortablejs.github.io/Sortable/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>design</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Be more productive with these tools! ❄️ January picks for you</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Thu, 09 Jan 2020 14:13:19 +0000</pubDate>
      <link>https://dev.to/paco_ita/be-more-productive-with-these-tools-january-picks-for-you-4b86</link>
      <guid>https://dev.to/paco_ita/be-more-productive-with-these-tools-january-picks-for-you-4b86</guid>
      <description>&lt;p&gt;&lt;a href="https://i.giphy.com/media/g6Xmo9j6U0IhO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/g6Xmo9j6U0IhO/giphy.gif" alt="Happy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No better way to start the new year than a collection of Javascript libraries and get inspired for your projects! Without further ado, let's see what January brings us. &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%2Flztg0gol56hkurkanam1.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%2Flztg0gol56hkurkanam1.png" alt="Sal.js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sal.js is a scroll animation library, focusing on performance and  small footprint. It is written in vanilla JavaScript and doesn't introduce any additional dependencies.&lt;/p&gt;

&lt;p&gt;It is based on the Intersection Observer API, which allows to asynchronously observe changes in the intersection of a target element with an ancestor one or with a top-level document's viewport.&lt;/p&gt;

&lt;p&gt;Be aware though that not all browsers &lt;a href="https://caniuse.com/#feat=intersectionobserver" rel="noopener noreferrer"&gt;support&lt;/a&gt; this API:&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%2Fb2s5gk3eheksfqukc53e.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%2Fb2s5gk3eheksfqukc53e.png" alt="Support"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case your target browser is not supported, you need to use a &lt;a href="https://github.com/w3c/IntersectionObserver/tree/master/polyfill" rel="noopener noreferrer"&gt;polyfill&lt;/a&gt;.&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;In your template file, add &lt;code&gt;data-sal&lt;/code&gt; attribute with an animation name as value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-sal=&lt;/span&gt;&lt;span class="s"&gt;"fade"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!--
Many other animations are available:
- fade
- slide-up
- slide-down
- slide-left
- slide-right
- zoom-in
- zoom-out
- flip-up
- flip-down
- flip-left
- flip-right
 --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then simply initialise the library in the script 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;// ES6 modules&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sal&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;sal.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// CommonJS modules&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sal&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;sal.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;sal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sal.js will look for all elements with a &lt;code&gt;data-sal&lt;/code&gt; attribute and launch their animation when visible in the viewport. The animation's properties: &lt;code&gt;duration, delay and easing&lt;/code&gt; can be customised according to your own needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;data-sal=&lt;/span&gt;&lt;span class="s"&gt;"slide-up"&lt;/span&gt;
  &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"--sal-duration: 3s; --sal-delay: 2s;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://mciastek.github.io/sal/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;




&lt;p&gt; &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%2Fxoyr69149rptf2m5v62t.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%2Fxoyr69149rptf2m5v62t.png" alt="Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Headroom.js is a lightweight, high-performance JS widget (with no dependencies) that allows you to react to the user's scroll. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fixed headers are a popular approach for keeping the primary navigation in close proximity to the user. This can reduce the effort required for a user to quickly navigate a site, but they are not without problems…&lt;/p&gt;

&lt;p&gt;Large screens are usually landscape-oriented, meaning less vertical than horizontal space. A fixed header can therefore occupy a significant portion of the content area. Small screens are typically used in a portrait orientation. Whilst this results in more vertical space, because of the overall height of the screen a meaningfully-sized header can still be quite imposing.&lt;/p&gt;

&lt;p&gt;Headroom.js allows you to bring elements into view when appropriate, and give focus to your content the rest of the time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The library dynamically adds and removes CSS classes from the target element, allowing developers to carefully define what should happen in each case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- initially --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"headroom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- scrolling down --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"headroom headroom--unpinned"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- scrolling up --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"headroom headroom--pinned"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.headroom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;will-change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;200ms&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.headroom--pinned&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.headroom--unpinned&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are plenty of options that you can use to adapt the library with ease:&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;headroom&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;Headroom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elem&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;offset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;205&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tolerance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;classes&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;initial&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;animated&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;pinned&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;bounceInDown&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;unpinned&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;bounceOutUp&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;headroom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// to destroy&lt;/span&gt;
&lt;span class="nx"&gt;headroom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test it with different &lt;a href="https://wicky.nillia.ms/headroom.js/playroom/" rel="noopener noreferrer"&gt;demos&lt;/a&gt;. &lt;br&gt;&lt;br&gt;
Below an example using the swing effect: &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%2Fgd4d2f7wqwsgpfua8d5r.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgd4d2f7wqwsgpfua8d5r.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wicky.nillia.ms/headroom.js/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;



&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F34strmipjvws2og3aer8.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%2F34strmipjvws2og3aer8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PWA asset generator is a tool implemented by my friend &lt;a href="https://twitter.com/onderceylan" rel="noopener noreferrer"&gt;Önder Ceylan&lt;/a&gt; and based on &lt;a href="https://pptr.dev/" rel="noopener noreferrer"&gt;Puppeteer&lt;/a&gt;. It generates icons and splash screens automatically for your app and integrates them directly into the related files (manifest and index.html).&lt;br&gt;
If you have implemented at least once a PWA, you know how tedious and time consuming is creating icon images for different platforms, while  keeping sizes and quality for all of them. Thanks to PWA asset generator you can completely automate this step and be sure to deliver pixel perfect images to the several target devices.&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%2Fonderceylan%2Fpwa-asset-generator%2FHEAD%2Fstatic%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%2Fonderceylan%2Fpwa-asset-generator%2FHEAD%2Fstatic%2Fdemo.gif" alt="demo"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Install &amp;amp; Usage
&lt;/h3&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;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; pwa-asset-generator

&lt;span class="nv"&gt;$ &lt;/span&gt;npx pwa-asset-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;PWA asset generator offers several option to customise the generated assets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  Options
    &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;--background&lt;/span&gt;             Page background to use when image &lt;span class="nb"&gt;source &lt;/span&gt;is provided: css value  &lt;span class="o"&gt;[&lt;/span&gt;default: transparent]
    &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;--opaque&lt;/span&gt;                 Shows white as canvas background and generates images without transparency  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--padding&lt;/span&gt;                Padding to use when image &lt;span class="nb"&gt;source &lt;/span&gt;provided: css value  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="s2"&gt;"10%"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--scrape&lt;/span&gt;                 Scraping Apple Human Interface guidelines to fetch splash screen specs  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;--manifest&lt;/span&gt;               Web app manifest file path to automatically update manifest file with the generated icons
    &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--index&lt;/span&gt;                  Index HTML file path to automatically put splash screen and icon meta tags &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--path&lt;/span&gt;                   Path prefix to prepend &lt;span class="k"&gt;for &lt;/span&gt;href links generated &lt;span class="k"&gt;for &lt;/span&gt;meta tags
    &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt;                   Image &lt;span class="nb"&gt;type&lt;/span&gt;: png|jpeg  &lt;span class="o"&gt;[&lt;/span&gt;default: png]
    &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;--quality&lt;/span&gt;                Image quality: 0...100 &lt;span class="o"&gt;(&lt;/span&gt;Only &lt;span class="k"&gt;for &lt;/span&gt;JPEG&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;[&lt;/span&gt;default: 100]
    &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="nt"&gt;--splash-only&lt;/span&gt;            Only generate splash screens  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;--icon-only&lt;/span&gt;              Only generate icons  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--favicon&lt;/span&gt;                Generate favicon image and HTML meta tag  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nt"&gt;--landscape-only&lt;/span&gt;         Only generate landscape splash screens  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;--portrait-only&lt;/span&gt;          Only generate portrait splash screens  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--dark-mode&lt;/span&gt;              Generate iOS splash screen meta with &lt;span class="o"&gt;(&lt;/span&gt;prefers-color-scheme: dark&lt;span class="o"&gt;)&lt;/span&gt; media attr  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;--single-quotes&lt;/span&gt;          Generate HTML meta tags with single quotes  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;--log&lt;/span&gt;                    Logs the steps of the library process  &lt;span class="o"&gt;[&lt;/span&gt;default: &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/onderceylan/pwa-asset-generator" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F23wwkestlz7x31g9ttvv.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%2F23wwkestlz7x31g9ttvv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UnDraw is a collection of open-source (MIT licensed), constantly updated, sketched images to use in your blog or web app. &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%2F992yjakyiz0yylui47ao.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%2F992yjakyiz0yylui47ao.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The selection available is quite wide, allowing everybody to find easily an image matching almost any context. &lt;br&gt;
&lt;br&gt;Before downloading a file, you can also customise the colours to better fit the target colour palette.  &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%2F1uvxnsmgyhk5cvggncaw.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%2F1uvxnsmgyhk5cvggncaw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://undraw.co/illustrations" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcwpacw5z63ttnfwz8mwd.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%2Fcwpacw5z63ttnfwz8mwd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OFFEO is an online animated video maker to create social media videos with ease. It provides many motion graphics elements, templates and more than 500 royalty free soundtracks.&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%2F4luoycyeo8elxk5beeyx.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%2F4luoycyeo8elxk5beeyx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You start by selecting a template from different categories:&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%2Fhumimu8r26cskv3bfgm9.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%2Fhumimu8r26cskv3bfgm9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then you continue by adding elements and animations from the libraries available. Below a sample I created in barely 10 minutes (I know it is kind of horrible, but considering the time invested it is not too bad after all 😄):&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%2F1ko9va2csrkj9kocs015.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1ko9va2csrkj9kocs015.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway, to better understand the true potential behind the tool, watch the official introductory video:&lt;/p&gt;

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




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqqk4c9uzdj9kl4r6tunb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqqk4c9uzdj9kl4r6tunb.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>design</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Be more productive with these tools! 🎅 December picks for you</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Tue, 17 Dec 2019 14:27:43 +0000</pubDate>
      <link>https://dev.to/paco_ita/be-more-productive-with-these-tools-december-picks-for-you-ajd</link>
      <guid>https://dev.to/paco_ita/be-more-productive-with-these-tools-december-picks-for-you-ajd</guid>
      <description>&lt;p&gt;Just a couple of weeks remaining before the end of the year, let's have a look at the last collection for the 2019!!&lt;/p&gt;

&lt;p&gt;Many thanks to all the readers who left positive comments about the previous posts, it is always a pleasure to know you could use the suggested libraries in your projects!! ❤️&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%2F4upc8tzcghm5jcyo8rxu.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%2F4upc8tzcghm5jcyo8rxu.PNG" alt="medium-zooom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Medium zoom is a JavaScript library for zooming images on a page and add different effects to them, like a margin or a background color matching the target 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%2Ftd7w6lq6znpb7y0iixr4.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftd7w6lq6znpb7y0iixr4.gif" alt="sample"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;We have different ways to bind the zoom functionality to an image element:&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;// CSS selector&lt;/span&gt;
&lt;span class="nf"&gt;mediumZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-zoomable]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// HTMLElement&lt;/span&gt;
&lt;span class="nf"&gt;mediumZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#cover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;// NodeList&lt;/span&gt;
&lt;span class="nf"&gt;mediumZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-zoomable]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;// Array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#cover&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-zoomable]&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;mediumZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library offers several interesting features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📱 Responsive — scale on mobile and desktop&lt;/li&gt;
&lt;li&gt;🚀 Performant and lightweight — should be able to reach 60 fps&lt;/li&gt;
&lt;li&gt;⚡️ High definition support — load the HD version of your image on zoom&lt;/li&gt;
&lt;li&gt;🔎 Flexibility — apply the zoom to a selection of images&lt;/li&gt;
&lt;li&gt;🖱 Mouse, keyboard and gesture friendly — click anywhere, press a key or scroll away to close the zoom&lt;/li&gt;
&lt;li&gt;🎂 Event handling — trigger events when the zoom enters a new state&lt;/li&gt;
&lt;li&gt;📦 Customization — set your own margin, background and scroll offset&lt;/li&gt;
&lt;li&gt;🔧 Pluggable — add your own features to the zoom&lt;/li&gt;
&lt;li&gt;💎 Custom templates — extend the default look to match the UI of your app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://medium-zoom.francoischalifour.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F64aodox5j49992bwe3d3.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%2F64aodox5j49992bwe3d3.png" alt="Progress"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Progressbar.js is a library to create responsive and slick progress bars with animated SVG paths. Some built‑in shapes are available, but it is also possible to create custom shaped progress bars with any vector graphic editor.&lt;/p&gt;

&lt;p&gt;The usage is quite simple:&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;ProgressBar&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;progressbar.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;// Assuming you have an empty &amp;lt;div id="container"&amp;gt;&amp;lt;/div&amp;gt; in HTML&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ProgressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#container&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;easing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;easeInOut&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;animate&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;// Value from 0.0 to 1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Semi circle example (check the Result tab):&lt;br&gt;
&lt;iframe src="https://jsfiddle.net/kimmobrunfeldt/sqwdkrg0//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Custom shape example (check the Result tab):&lt;br&gt;
&lt;iframe src="https://jsfiddle.net/kimmobrunfeldt/dnLLgm5o//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kimmobrunfeldt.github.io/progressbar.js/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;



&lt;p&gt; &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%2Fxhspeg85hojpt0hoqswd.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%2Fxhspeg85hojpt0hoqswd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tailwind CSS is a utility-first framework for rapid UI development. &lt;br&gt;
Differently from others CSS frameworks, it doesn't provide a set of ready-to-use elements, but rather it offers several utility classes that can used directly in our HTML templates.&lt;/p&gt;

&lt;p&gt;For example, the following set of style rules, applied to a sample template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"md:flex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"md:flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rounded-lg md:w-56"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-1.2.1&amp;amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=448&amp;amp;q=80"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Woman paying for a purchase"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 md:mt-0 md:ml-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"uppercase tracking-wide text-sm text-indigo-600 font-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Marketing&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Finding customers for your new business&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-2 text-gray-600"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Getting a new business off the ground is a lot of hard work. Here are five ideas you can use to find your first customers.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate this output: &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%2Fmbyjccrcrgqqbgjk3dup.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%2Fmbyjccrcrgqqbgjk3dup.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea behind is to not write any custom CSS, but rather style our elements by applying pre-existing Tailwind classes directly to the HTML files. &lt;br&gt;Moreover every utility class can be applied conditionally at different breakpoints, making it very easy to build complex responsive interfaces.&lt;/p&gt;

&lt;p&gt;It is also possible to customize the default settings with ease:&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;// Example `tailwind.config.js` file&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;important&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="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;display&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="s1"&gt;Gilroy&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="s1"&gt;sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;body&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="s1"&gt;Graphik&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="s1"&gt;sans-serif&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;extend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#9cdbff&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;margin&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="s1"&gt;96&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="s1"&gt;24rem&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="s1"&gt;128&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="s1"&gt;32rem&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;opacity&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="s1"&gt;responsive&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="s1"&gt;hover&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3y6535xoe5kwidphk1lj.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%2F3y6535xoe5kwidphk1lj.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Color Thief can extract the dominant colour from an image and also generate a palette for it. The colour details are returned as an array of integers representing red, green, and blue values that can be used for further processing.  &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%2Fy1dfxthfx3txcc7edh6q.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%2Fy1dfxthfx3txcc7edh6q.png" alt="example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fu262kc19u6yxbwx4yzkg.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%2Fu262kc19u6yxbwx4yzkg.png" alt="example2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can be very useful when you need to decide which colours set to use in your web application.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lokeshdhakar.com/projects/color-thief/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpbz4mmhgsiwf72d66guw.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%2Fpbz4mmhgsiwf72d66guw.png" alt="ascii"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would you like to generate an ASCII title to give a &lt;em&gt;nerdish&lt;/em&gt; touch to your app? &lt;br&gt;
Then give Ascii Today a try, it is an interesting ASCII title generator, you type the title you want and you can select among different ASCII representations of the entered text:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe6jrisv7a5gzmv0k4f36.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%2Fe6jrisv7a5gzmv0k4f36.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ascii.today/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;br&gt;
That's all for the December collection! Come next year for new discoveries...&lt;br&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvrqvmzuwkvn3q3tce216.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%2Fvrqvmzuwkvn3q3tce216.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>🎄 Advent of Code 💻</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Mon, 02 Dec 2019 09:14:48 +0000</pubDate>
      <link>https://dev.to/paco_ita/advent-of-code-31mn</link>
      <guid>https://dev.to/paco_ita/advent-of-code-31mn</guid>
      <description>&lt;p&gt;Christmas holidays are getting close. Either we are planning to work on some personal side projects, learning some new techie subjects or simply recharging batteries with a well deserved coding pause.&lt;/p&gt;

&lt;p&gt;Nevertheless I would like to spread some awareness about the &lt;a href="https://adventofcode.com/2019"&gt;"Advent of code"&lt;/a&gt; series, created by &lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;, allowing us to practice our developer skills by solving programming problems on a daily base before Christmas.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is it about?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like. People use them as a speed contest, interview prep, company training, university coursework, practice problems, or to challenge each other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The challenge for the second day looks like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oHhAuChO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/mz8kkoie9u9qli75x7mv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oHhAuChO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/mz8kkoie9u9qli75x7mv.png" alt="Alt Text" width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the UI is minimal and you do not need any super computer to take part to it. All you need is just some IT background, but without being an expert developer.&lt;/p&gt;

&lt;p&gt;You need to authenticate before starting (you can use the most common social media login channels for this) and then you will get the input data to start the challenge and an input field to provide the answer with the solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OCSbmVig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5h0ywss9jiyn9yiz5m1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OCSbmVig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5h0ywss9jiyn9yiz5m1m.png" alt="Alt Text" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty easy, isn't it? The let's start solving the daily puzzle!!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>adventofcode</category>
    </item>
    <item>
      <title>🏋️ Train your WEB DEV skills with online games 🎮</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Wed, 27 Nov 2019 14:52:39 +0000</pubDate>
      <link>https://dev.to/paco_ita/train-your-javascript-skills-with-online-games-289m</link>
      <guid>https://dev.to/paco_ita/train-your-javascript-skills-with-online-games-289m</guid>
      <description>&lt;p&gt;Learning to code by ourselves can be overwhelming, not only for the difficulty of the subject, but also trying not to get lost in the humongous amount of tutorials and documentation available online. Luckily, there are resources that make things easier and fun, offering educational contents with a gamification aspect.&lt;/p&gt;

&lt;p&gt;For a reference you can check out the article I recently published, about learning CSS concepts through online games:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/paco_ita" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F183068%2F9f59ae0e-2b1c-475c-ad6d-8db6ee5544d4.jpg" alt="paco_ita"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/paco_ita/train-your-css-skills-with-online-games-4ah3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;💪 Train your CSS skills with online games 👾&lt;/h2&gt;
      &lt;h3&gt;Francesco Leardini ・ Nov 15 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#layout&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Afterwards, I got many inquiries about similar games to learn web development and javascript. Below the results of my research.&lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Checki0
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TJT471xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/lqxhklaxtq465d3u83s1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TJT471xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/lqxhklaxtq465d3u83s1.png" alt="Alt Text" width="700" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Checki0 allows to learn the basics of Javascript or Python by solving different problems and moving between "floating islands" in an imaginary world. Each island collects around 40 challenges and an increasing level of difficulty.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7b-KwxZ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/rjq0w675h5n4rod4wukb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7b-KwxZ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/rjq0w675h5n4rod4wukb.png" alt="Checki0" width="800" height="746"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://checkio.org/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Elevator Saga
&lt;/h2&gt;

&lt;p&gt;In Elevator Saga you have to program the movement of elevators, by writing a program in JavaScript. The goal is to transport people in the most efficient manner.&lt;br&gt;
Depending on how well you do it, you can progress through the ever more difficult challenges.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dDIW7--a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ic6ke6bkua7g2xjwulky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dDIW7--a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ic6ke6bkua7g2xjwulky.png" alt="Elevator" width="800" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An help and documentation section will help you moving the first steps in this interesting game.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="http://play.elevatorsaga.com/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  CodinGame
&lt;/h2&gt;

&lt;p&gt;CodinGame offers free games where you have to solve puzzles and algorithm problems. It is possible to choose which language to learn among a wide choice: JavaScript, Ruby, Java and C#, just to mention some. &lt;br&gt; To make things more interesting, you can invite friends to play online and - if you want to increase the challenge - you can also participate in international programming competitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hSGuydSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/bft3gev4mw1gikn8kmdz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hSGuydSU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/bft3gev4mw1gikn8kmdz.png" alt="CodinGame" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many playgrounds for each programming language and you can choose among different grades of difficulty, so that you can proceed at your own pace. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://www.codingame.com/training"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Screeps
&lt;/h2&gt;

&lt;p&gt;Screeps is MMO sandbox for programmers with already some experience. The title stands for "scripting creeps". The game offers a wide range of options for players and possibilities to practice real-life code in a fun way.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LW6OwtwR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/cyqhy3a8q7q6z1bu67rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LW6OwtwR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/cyqhy3a8q7q6z1bu67rq.png" alt="Alt Text" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Screeps is a massive multiplayer online real-time strategy game. Each player can create their own colony in a single persistent world shared by all the players. Such a colony can mine resources, build units, conquer territory. As you conquer more territory, your influence in the game world grows, as well as your abilities to expand your footprint. However, it requires a lot of effort on your part, since multiple players may aim at the same territory.&lt;br&gt; Unlike some other RTS games, your units in Screeps can react to events without your participation – provided that you have programmed them properly. And, unlike other MMO, you do not have to play Screeps constantly to play well. It is quite enough just to check once in a while to see if everything goes well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nOG3UZG0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w0wp1slekywgmhh6hbck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nOG3UZG0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w0wp1slekywgmhh6hbck.png" alt="Alt Text" width="800" height="590"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://screeps.com/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  CodeWars
&lt;/h2&gt;

&lt;p&gt;CodeWars is a portal providing an extensive list of languages you can choose from.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yi5mAb0T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r31f1s1llq8p4nmb14ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yi5mAb0T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r31f1s1llq8p4nmb14ie.png" alt="CodeWars" width="800" height="705"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After an initial and simple test, you will be asked to confirm the programming language you are interested in and to select at which level  to start your training (from absolute beginner to senior developer). You  earn points by solving different challenges, each one covering different coding principles, and compete with other developers for the highest position on the scoreboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CQMrvsIJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/juzpccidaevgebsg6gbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQMrvsIJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/juzpccidaevgebsg6gbp.png" alt="example" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://www.codewars.com/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Untrusted
&lt;/h2&gt;

&lt;p&gt;Untrusted is an adventure game where you need to use your JavaScript skills to solve problems that arise during the story development. In order to guide the main character (Dr. Eval, the green @ on the screen) between levels, you enter javascript instructions on the right panel to let him escape from the current stage.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7kLp5cf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/xga01dfzgrogu580ca79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7kLp5cf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/xga01dfzgrogu580ca79.png" alt="Alt Text" width="800" height="352"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://alexnisnevich.github.io/untrusted/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Ruby Warrior
&lt;/h2&gt;

&lt;p&gt;You guide a knight through different levels, coding his moves and learning Ruby along the way. You can choose among an easy or intermediate difficulty. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the game starts with music on! So be aware in case you open the link in the office or at school 😄&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EKgzf-wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/p8ayl74l20cbnz6eprbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EKgzf-wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/p8ayl74l20cbnz6eprbe.png" alt="Alt Text" width="700" height="489"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://www.bloc.io/ruby-warrior#/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Dungeon &amp;amp; Developers
&lt;/h2&gt;

&lt;p&gt;Many developers like RPG games (I do 😄) and 352 Inc, a digital web agency, used this aspect to create Dungeon &amp;amp; Developers.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9rcZ-Rgn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ppi52gzw3nwta7t3dopr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9rcZ-Rgn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ppi52gzw3nwta7t3dopr.png" alt="Alt Text" width="681" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not exactly a game, but it provides really cool graphics and it is worth a look. You build a &lt;em&gt;talent tree&lt;/em&gt;, following the classical RPG tree skills. For each level there is a set of links redirecting to different topics (CSS, Javascript, SEO, etc.), after mastering them - that is, you&lt;br&gt;
 study the referenced docs at each step - you unlock the next skillset, adding features points (strength, wisdom or charisma) to your character, exactly as in a classic RPG game.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---1RUhKTX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/otuf1e1rthv7vrtiwbio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---1RUhKTX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/otuf1e1rthv7vrtiwbio.png" alt="Alt Text" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the creators:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We came up with Dungeons &amp;amp; Developers as a fun way to assess, promote and learn the skills it takes to design and develop great web sites.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="http://www.dungeonsanddevelopers.com/"&gt;Let's play&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;


&lt;p&gt;If you know other games (not just tutorials or docs) to learn javascript or web development basics, please mention them in the comments below, so I will update the list.&lt;br&gt;
 &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---QrzixBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vq05prdgb5dxet2ucwhx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---QrzixBs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vq05prdgb5dxet2ucwhx.jpg" alt="Alt Text" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>game</category>
    </item>
    <item>
      <title>💪 Train your CSS skills with online games 👾</title>
      <dc:creator>Francesco Leardini</dc:creator>
      <pubDate>Fri, 15 Nov 2019 13:31:02 +0000</pubDate>
      <link>https://dev.to/paco_ita/train-your-css-skills-with-online-games-4ah3</link>
      <guid>https://dev.to/paco_ita/train-your-css-skills-with-online-games-4ah3</guid>
      <description>&lt;p&gt;As frontend developers we are often called to design a neat and appealing UI for our web app.&lt;/p&gt;

&lt;p&gt;Nowadays there are plenty of concepts and technologies to be aware of: SCSS, responsive design, Grid Layout and Flexbox, just to cite some. Even when we use them daily at work, we typically remember only the most common rules.&lt;/p&gt;

&lt;p&gt;Therefore why not practicing these concepts while playing and making the learning process fun?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/H3rmzuXUzcaOI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/H3rmzuXUzcaOI/giphy.gif" alt="fungames"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are several online games that allows us to train our design skills and keep them up to date in an entertaining way. Let's have a look at some of them together.&lt;/p&gt;




&lt;h1&gt;
  
  
  Basic CSS
&lt;/h1&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Diner
&lt;/h3&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%2Fg4uqsw53kmtdtudck5i8.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%2Fg4uqsw53kmtdtudck5i8.png" alt="CSS Diner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is to use CSS statements to select specific UI elements on the screen. If the entered rules are correct, we can pass to the following level. There are 32 levels in total.&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://flukeout.github.io/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  CSS Grid Garden
&lt;/h3&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%2Fgwld8qlkvtymvpav45qe.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%2Fgwld8qlkvtymvpav45qe.png" alt="cssgridgarden"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this game, we must water carrot crops by mastering CSS grid. To reach our goal we need to define columns, rows, and grid template areas.&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://cssgridgarden.com/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Gridcritters
&lt;/h3&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%2Fjostmz0vky409rva4sf1.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%2Fjostmz0vky409rva4sf1.png" alt="gridcritters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This game is a little design masterpiece. &lt;br&gt;
We need to use our CSS Grid skills to save alien critters from extinction! At each level more challenging requirements must be fulfilled  to succeed and proceed to the following stage.&lt;/p&gt;

&lt;p&gt;The game has been developed by Dave Geddes, ex IT architect, now fully converted into educational platforms developer. You can read &lt;a href="https://gedd.ski/post/new-grid-site/" rel="noopener noreferrer"&gt;here&lt;/a&gt; the story behind the project and also the CSS Grid rules used for the game home page. The blog post is already very informative by itself!&lt;br&gt;
&lt;strong&gt;Cost: 179$&lt;/strong&gt; &lt;a href="https://www.gridcritters.com/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  CSS Battle
&lt;/h3&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%2Fd5eviwckwle2w52g11p9.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%2Fd5eviwckwle2w52g11p9.PNG" alt="CSSBattle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In CSS Battle we have to replicate a target layout with the smallest possible code and we can compete against other players to get the highest score on the leaderboard.&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%2Fo8fpgab1mq6146vmf24b.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%2Fo8fpgab1mq6146vmf24b.PNG" alt="CSSBattle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://cssbattle.dev/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
👉 Thanks @ Nick Taylor for suggesting it in the comments!&lt;br&gt;
 &lt;/p&gt;



&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;
  
  
  Flexbox Layout
&lt;/h1&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Flexbox froggy
&lt;/h3&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%2Fqfru7wnt8vze8f83yk95.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%2Fqfru7wnt8vze8f83yk95.png" alt="flexboxfroggy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Help Froggy and friends by writing CSS code!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flexbox Froggy takes inspiration from the classic arcade game Frogger, and web literacy games like the brilliant CSS Diner and Erase All Kittens, where you learn about CSS selectors and HTML markup respectively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We must bring the frogs home to their lilypads by using CSS flexbox instructions. We need to control alignment, spacing, and wrapping of elements on the webpage to achieve our goal.&lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://flexboxfroggy.com/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Flexbox defense
&lt;/h3&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%2F37cblhul8f2skfkyyhby.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%2F37cblhul8f2skfkyyhby.png" alt="flexboxdefense"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flexbox defense is based on the classic tower defence games, but to place our items we write CSS instructions. We use the justify-content property on the main container to move the single towers into effective positions. &lt;br&gt;
&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="http://www.flexboxdefense.com/" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Flexbox zombies
&lt;/h3&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%2Fzeclqc7h1waz96knkdge.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%2Fzeclqc7h1waz96knkdge.png" alt="flexboxzombies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also this game has been designed by Dave Geddes (as Gridcritters above). Here we use Flexbox to position the hero's crossbow and hit the zombies and survive along the game.&lt;/p&gt;

&lt;p&gt;Have a look at the video below used by Dave for the game launch. Also in this case the graphics and the story are really amazing!&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each section unravels part of the plot, gives you expertise over a new flexbox concept, and presents zombie survival challenges that force you to solidify your new skills like your life depends on it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Free&lt;/strong&gt; &lt;a href="https://flexboxzombies.com/p/flexbox-zombies" rel="noopener noreferrer"&gt;Let's play&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;




&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Do you know other CSS/Design games?&lt;br&gt;
Write it in the comments below and I will add them to the above list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Js7cqIkpxFy0bILFFA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Js7cqIkpxFy0bILFFA/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  Useful references
&lt;/h1&gt;

&lt;p&gt;Below a collection of resources we can access if we need to learn from the basics or simply to have a look from time to time for a reference.&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Selectors
&lt;/h3&gt;

&lt;p&gt;An overview about all &lt;a href="https://www.w3schools.com/cssref/css_selectors.asp" rel="noopener noreferrer"&gt;Css selectors&lt;/a&gt; and how to apply them.&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Grid CSS
&lt;/h3&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%2F3thipbiuic5olwjuqs67.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%2F3thipbiuic5olwjuqs67.png" alt="gridbyexample"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://gridbyexample.com/learn/" rel="noopener noreferrer"&gt;comprehensive collection&lt;/a&gt; of resources (videos and examples) to learn CSS Grid Layout.&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  Flexbox Layout
&lt;/h3&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%2F6nkl5kfueli7s99y00fh.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%2F6nkl5kfueli7s99y00fh.png" alt="css-tricks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A visual guide to CSS flexbox layout (one of the best in my opinion). The guide focuses on all the different possible properties for the parent element (the flex container) and the child elements (the flex items).&lt;br&gt;
&lt;a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>layout</category>
    </item>
  </channel>
</rss>
