<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/darko-kukovec/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 16 Apr 2026 15:26:52 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>40076https://infinum.com/uploads/2023/07/OAuth2-hero.webp</url>
				</image>
				<title>Overcome Token Storage and Security Challenges of OAuth2</title>
				<link>https://infinum.com/blog/secure-token-storage-oauth2/</link>
				<pubDate>Thu, 13 Jul 2023 13:29:15 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=40076</guid>
				<description>
					<![CDATA[<p>Implementing the recommendations from the official OAuth2 specification, we created an open-source library that allows you to save tokens securely.</p>
<p>The post <a href="https://infinum.com/blog/secure-token-storage-oauth2/">Overcome Token Storage and Security Challenges of OAuth2</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-176"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Saving tokens securely when using OAuth2 is often mishandled, even in tutorials, so we decided to implement the recommendations from the official specification by ourselves. Let us introduce you to our new open-source library – auth-worker.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	OAuth2 is a protocol widely used in modern web and mobile applications, enabling seamless integration with third-party services. You must have seen web pages or apps that have a “login with Google/Facebook/Twitter/other service” option – this functionality is built upon the OAuth2 standard.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	However, secure token storage with OAuth2 can be a challenge, and all of the tutorials available seem to mishandle the issue.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	With OAuth2 specification as the basis, we implemented the official recommendations and created an open-source library that enables secure token storage. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	In this blog post, we present both the security problem and the solution, focusing on the implementation of OAuth2 in the browser, and more specifically, in single-page applications.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	What is OAuth2?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	OAuth2 is an open standard protocol that provides a secure and standardized way for users to grant limited access to their protected resources on one website (the resource server) to another website or application (the client) without having to share their login credentials. It acts as an authorization framework, allowing users to delegate access rights to their resources across websites and applications.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-114">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-115'
	>
	Why use OAuth2?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	There are many benefits to using OAuth2. First and foremost, it enhances security by eliminating the need for users to share their usernames and passwords with third-party applications. Instead, OAuth2 relies on authorization tokens, reducing the risk of credential theft and unauthorized access. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	This framework also offers fine-grained control over access permissions, allowing users to grant specific rights to different applications. It provides a layer of abstraction, ensuring that users retain control over their data with the option to revoke access at any time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-123'
	>
	<strong>OAuth2 promotes interoperability and simplifies integration between different platforms, fostering the development of a vibrant ecosystem of interconnected services.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	Furter, OAuth2 enhances user experience by enabling the single sign-on (SSO) functionality. Users can authenticate once with the identity provider (such as Google or Facebook) and then seamlessly access multiple applications and services without the need to log in repeatedly. This streamlines the login process, reduces friction, and improves usability across various platforms and devices. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-128">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-129'
	>
	OAuth2 also encourages innovation and collaboration by facilitating the integration of third-party services, allowing developers to leverage existing platforms and extend the functionality of their applications without reinventing the wheel.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-131">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-132'
	>
	What the tutorials get wrong</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	If you search for tutorials on how to implement OAuth2 in a JavaScript application, almost every tutorial or article will make one crucial mistake – how to save tokens.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	The most obvious way to save data in the browser is to simply save it to localStorage. If you are trying to be more conscious of security, you might decide that sessionStorage is better, or perhaps cookies. However, out of those options, only one is secure enough to store credentials, and only under specific circumstances – http-only cookies</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-140'
	>
	With http-only cookies, the server sets the cookie, and only the server can read it – it is completely invisible to the JS app in the browser. However, this might not always be an option as OAuth2 providers usually don’t support this method.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-142">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-143'
	>
	The problem with localStorage, sessionStorage, and regular cookies (or any other similar storage, like IndexedDB) is that they can be accessed by the JS code and are therefore susceptible to XSS attacks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-145">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-146'
	>
	There are multiple real scenarios when this could become an issue:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-148">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-149'
	>
	<li>A compromised dependency could add some code that steals the tokens</li><li>Some user input might not be escaped well enough, and a malicious user could insert code that would steal the tokens</li><li>If you’re using tools like Google Tag Manager, someone could unknowingly (e.g., while not checking it closely enough) inject a malicious script through the GTM dashboard that steals the tokens</li><li>A rogue browser extension installed in the user’s browser that is stealing data from browser storage and sending it to its owner</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-151">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-152'
	>
	Of course, in some cases, the risk might be acceptable – if it’s just an internal app and all other best practices are followed, and the expiration time of the tokens is short, these security risks might not matter to you. Regardless, this should be an educated decision with known risks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-154">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-155'
	>
	So, what is the solution?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-159"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-157">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-158'
	>
	Surprisingly, despite many tutorials mishandling this issue, the OAuth2 specification actually has some <a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6.4" target="_blank" rel="noreferrer noopener">good recommendations</a> on how to solve this issue.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-162"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-160">
	<h3	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-161'
	>
	Apps with server-side rendering</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-165"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-163">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-164'
	>
	In many cases, <a href="https://infinum.com/blog/react-project-structure/" target="_blank" rel="noreferrer noopener">when we’re using React</a>, we also use Next.js, which basically gives us a lot of flexibility. In this case, the simplest solution is to use the <a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6.2" target="_blank" rel="noreferrer noopener">Backend for Frontend</a> Proxy with http-only cookies by using the Next.js API endpoints as a proxy for all authenticated API calls. We also combine this with <a href="https://next-auth.js.org/" target="_blank" rel="noreferrer noopener">NextAuth.js</a>, which handles the login and token exchange in a secure way (on the server side).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-168"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-166">
	<h3	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-167'
	>
	Client-side rendered apps</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-171"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-169">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-170'
	>
	If you don’t have a dedicated server, things are a bit trickier. To handle tokens in a secure way (and not expose them in the browser scope), the specification suggests leveraging <a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#name-javascript-applications-obt" target="_blank" rel="noreferrer noopener">Service Worker</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-174"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-172">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-173'
	>
	The OAuth2 specification recommends using Service Workers because they can intercept API calls and add the credentials before passing the API call to the server. They can also intercept the login flow – that way, no sensitive data needs to be exposed to the main browser thread.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-177"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-178">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/07/auth-chart-1400x654.webp				media='(max-width: 699px)'
				type=image/webp								height="654"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/07/auth-chart.webp"
					class="image__img block-media__image-img"
					alt=""
										height="830"
															width="1776"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			SOURCE: <a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6.4:~:text=User%20%20%20%20%20%20%20Application%20%20%20%20%20%20%20%20Service,Authorization%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20server%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20server" target="_blank" rel="noreferrer noopener">IETF</a>		</figcaption>
	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-238"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-180">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-181">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-182'
	>
	In this case, one big downside of client-side rendered apps is that there is no secure way to persist the tokens in the browser because all storage options are available across all scopes. This means that the tokens exist only in the service worker’s memory. Since Service Workers usually have a longer lifespan than the web pages they belong to, the UX will not be significantly compromised. In some cases, an acceptable compromise would be to encrypt the data with a key that is hardcoded in the service worker, but this is more of a security through obscurity solution, and it’s not covered in the best practices document.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-184">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-185'
	>
	And it’s not just the tutorials…</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-187">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-188'
	>
	If we look at the OAuth2 libraries and SDKs from some big names like Auth0 and Microsoft, we can see that they make the same mistake – asking the user to detect a callback and then saving the data into the regular cookie or local/session storage. This leads us to wonder why they would not implement the best practice that some of them (e.g., Okta, the owner of Auth0) contributed to. It is possible that this is due to issues with Service Workers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-190">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-191'
	>
	<li>Developer Experience while using SW is worse than without them – it is harder to revalidate things, the DevTools are not that polished, etc.</li><li>Browser support – until recently, Service Workers were not a viable solution for general usage. Right now, however, all major browsers (except Firefox in Private Mode) support Service Workers.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-193">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-194'
	>
	OAuth2 implementation security issue – solved</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-196">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-197'
	>
	Since there seemed to be no good solution for this problem (at least not one that is provider-agnostic), we decided to make our own – and open-source it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-199'
	>
	Meet <a href="https://github.com/infinum/auth-worker" target="_blank" rel="noreferrer noopener">auth-worker</a>, a library that does most of the heavy lifting of Oauth2 authentication with the workers. It has built-in support for some OAuth2 providers (e.g., Google and Facebook), and anyone can define their custom providers, with new ones to be added in the future. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-201">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-202'
	>
	Auth-worker also manages the <a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#auth_code_request" target="_blank" rel="noreferrer noopener">PKCE</a> flow and OAuth2 state (both of these are security recommendations from the specification) automatically without any extra work from the app side.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-206"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-204">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-205'
	>
	If it is an acceptable compromise for you, the library also supports persisting the encrypted auth data in IndexedDB.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-209"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-207">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-208'
	>
	To <a href="https://github.com/infinum/auth-worker#getting-started" target="_blank" rel="noreferrer noopener">get started</a> with the library, you just need to do three things:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-210">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-211'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-212'
	>
	Create a service worker:</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> service-worker.ts</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #24292e;">initAuthServiceWorker</span><span class="token"> </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">from</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">auth-worker/worker</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #24292e;">google</span><span class="token"> </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">from</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">auth-worker/providers</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">initAuthServiceWorker</span><span class="token">(</span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #24292e;">google</span><span class="token"> </span><span class="token">}</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">/auth</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">/allowed</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">/routes</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-219"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-216">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-217'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-218'
	>
	Load the service worker:</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> index.ts</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">import</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">loadAuthServiceWorker</span><span class="token"> </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #005cc5;">from</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">auth-worker</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">loadAuthServiceWorker</span><span class="token">(</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">google</span><span class="token">:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">             </span><span class="token" style="color: #6f42c1;">clientId</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">example-client-id</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">             </span><span class="token" style="color: #6f42c1;">scopes</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">https://www.googleapis.com/auth/userinfo.profile</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #d73a49;">catch</span><span class="token">(</span><span class="token" style="color: #005cc5;">console</span><span class="token">.</span><span class="token" style="color: #005cc5;">error</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-225"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-222">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-223'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-224'
	>
	Start using the library.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-228"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-226">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-227'
	>
	Here is an example of how to make an authenticated API call:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-230"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #005cc5;">response</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token" style="color: #6f42c1;">fetch</span><span class="token">(</span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">https://example.com/api</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">method</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">POST</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">headers</span><span class="token">:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">             </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">Content-Type</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">application/json</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">             </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">X-Use-Auth</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">true</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> This is how we tell the library that we want auth</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">body</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">JSON</span><span class="token">.</span><span class="token" style="color: #6f42c1;">stringify</span><span class="token">(</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">foo</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">bar</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">}</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-233"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-231">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-232'
	>
	Prioritize security with auth-worker</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-236"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-234">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-235'
	>
	There are a lot of different ways to implement authentication, but all of them have their pros and cons. Depending on your requirements, you might choose a different approach, but it is always important to keep security in mind and make decisions that don’t endanger the safety of users or our data. We hope that you find auth-worker useful in overcoming the token storage and security challenges of OAuth2.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/secure-token-storage-oauth2/">Overcome Token Storage and Security Challenges of OAuth2</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>35474https://infinum.com/uploads/2023/03/AI-coding-assistants-and-their-impact-on-the-work-of-developers-hero.webp</url>
				</image>
				<title>AI Coding Assistants – Developers’ Friends or Foes?</title>
				<link>https://infinum.com/blog/ai-coding-assistants/</link>
				<pubDate>Mon, 13 Mar 2023 13:41:05 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=35474</guid>
				<description>
					<![CDATA[<p>AI coding assistants can be useful tools, but make the most sense for more experienced developers who know what they're doing. </p>
<p>The post <a href="https://infinum.com/blog/ai-coding-assistants/">AI Coding Assistants – Developers’ Friends or Foes?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-424"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-239">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-240">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-241'
	>
	<strong>Although it may seem counterintuitive, AI tools can be of greatest help to those who already know what they’re doing.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-243">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-244'
	>
	Three engineers walk into a bar. Together, they have 25 years of experience, but 15 of those belong to one of them. How many years of experience do the other two engineers have?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-246">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-247'
	>
	This seems like a typical question people are asking ChatGPT these days. After all, <a href="https://www.fastcompany.com/90819887/how-to-trick-openai-chat-gpt" target="_blank" rel="noreferrer noopener">outsmarting AI is the ultimate goal</a> – or is it?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-249">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-250'
	>
	We asked three flesh-and-blood engineers about their experience of working with AI coding assistants GitHub Copilot and ChatGPT, and found out whether they recommend using them – and in what cases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-252">
	<p	class='typography typography--size-20-text-roman js-typography block-typography__typography'
	data-id='es-253'
	>
	These are their stories. *tn tn*</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-255">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-256'
	>
	The flesh-and-blood engineers who participated in this experiment</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-258">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-259'
	>
	Marin Teskera, a junior developer fresh off of JavaScript course at Infinum Academy. He is at the beginning of his career and eager to learn the intricacies of programming.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-261">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-262'
	>
	Tomislav Habalija, a JavaScript engineer turned JavaScript team lead, who also wrote the Angular course curriculum for Infinum Academy and mentored Marin at the JavaScript course. He’s been in the biz for seven years.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-264">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-265'
	>
	Darko Kukovec, an experienced JavaScript and TypeScript engineer with +15 years of code writing under his belt. He is the head of frontend development.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-273"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-267"
	 href='https://infinum.com/artificial-intelligence/agent-development/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<h2	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-268'
	>
	As the pressure to implement AI grows, many businesses don&#8217;t know where to start. Our 14-day sprint helps you cut through the noise—turning early ideas into validated prototypes with clear logic, smart design, and real momentum. Learn how it works.</h2>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-270"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-271'
	>
	Learn more </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-272'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-276"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-274">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-275'
	>
	Where did AI code writing assistants prove to be useful?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-279"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-277">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-278'
	>
	Using a coding assistant for writing boilerplate code</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-282"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-280">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-281'
	>
	Nobody likes it, but boilerplate is always there. It’s a hassle to read and maintain it, so any kind of a helping hand is a godsend. Whether it’s lists of data or some repetitive code, types, or just long names of variables and functions, it’s easier to use an AI coding assistant to write it, and then check if everything is ok than to do the whole thing from scratch.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-283">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-284'
	>
	Also, as our Marin puts it, “doesn’t it feel great when the AI coding assistant recommends something you were going to write anyway?” #sanityCheck</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-286">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-287'
	>
	Using a coding assistant for writing documentation</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-289">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-290'
	>
	Sometimes you know exactly what you want to do, but you can’t fully remember the documentation for some API (e.g. DOM, or even your own code). The copilot might be able to autocomplete big chunks of the code without having to switch tabs or apps to check the docs.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-294"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-292">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-293'
	>
	What tasks did AI code writing assistants struggle with?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-297"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-295">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-296'
	>
	Using AI tools for learning something new</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-300"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-298">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-299'
	>
	With <a href="https://github.com/karimould/awesome-js-tooling-in-rust" target="_blank" rel="noreferrer noopener">a lot of JavaScript tooling being written in Rust </a>nowadays, Darko Kukovac decided to try out first-hand what all the fuss was about. He opted for Rust when solving the <a href="https://adventofcode.com/2022" target="_blank" rel="noreferrer noopener">2022 edition of advent of code</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-303"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-301">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-302'
	>
	“In preparation, I had just enough time to read the first six chapters of the Rust docs – not great, not terrible. This was enough to get familiar with the basic concepts, but without any practical knowledge, it would surely be quite annoying to google solutions for each trivial issue I encountered. After all, that’s what happened when I tried Kotlin a few years ago,” Darko said.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-306"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-304">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-305'
	>
	Copilot did its job and got Darko through the first few days with much less frustration than expected. Of course, he still had to google things, but mostly on the conceptual level and not syntax or trivial issues. After a few days, he noticed his understanding of the language got better, and he was able to better understand Copilot’s suggestions and assess if they were good solutions or not. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-309"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-307">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-308'
	>
	Looking back at the code that Darko wrote himself and the code where he trusted Copilot (almost) blindly, he concludes:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-310">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-311'
	>
	“The Copilot code is somewhat weaker because it adds extra steps or does some things in a less-than-ideal way. However, I do believe it can help engineers kickstart their learning experience, which is a plus.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-313">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-314'
	>
	<strong>Using code you don’t understand</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-316">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-317'
	>
	What happens when the AI helper recommends code you don’t understand?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-319">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-320'
	>
	By just mindlessly pressing the tab key, developers who are still learning the ropes can miss the opportunity to learn by trial and error.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-324"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-322">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-323'
	>
	For example, in last year&#8217;s edition of Infinum Academy, our mentor Tomislav Habalija had a few students who were writing suspiciously clean code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-325">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-326'
	>
	“I had a hunch something was going on until I realized they were using GitHub Copilot.” </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-330"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-328">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-329'
	>
	It is a tool, or as they say on their website – AI pair programmer, which speeds up your developing process by giving you suggestions on what to write next.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-333"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-331">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-332'
	>
	For example, let&#8217;s say you want to write a simple function that calculates average numbers. Just by writing the function calculateAverage and selecting the first GitHub Copilot example, you will get the correct implementation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-335"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">function</span><span class="token"> </span><span class="token" style="color: #6f42c1;">calculateAverage</span><span class="token">(</span><span class="token">numbers</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">  const</span><span class="token"> </span><span class="token" style="color: #005cc5;">sum</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">numbers</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">reduce</span><span class="token">((</span><span class="token" style="color: #005cc5;">acc</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">number</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">acc</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token" style="color: #005cc5;">number</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">  return</span><span class="token"> </span><span class="token" style="color: #005cc5;">sum</span><span class="token"> </span><span class="token" style="color: #d73a49;">/</span><span class="token"> </span><span class="token" style="color: #005cc5;">numbers</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">length</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-339"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-336">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-337'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-338'
	>
	This can be a great time saver for a senior developer who knows what they are doing but a big pitfall for junior developers. “By writing code from scratch, you are learning, and while using tools like this, you are just writing code,” says Tomislav. </p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-342"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-340">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-341'
	>
	<strong>Introducing bugs while you introduce “correct” code</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-345"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-343">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-344'
	>
	If you’re not that experienced, blindly trusting the coding assistant can result in using code that is plain wrong. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-348"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-346">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-347'
	>
	But even if the code is correct and it works, it doesn’t always follow best practices. It might also introduce errors that a beginner doesn’t know how to fix. That is really not ideal when working on a bigger project because when another programmer starts to work on the code, they may have a hard time following it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-351"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-349">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-350'
	>
	Case in point: Tomislav Habalija tested this when he was writing a regular expression:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-354"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-352">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-353'
	>
	“I had to write a regex for removing query params from the string. Easy enough, right? So I asked the AI.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-357"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-355">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-356'
	>
	This was Tomislav’s prompt:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-359"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-18-text js-typography block-highlighted-text__typography'
	data-id='es-358'
	>
	Write a regex for removing query params from the string using javascript.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-362"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-360">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-361'
	>
	And he received a correct response:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-364"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #005cc5;">removeQueryParams</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">url</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">url</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #d73a49;">/</span><span class="token">\</span><span class="token" style="color: #d73a49;">?</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">/</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-367"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-365">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-366'
	>
	This solved one case but added a bug to the rest of the code because the team was using templated links. ChatGPT couldn’t know that, as Tomislav did not mention it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-370"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-368">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-369'
	>
	Back to the drawing board, Tomislav tried another prompt:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-372"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-18-text js-typography block-highlighted-text__typography'
	data-id='es-371'
	>
	Write a regex for removing query params from the url that contains templated strings. Templated part starts with { and ends with }. Templated part must not be removed from the string.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-375"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-373">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-374'
	>
	This time, the answer was slightly better. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-377"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #005cc5;">removeQueryParams</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">url</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">url</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #d73a49;">/</span><span class="token">\</span><span class="token" style="color: #d73a49;">?</span><span class="token">(</span><span class="token" style="color: #d73a49;">?:</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token">{</span><span class="token">]</span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">)</span><span class="token" style="color: #d73a49;">?</span><span class="token">(</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">]*)#?.*/, &#039;$1&#039;);</span><span class="token" style="color: #6a737d;">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-380"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-378">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-379'
	>
	“Regex is bigger, it should be correct, right? Right? I have tried it out in my code, and I was surprised when the tests started failing. The answer was still wrong,” Tomislav decided before giving AI one final chance.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-382"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-18-text js-typography block-highlighted-text__typography'
	data-id='es-381'
	>
	The provided answer still removes the templated part. For example, regex should not remove &#8220;{?foo}&#8221; or &#8220;{?bar}&#8221; from &#8220;http://www.test.com{?foo}/bar{?bar}?first_param=1&amp;second=2&#8221;. Can you try again?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-385"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-383">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-384'
	>
	AI’s response was &#8220;Here is a modified regular expression that will remove the query parameters from a URL string, while leaving any templated parts of the URL intact:&#8221;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-387"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">url</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #d73a49;">/</span><span class="token">\</span><span class="token" style="color: #d73a49;">?</span><span class="token">(</span><span class="token" style="color: #d73a49;">?:</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token" style="color: #d73a49;">?</span><span class="token">{</span><span class="token">]</span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">)</span><span class="token" style="color: #d73a49;">?</span><span class="token">(</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">]*)(#?.*)/, &#039;$1$2&#039;);</span><span class="token" style="color: #6a737d;">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-390"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-388">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-389'
	>
	This answer was even worse than the one before. The answer Tomislav was looking for was:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-392"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">url</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #d73a49;">/</span><span class="token">(</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token">{</span><span class="token">])\</span><span class="token" style="color: #d73a49;">?</span><span class="token">[</span><span class="token" style="color: #d73a49;">^</span><span class="token" style="color: #d73a49;">/</span><span class="token">]</span><span class="token" style="color: #d73a49;">+</span><span class="token" style="color: #d73a49;">/</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">$1</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-395"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-393">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-394'
	>
	And he couldn’t get AI to come up with that. At least not with the questions and descriptions he provided.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-398"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-396">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-397'
	>
	<strong>Privacy considerations</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-401"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-399">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-400'
	>
	Since both GitHub Copilot and ChatGPT use their servers to generate results, the question is what happens with the data entered. How is it used? This might be a very important question if you’re working on a project that is not open source.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-404"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-402">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-403'
	>
	In the case of Copilot, there’s <a href="https://github.com/settings/copilot" target="_blank" rel="noreferrer noopener">an option in settings</a> that allows it to use your code to train the AI – this doesn’t mean that someone will get your snippet of code, but someone might get a code snippet that was in part inspired by your code. If you’re working on code that is not open source or the license doesn’t allow this type of usage, you should disable this option.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-407"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-405">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-406'
	>
	On the other hand, ChatGPT doesn’t have such settings, and <a href="https://help.openai.com/en/articles/6783457-chatgpt-faq" target="_blank" rel="noreferrer noopener">all entered data</a> could be used to train the AI. That’s why you should always be careful what you enter into the system and obfuscate any information you don’t want to share with anyone.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-410"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-408">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-409'
	>
	Turns out, AI coding assistants are only as smart as the engineer using them</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-413"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-411">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-412'
	>
	Our engineers all agreed that using an AI coding assistant makes the most sense for more experienced developers who know what they are doing.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-416"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-414">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-415'
	>
	For people trying to learn, like our junior engineer Marin, using a tool like this brings the same benefits as for the experienced developer. However, they should be careful about using code they don’t understand because it can affect their learning curve, or they might even end up introducing the wrong functionalities. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-419"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-417">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-418'
	>
	Using AI coding assistants with a grain of salt can speed up development, but for now at least, it is not ready to take over the wheel.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-422"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-420">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-421'
	>
	<em>If you are interested in utilizing AI in your digital product, see <a href="https://infinum.com/ai-business-solutions/" target="_blank" rel="noreferrer noopener">how we can help you on the way</a>.</em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/ai-coding-assistants/">AI Coding Assistants – Developers’ Friends or Foes?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7954https://infinum.com/uploads/2019/09/the-role-of-javascript-in-the-biggest-ios-security-exploit-yet-0.webp</url>
				</image>
				<title>The Role of JavaScript in the Biggest Apple Security Breach</title>
				<link>https://infinum.com/blog/the-role-of-javascript-in-the-biggest-ios-security-exploit-yet/</link>
				<pubDate>Tue, 03 Sep 2019 15:05:00 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/the-role-of-javascript-in-the-biggest-ios-security-exploit-yet/</guid>
				<description>
					<![CDATA[<p>Find out what was the role of JavaScript in the biggest Apple security breach that is responsible for 2 million instances of privacy breaches.</p>
<p>The post <a href="https://infinum.com/blog/the-role-of-javascript-in-the-biggest-ios-security-exploit-yet/">The Role of JavaScript in the Biggest Apple Security Breach</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-506"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-425">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-428"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-426">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-427'
	>
	A few months ago, Google Project Zero discovered a bunch of security exploits in iOS versions from 10.0 up to 12.1.3 that cover a total of 1.4 billion devices.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-431"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-429">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-430'
	>
	Last week, they published their findings in more detail. What part did JavaScript play in the incident?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-434"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-432">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-433'
	>
	What’s the issue with Safari?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-437"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-435">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-436'
	>
	Based on the <a href="https://googleprojectzero.blogspot.com/2019/08/a-very-deep-dive-into-ios-exploit.html">Google Project Zero research</a>, a malicious website would be able to install a monitoring implant on the phone, and the implant would have access to pretty much <a href="https://googleprojectzero.blogspot.com/2019/08/implant-teardown.html">everything on the phone</a>–photos, contacts, messages, the real-time location, and keychain (passwords, certificates, etc.)</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-440"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-438">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-439'
	>
	Based on Google’s investigation, this was used by the Chinese government to target some of their citizens. They estimate a few thousands of people a day were targeted for up to 2 years, but it’s hard to know if they were the only ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-443"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-441">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-442'
	>
	We’re talking more than <strong>2 million instances of privacy breaches</strong>, and that’s just the part that’s been accounted for.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-446"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-444">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-445'
	>
	Why is this relevant for developers?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-449"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-447">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-448'
	>
	Perhaps not directly, but any <a href="https://infinum.com/mobile-web-apps/">developer using iOS</a>, or any “smart” device for that matter (yes, even a blender), should make sure they are up-to-date with the latest security updates. To me, the most interesting part of this privacy breach was how the attackers found the security issues.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-452"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-450">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-451'
	>
	<a href="https://googleprojectzero.blogspot.com/2019/08/jsc-exploits.html">The issues</a> are mostly using array or object bugs to gain read/write access to the system memory and then use some lower level OS issues to install the tracker.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-455"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-453">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-454'
	>
	The most likely scenario is that the attackers used the open source nature of WebKit and to find the vulnerabilities affecting the Safari browser on iOS. Once a vulnerability was detected by someone and reported to Apple, it would usually be fixed, test cases (both JavaScript and C++) were added and a nice descriptive commit message was written.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-458"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-456">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-457'
	>
	The problem here is that with WebKit being open source, and the fact it is updated together with the OS, the fix would be waiting for the next OS release–usually for months. All the while, the vulnerability was exposed to the public.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-465"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-459"
	 target='_blank' rel='noopener noreferrer' href='https://infinum.com/cybersecurity/penetration-testing/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<h2	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-460'
	>
	Keeping your business safe starts with penetration testing—simulated attacks that assess your security posture. Explore our pentesting services and discover any vulnerabilities in your system before malicious actors do.</h2>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-462"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-463'
	>
	Find out more </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-464'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-468"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-466">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-467'
	>
	Is there a problem with other platforms?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-471"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-469">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-470'
	>
	Chrome and the new Edge</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-474"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-472">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-473'
	>
	The same issue could happen, but a bit more unlikely because the release cycle is faster, and they generally don’t include JavaScript test cases. Therefore, the attackers would need to reverse-engineer the commit instead of just copy/pasting the problematic code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-477"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-475">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-476'
	>
	Firefox and the old Edge</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-480"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-478">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-479'
	>
	Mozilla and Microsoft keep the security commits private until the release is public, so the chances of this are very slim.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-483"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-481">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-482'
	>
	Other open source projects</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-486"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-484">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-485'
	>
	The majority of other projects, like <a href="https://www.kernel.org/doc/html/v4.19/admin-guide/security-bugs.html">Linux</a> and <a href="https://source.android.com/security/overview/updates-resources.html">Android</a> have a similar approach to Mozilla, in which they discuss and prepare security fixes in private, and publish them publicly only after they’re ready to be installed on the affected systems.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-489"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-487">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-488'
	>
	Safety measures you should be taking</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-492"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-490">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-491'
	>
	In the case described above, it seems like malicious websites added the problematic code themselves, but it could have also been added by some third party.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-495"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-493">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-494'
	>
	Although it’s not realistic to review all the source code of all the dependencies we’re using, it’s important to use <a href="https://infinum.com/blog/top-10-most-useful-iOS-libraries/">reliable libraries from well-known authors</a> (which is also <a href="https://blog.npmjs.org/post/180565383195/details-about-the-event-stream-incident">not a 100% guarantee</a>) whenever possible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-498"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-496">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-497'
	>
	Also, keep an eye on the <code>npm install</code> command, which is doing an automated security audit of all installed packages, and run <code>npm audit</code> / <code>yarn audit</code> manually from time to time–or use the <a href="https://help.github.com/en/articles/about-security-alerts-for-vulnerable-dependencies">GitHub’s security monitoring</a> feature.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-501"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-499">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-500'
	>
	Better safe than sorry!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-504"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-502">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-503'
	>
	<em>In case you&#8217;d like to consult on improving your company&#8217;s security posture, check out our <a href="https://infinum.com/cybersecurity/" target="_blank" rel="noreferrer noopener">cybersecurity services</a>. </em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/the-role-of-javascript-in-the-biggest-ios-security-exploit-yet/">The Role of JavaScript in the Biggest Apple Security Breach</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>8079https://infinum.com/uploads/2017/02/squeezing-webpack-into-backend-frameworks-0.webp</url>
				</image>
				<title>Squeezing Webpack into Backend Frameworks</title>
				<link>https://infinum.com/blog/squeezing-webpack-into-backend-frameworks/</link>
				<pubDate>Tue, 24 Jan 2017 10:46:00 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/squeezing-webpack-into-backend-frameworks/</guid>
				<description>
					<![CDATA[<p>In order for a page to be fast, it’s a good idea to concatenate all your JavaScript assets into one file and all your CSS assets into another. </p>
<p>The post <a href="https://infinum.com/blog/squeezing-webpack-into-backend-frameworks/">Squeezing Webpack into Backend Frameworks</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-681"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-507">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-510"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-508">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-509'
	>
	If you ever made a website, it probably contained some assets like images, CSS and JavaScript. In order for a page to be fast, it’s a good idea to concatenate all your JavaScript assets into one file and all your CSS assets into another. Caching might also be tricky…</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-513"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-511">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-512'
	>
	Working with assets 101</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-516"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-514">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-515'
	>
	If you want to concatenate files, use SASS or make sure your files are not cached when they shouldn’t be, you’ll need to use a tool that will take care of that. Most web frameworks have tools that work out of the box, but that might not be good enough for everyone.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-519"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-517">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-518'
	>
	The asset pipeline</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-522"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-520">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-521'
	>
	The asset pipeline is Rails’ way of preparing files for production. Other frameworks might use different names for it, but they all mostly do the same thing.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-525"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-523"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-524">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/squeezing-webpack-into-backend-frameworks-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="661"
															width="961"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			 The basic Ruby on Rails request flow		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-528"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-526">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-527'
	>
	Module bundlers</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-531"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-529">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-530'
	>
	A module bundler does a similar thing, but it is generally more flexible. The final product (files) might be similar, but it does more things in between.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-534"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-532">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-533'
	>
	Webpack – the good parts</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-537"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-535">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-536'
	>
	Webpack is a module bundler that is getting more popular day by day. Although this is mostly because of the <a href="https://facebook.github.io/react/">React</a> community, it gained a lot traction in other communities, e.g. the <a href="https://github.com/angular/angular-cli">Angular 2 CLI</a> also switched to Webpack recently.<br>The reason why it’s so popular is that it’s very fast and extendable. Therefore, it can be adapted to a lot of different use-cases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-540"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-538">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-539'
	>
	Here are some things that Webpack can do with very little configuration that would be impossible or very hard in the Rails asset pipeline:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-543"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-541">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-542'
	>
	<li>Dead code removal – remove unused code to decrease the final JS size</li><li>Code splitting – break the code into multiple parts that can be loaded only when needed</li><li>Linting – stop the build process if there are some errors that might cause issues</li><li>Treat assets as modules – every asset (images, fonts, etc.) can be required and used anywhere</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-546"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-544">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-545'
	>
	Webpack handles assets in a different way, which might be weird at first, but is very powerful. Your application has only one entry point (in most cases this will be a JavaScript file), and from there, you can require all other files as you need them. You can include other JavaScript files, but also CSS, JPG, PNG, or any other format you want. The important thing is to define a loader for a specific file format, and you’re good to go.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-549"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-547">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-548'
	>
	What is out there</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-552"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-550">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-551'
	>
	When we decided to use Webpack with Rails, we looked at the available options and tried a few. Although they were good, none of them covered all our use cases:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-555"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-553">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-554'
	>
	<li>The Pixelated approach – It’s very similar to our approach, but the difference being in how assets are handled in production. Since they’re using the same fingerprint for all files, it means that it will change when any of the files changes. What that means is – if you change one icon and redeploy your site, the visitors will need to download all the assets again, even if nothing has changed for them. We think this is very inefficient, especially if you’re doing multiple deploys per day.</li><li><a href="https://github.com/mipearson/webpack-rails">webpack-rails</a> gem – It requires you to change how you’re using the assets from the Rails side. It also has a very specific (tightly coupled) setup that might limit us in some situations.</li><li><strong>webpack-assets gem</strong> – The whole configuration is done through Rails and it makes some assumptions about your client-side setup</li><li><a href="https://github.com/danethurber/webpack-manifest-plugin">webpack-manifest-plugin</a> – this plugin was our starting point, but we realized there were some features missing, like the very powerful <a href="https://github.com/infinum/webpack-asset-pipeline/blob/master/documentation/options.md#mapassetpath"><code>mapAssetPath</code></a> that allows us to do manual adjustments in some cases that aren’t covered out of the box.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-558"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-556">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-557'
	>
	Rails 5.1</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-561"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-559">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-560'
	>
	It <a href="https://github.com/rails/rails/pull/26836#issuecomment-264242030">was announced</a> a few weeks ago that Rails 5.1 will get an official (but experimental) support for Webpack. The release date for Rails 5.1 is still unknown. Given that Rails 5 was released in June, and the <a href="https://github.com/rails/rails/milestones">current progress of 5.1</a> is just above 50%, it might still be a while before you’ll be able to use it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-564"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-562">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-563'
	>
	The missing link</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-567"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-565">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-566'
	>
	Our approach was simple – find a common ground for communication between Webpack and Rails. With this approach, we’re avoiding the tight coupling – Rails doesn’t know much about Webpack, and Webpack doesn’t know a lot about Rails. There are two parts of the solution:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-570"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-568">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-569'
	>
	The Webpack part</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-573"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-571">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-572'
	>
	Webpack will be responsible for all the assets in the project. Since it will also add fingerprints to the files, we’ll need to let Rails know what the new files are, and to which folders they’re saved. To make this part simple, we created <a href="https://github.com/infinum/webpack-asset-pipeline">webpack-asset-pipeline</a>. The plugin will intercept all requires and imports from your JS and CSS and add them to the manifest JSON file:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-575"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #24292e;">WebpackAssetPipeline</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">require</span><span class="token">(</span><span class="token">’</span><span class="token" style="color: #24292e;">webpack</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #24292e;">asset</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #24292e;">pipeline</span><span class="token">’</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">module</span><span class="token">.</span><span class="token" style="color: #005cc5;">exports</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> The usual Webpack configuration</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">entry</span><span class="token">:</span><span class="token"> ’</span><span class="token" style="color: #24292e;">main</span><span class="token" style="color: #24292e;">.j</span><span class="token">s</span><span class="token">’</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> etc.</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">plugins</span><span class="token">:</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">WebpackAssetPipeline</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">output</span><span class="token">:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">path</span><span class="token">:</span><span class="token"> ’</span><span class="token" style="color: #24292e;">public</span><span class="token" style="color: #d73a49;">/</span><span class="token">’</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">publicPath</span><span class="token">:</span><span class="token"> ’</span><span class="token" style="color: #d73a49;">/</span><span class="token">’</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">filename</span><span class="token">:</span><span class="token"> ’</span><span class="token">[</span><span class="token" style="color: #24292e;">name</span><span class="token">]</span><span class="token" style="color: #24292e;">.j</span><span class="token">s</span><span class="token">’
</span></span><span class="line"><span class="token">  </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-578"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-576">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-577'
	>
	When you run Webpack, the plugin will create a <code>manifest.json</code> file that will contain all the asset mappings.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-581"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-579">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-580'
	>
	An example of JavaScript code with requires:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> application.js</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">require</span><span class="token">(</span><span class="token">’</span><span class="token" style="color: #24292e;">application</span><span class="token" style="color: #24292e;">.cs</span><span class="token">s</span><span class="token">’</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">require</span><span class="token">(</span><span class="token">’</span><span class="token" style="color: #24292e;">images</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #24292e;">file1</span><span class="token" style="color: #24292e;">.jp</span><span class="token">g</span><span class="token">’</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">require</span><span class="token">(</span><span class="token">’</span><span class="token" style="color: #24292e;">images</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #24292e;">file2</span><span class="token" style="color: #24292e;">.jp</span><span class="token">g</span><span class="token">’</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">require</span><span class="token">(</span><span class="token">’</span><span class="token" style="color: #24292e;">images</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #24292e;">file3</span><span class="token" style="color: #24292e;">.jp</span><span class="token">g</span><span class="token">’</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-584">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-585'
	>
	The mappings you’ll get in the manifest file:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-588"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">application.js</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">application-63eb3290f4d9a09812716b989a0808f3.js</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">application.css</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">application-07eb3299a08b981290763eb32962808f.css</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">images/file1.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">963eb32907744d9a0d6b98127162808f.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">images/file2.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">162808f4d9a0963eb3290774127d6b98.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">images/file3.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">d6b98127162969a0808f3eb32907744d.jpg</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-591"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-589">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-590'
	>
	To run Webpack on every relevant file change (for development), you should run it with the <code>&#8211;watch</code> flag:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-593"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">webpack</span><span class="token"> </span><span class="token" style="color: #005cc5;">-</span><span class="token" style="color: #005cc5;">-watch</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-596"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-594">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-595'
	>
	The Rails part</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-599"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-597">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-598'
	>
	The only thing Ruby on Rails needs to do is to replace the assets helpers. This can be done in one of two ways (depending on your preferences). In both cases, you should remove Rails sprockets because they will not be used, and you won’t be able to use their methods by mistake. The easiest way to do this is with the following command when you’re creating your app:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-601"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">rails</span><span class="token"> </span><span class="token" style="color: #032f62;">new</span><span class="token"> </span><span class="token" style="color: #032f62;">app</span><span class="token"> </span><span class="token" style="color: #005cc5;">-</span><span class="token" style="color: #005cc5;">-skip-sprockets</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-602">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-603'
	>
	Adding a new <code>webpack_asset_url</code> helper</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-605">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-606'
	>
	You’ll need a helper to replace the asset pipeline. Here is an example of how you can do this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-609"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> app/helpers/webpack_helper.rb</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">module</span><span class="token"> </span><span class="token" style="color: #6f42c1;">WebpackHelper</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">webpack_asset_url</span><span class="token">(</span><span class="token">asset</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/assets/</span><span class="token" style="color: #032f62;">#{</span><span class="token" style="color: #032f62;">manifest</span><span class="token" style="color: #032f62;">.</span><span class="token" style="color: #6f42c1;">fetch</span><span class="token" style="color: #032f62;">(</span><span class="token" style="color: #032f62;">asset</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">}</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">manifest</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #24292e;">@</span><span class="token" style="color: #24292e;">manifest</span><span class="token"> </span><span class="token" style="color: #d73a49;">||=</span><span class="token"> </span><span class="token" style="color: #005cc5;">JSON</span><span class="token">.</span><span class="token" style="color: #6f42c1;">parse</span><span class="token">(</span><span class="token" style="color: #005cc5;">File</span><span class="token">.</span><span class="token" style="color: #6f42c1;">read</span><span class="token">(</span><span class="token">’manifest</span><span class="token">.</span><span class="token" style="color: #6f42c1;">json</span><span class="token">’</span><span class="token">)</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">rescue</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">fail</span><span class="token"> ’</span><span class="token" style="color: #005cc5;">Please</span><span class="token"> run webpack’
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-612"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-610">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-611'
	>
	An example how to use the helper:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-614"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">img src</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">#{</span><span class="token" style="color: #6f42c1;">webpack_asset_url</span><span class="token" style="color: #032f62;">(</span><span class="token" style="color: #032f62;">’logo</span><span class="token" style="color: #032f62;">.</span><span class="token" style="color: #6f42c1;">svg</span><span class="token" style="color: #032f62;">’</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">}</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> alt</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">logo</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-617"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-615">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-616'
	>
	You’ll need to add the main JavaScript file to your layout with this helper. Also, keep in mind that you shouldn’t use Rails <code>image_tag</code>, <code>stylesheet_link_tag</code> or <code>javascript_include_tag</code> helpers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-620"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-618">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-619'
	>
	Monkey patching Rails assets helpers</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-623"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-621">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-622'
	>
	The second solution means a little more work in the start, but your application code will stay the same. Although removing sprockets is optional in the first method, in this case you have to remove them. The code for monkey patching is available <a href="https://github.com/infinum/webpack-asset-pipeline/blob/master/documentation/integrations/rails.md">in the plugin documentation</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-626"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-624">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-625'
	>
	After you’re done with monkey patching, you’ll be able to use the assets in the same way you used the asset pipeline:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-628"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">image_tag</span><span class="token">(</span><span class="token">’logo</span><span class="token">.</span><span class="token" style="color: #6f42c1;">svg</span><span class="token">’</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">=</span><span class="token"> stylesheet_link_tag ’application’</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">m</span><span class="token" style="color: #005cc5;">e</span><span class="token" style="color: #005cc5;">dia:</span><span class="token"> ’all’
</span></span><span class="line"><span class="token" style="color: #d73a49;">=</span><span class="token"> javascript_include_tag ’application’
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-631"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-629"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-630">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/squeezing-webpack-into-backend-frameworks-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="680"
															width="960"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			 Updated flow in combination with Webpack		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-634"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-632">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-633'
	>
	Hot reloading</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-637"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-635">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-636'
	>
	If you want to use all the features Webpack can offer, you can. One of the biggest features is hot reloading. Since JavaScript hot reloading depends on the JavaScript framework, this is out of scope for this blog post, but CSS hot reloading can be set up with relative ease:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-638">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-639'
	>
	Configuring Webpack</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-643"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-641">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-642'
	>
	To use hot reloading, all assets will need to be served from the Webpack server. To work correctly with the rest of the setup, you’ll need to proxy the rest through the Webpack server to your original app server. For that, you can use <a href="https://webpack.js.org/guides/development/#webpack-dev-server"><code>webpack-dev-server</code></a>, or if you need more control, <a href="https://webpack.js.org/guides/development/#webpack-dev-middleware"><code>webpack-dev-middleware</code></a> in combination with <a href="http://expressjs.com/"><code>express</code></a>. An example of how to configure the <code>webpack-dev-middleware</code> to enable CSS hot reloading is available in the <a href="https://github.com/DarkoKukovec/webpack-express-dev-server-boilerplate"><code>webpack-express-dev-server-boilerplate</code></a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-646"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-644">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-645'
	>
	You’ll also need to set the <a href="https://github.com/infinum/webpack-asset-pipeline/blob/master/documentation/options.md"><code>writeToFileEmit</code></a> property in <code>webpack-asset-pipeline</code> to <code>true</code> to ensure the manifest is saved to disk and therefore accessible by the app server.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-649"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-647"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-648">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/squeezing-webpack-into-backend-frameworks-5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="661"
															width="961"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			 Request flow during development with hot reloading		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-652"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-650">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-651'
	>
	Caveats</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-655"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-653">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-654'
	>
	There are still some issues we didn’t solve, but they’re just features that are nice to have – nothing essential:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-658"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-656">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-657'
	>
	Running the server</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-661"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-659">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-660'
	>
	Since both Webpack and Rails have their servers or watch commands, we’ll need to run them both at the same time. We can do this either by having two terminals running the processes or by using something like the <a href="https://github.com/ddollar/foreman">foreman</a> gem.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-664"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-662">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-663'
	>
	Requiring assets</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-667"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-665">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-666'
	>
	A great thing about Webpack is that it only processes those files that are explicitly referenced in JavaScript or CSS. That works great as long as you don’t need the assets somewhere else (e.g. in Rails). If you need an asset in Rails, but not in JS/CSS, you’ll still need to require the file in JS so Webpack will know it has to process it. The best way to do this is to have a separate JS file where you require all the assets that are used in Rails, but not in JS/CSS.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-670"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-668">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-669'
	>
	What if I’m using some other framework instead of Rails?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-673"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-671">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-672'
	>
	You might not be using Rails on your projects, but the plugin could work just as well with other server-side frameworks like Laravel, Django, Spring or ASP.NET MVC – the only thing you’ll need to do yourself is write the helper that will be used to fetch the asset names from the manifest file.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-676"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-674">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-675'
	>
	Want to contribute?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-679"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-677">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-678'
	>
	We’re looking to cover as many platforms as possible, so if you created helpers for your framework, you can send us a pull request with instructions on how to set it up. I’m sure others will appreciate it.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/squeezing-webpack-into-backend-frameworks/">Squeezing Webpack into Backend Frameworks</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>8052https://infinum.com/uploads/2014/03/web-components-building-blocks-of-the-future-web-0.webp</url>
				</image>
				<title>Web Components  Building Blocks of the Future Web</title>
				<link>https://infinum.com/blog/web-components-building-blocks-of-the-future-web/</link>
				<pubDate>Thu, 27 Mar 2014 10:00:00 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/web-components-building-blocks-of-the-future-web/</guid>
				<description>
					<![CDATA[<p>Every now and then a technology comes out that changes the web landscape. In 2008, Google announced Google Chrome, a simple but fast and powerful browser. Around the same time, HTML5 started to emerge and gave us access to a lot of new features. Now it&#8217;s time to embrace another new technology called Web Components.</p>
<p>The post <a href="https://infinum.com/blog/web-components-building-blocks-of-the-future-web/">Web Components  Building Blocks of the Future Web</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-771"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-682">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-685"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-683">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-684'
	>
	Every now and then a technology comes out that changes the web landscape. In 2008, Google announced Google Chrome, a simple but fast and powerful browser. Around the same time, HTML5 started to emerge and gave us access to a lot of new features. Now it’s time to embrace another new technology called Web Components.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-688"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-686">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-687'
	>
	Although users won’t notice Web Components, they are probably an equally big change for web developers. First, let’s start with some history so we have a better understanding of how Web Components came to be.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-689">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-690'
	>
	A brief history of web libraries</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-694"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-692">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-693'
	>
	<li>2005 – <a href="http://dojotoolkit.org/">Dojo Toolkit</a> is published with an innovative idea: widgets. With a few lines of code, developers can add complicated elements like graphs and dialogs to their web pages.</li><li>2006 – <a href="http://jquery.com/">jQuery</a> gives us an ability to write small plugins that can later be reused.</li><li>2008 – <a href="https://jqueryui.com/">jQuery UI</a> is released and gives us a set of widgets and effects</li><li>2009 – Initial release of <a href="http://angularjs.org/">AngularJS</a>, a web framework with directives</li><li>2011 – Initial version of <a href="http://facebook.github.io/react/">React</a> (Facebook) is released, giving us the ability to build the page UI without worrying what framework is used on the rest of the page</li><li>2013 – <a href="http://www.w3.org/TR/components-intro/">Web Components</a> draft is published, but because of a small browser support, they are still not ready for the prime-time</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-697"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-695">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-696'
	>
	When Dojo Toolkit was published, developers saw the advantages of having reusable modules. Today, when we mention plugins on a web page, most of us think about jQuery plugins since they are used almost everywhere and can do almost anything.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-700"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-698">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-699'
	>
	AngularJS and React showed us the direction in which the web platform is moving, with web elements that aren’t just visuals, but have complex logic on their own.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-703"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-701">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-702'
	>
	Web Components</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-706"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-704">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-705'
	>
	Similar to HTML5, Web Components is a name for a group of features:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-709"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-707">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-708'
	>
	<li><strong>Shadow DOM</strong> allows us to encapsulate <a href="http://en.wikipedia.org/wiki/Document_Object_Model">DOM</a> and <a href="http://en.wikipedia.org/wiki/Css">CSS</a></li><li><strong>HTML Templates</strong> are a way of having a clonable DOM that can be reused on the page</li><li><strong>Custom elements</strong> can either create new or extend existing elements. That means that a developer can, for example, extend the input element to support only credit card number format or they can create a new element which will contain all the fields required for credit card payment.</li><li><strong>HTML Imports</strong> are a way of including web components into the page without having them inline in the code</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-712"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-710">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-711'
	>
	The interesting part is that web browsers already use web components. For example, datepicker or &lt;video&gt; element are web components, they are usually just hidden from the developer.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-715"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-713"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-714">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/03/web-components-building-blocks-of-the-future-web-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="241"
															width="538"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Datepicker element and its source code		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-718"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-716"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-717">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/03/web-components-building-blocks-of-the-future-web-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="260"
															width="768"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			 Datepicker element with its Shadow DOM displayed		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-721"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-719">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-720'
	>
	What is the point of Web Components?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-724"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-722">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-723'
	>
	JavaScript widgets and plugins are fragmented because they rely on different libraries and frameworks that might not play nice together. Web Components are a way of <strong>standardizing</strong> widgets and plugins.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-727"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-725">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-726'
	>
	The great thing about Web Components is encapsulation and, therefore, reusability – they can be used with any library or framework. Web Components don’t even need to be UI components – they can even be libraries that expose some functionality.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-730"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-728">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-729'
	>
	One of the examples is <a href="https://github.com/PolymerLabs/polymer-ajax">polymer-ajax</a>, which isn’t that useful but it gives us an idea what’s possible. Polymer-ajax is a web component that gives the developer a standard way of doing <a href="http://en.wikipedia.org/wiki/AJAX">AJAX</a> requests, so the developer doesn’t need to worry about browser quirks. It is something like <strong>$.ajax()</strong> in jQuery, but it doesn’t have any dependencies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-733"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-731">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-732'
	>
	Browser support</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-736"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-734">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-735'
	>
	Currently, the main issue with Web Components is that no browser supports them completely. Luckily, there are libraries like Polymer that <a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">polyfill</a> missing native features and go out of the way if the browser supports the feature.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-739"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-737"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-738">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/web-components-building-blocks-of-the-future-web-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="320"
															width="460"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-742"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-740">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-741'
	>
	<a href="https://www.polymer-project.org/">Polymer</a> (Google) has two parts &#8211; one for creating web components, and another for using them.<br>Another Web Component library is <a href="http://www.x-tags.org/">X-Tag</a> (Mozilla). The great thing about Web Components is that, no matter whether they were built with Polymer or X-Tags, they can seamlessly work together, and that exactly is the beauty of standardization.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-745"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-743">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-744'
	>
	Using the Polymer library, Web Components can be used in all evergreen browsers (the newest versions of Chrome, Firefox, Safari and Opera) and Internet Explorer 10 and newer. On mobile, web components will work on iOS6+, Chrome Mobile, Firefox Mobile and Android 4.4.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-748"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-746">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-747'
	>
	Older browsers like Internet Explorer 9 or Android Browser 4.3 don’t support Web Components, even with Polymer.<br />
This means that Web Components aren’t ready for use on the web, but they can be used inside of a native wrapper if the app targets a supported <a href="https://infinum.com/blog/web-technologies-for-desktop-development/">browser</a> or platform (iOS6+).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-751"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-749">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-750'
	>
	Although X-Tag library supports some older browsers for creating components, Polymer is required to use most of them and, therefore, the browser support is the same.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-754"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-752">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-753'
	>
	Alternatives</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-757"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-755">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-756'
	>
	Web Components might not be ready for use yet, but there are some libraries that already make use of some similar patterns to achieve the DOM abstraction:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-760"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-758">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-759'
	>
	<li><strong>React</strong> has its own “Virtual DOM” and allows the developer to use something very similar to Web Components. Since it doesn’t try to simulate Web Components, browser support is much better (Internet Explorer 6+). React is currently used on the Instagram and Facebook commenting system.</li><li><strong>AngularJS directives</strong> are very similar to web components but don’t use the Web Component standard in order to achieve better browser support (Internet Explorer 8+). Since AngularJS is Google’s playground for future features, it will surely move to real web components at some point.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-763"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-761">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-762'
	>
	The future</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-766"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-764">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-765'
	>
	Web Components might not be the silver bullet that will solve all web development problems, but once they gain a big enough support, they will simplify the development and maintenance of web pages and apps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-769"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-767">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-768'
	>
	I believe that in a few years embedding a YouTube video using a &lt;youtube-video&gt; component or displaying your Facebook profile on your web page or blog with a &lt;facebook-profile&gt; component will be normal. Also, when reusing an element you don&#8217;t have to worry if the new code will mess up something else or the other way around, which will make web development much easier. </p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/web-components-building-blocks-of-the-future-web/">Web Components  Building Blocks of the Future Web</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>8138https://infinum.com/uploads/2014/02/web-technologies-for-desktop-development-0.webp</url>
				</image>
				<title>Web Technologies for Desktop Development</title>
				<link>https://infinum.com/blog/web-technologies-for-desktop-development/</link>
				<pubDate>Mon, 28 Oct 2013 03:45:00 +0000</pubDate>
				<dc:creator>Darko Kukovec</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/web-technologies-for-desktop-development/</guid>
				<description>
					<![CDATA[<p>The second consecutive Webcamp Zagreb tech conference attracted around 600 participants from Croatia and the region.</p>
<p>The post <a href="https://infinum.com/blog/web-technologies-for-desktop-development/">Web Technologies for Desktop Development</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-813"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-772">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-775"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-773">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-774'
	>
	This Saturday, the second consecutive <a href="http://2013.webcampzg.org/">Webcamp Zagreb</a> tech conference took place. This year, there were around 600 participants from Croatia and the region, and they could choose between 24 presentations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-778"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-776">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-777'
	>
	Webcamp Zagreb is an annual developer conference organized by Croatian user groups that work with different web technologies like JavaScript, Ruby, Python, Java, .NET, PHP and others. One of the organizers is <strong>CodeAtSix</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-781"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-779">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-780'
	>
	CodeAtSix is a meetup we organize at Infinum that gathers developers interested in Ruby, Rails, Javascript, GIT, web and mobile app development in general.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-784"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-782">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-783'
	>
	Web technologies for desktop development</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-787"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-785">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-786'
	>
	I had the opportunity to give a presentation titled <strong>Web Technologies for Desktop Development</strong> in front of more than 250 people. In the 20 minute presentation I talked about the options developers have when developing desktop hybrid apps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-790"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-788"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-789">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/02/web-technologies-for-desktop-development-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="768"
															width="1024"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-793"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-791">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-792'
	>
	Node-webkit</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-796"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-794">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-795'
	>
	The majority of my talk was focused around&nbsp;<a href="https://github.com/rogerwang/node-webkit" target="_blank" rel="noreferrer noopener">node-webkit</a>&nbsp;&#8211; a technology we use for developing desktop applications using Web technologies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-799"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-797">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-798'
	>
	Node-webkit is a very powerful wrapper for hybrid desktop apps, which allows the developer to use the full power of <strong>Chromium</strong>. On the other hand, if the developer needs access to native functionality, node-webkit comes with <strong>node.js</strong> to help with that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-802"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-800">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-801'
	>
	WebCamp 2013 was awesome</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-805"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-803">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-804'
	>
	In the end, I would like to thank the Webcamp Zagreb organizers for an awesome conference. The schedule was tight, the organization top notch, and I’m very impressed with how they managed to bring together developers working with different technologies (typically known for flame wars) under one roof. That’s a real achievement.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-808"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-806">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-807'
	>
	I really hope the conference stays like this in the following years.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-811"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-809"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-810">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/02/web-technologies-for-desktop-development-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="768"
															width="1024"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Yeah. That’s a unicorn		</figcaption>
	</figure></div></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/web-technologies-for-desktop-development/">Web Technologies for Desktop Development</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>