<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mathias Nilsson</title>
    <description>The latest articles on Forem by Mathias Nilsson (@edgesoft).</description>
    <link>https://forem.com/edgesoft</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F198759%2F1f283ac8-a8bd-418c-9a64-99d12b2d5be2.png</url>
      <title>Forem: Mathias Nilsson</title>
      <link>https://forem.com/edgesoft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/edgesoft"/>
    <language>en</language>
    <item>
      <title>Legacy codebase to Remix.run</title>
      <dc:creator>Mathias Nilsson</dc:creator>
      <pubDate>Thu, 23 Dec 2021 00:58:48 +0000</pubDate>
      <link>https://forem.com/edgesoft/legacy-codebase-to-remixrun-3mnb</link>
      <guid>https://forem.com/edgesoft/legacy-codebase-to-remixrun-3mnb</guid>
      <description>&lt;p&gt;The 27th of November I got a legacy codebase that needed to be maintained. I had never seen the code, but after some poking around in the codebase it was evident that it needed maintenance. &lt;/p&gt;

&lt;p&gt;I had just built an app using Remix.run &lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/edgesoft" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F198759%2F1f283ac8-a8bd-418c-9a64-99d12b2d5be2.png" alt="edgesoft"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/edgesoft/remixrun-back-to-basics-2p55" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Remix.run - Back to basics&lt;/h2&gt;
      &lt;h3&gt;Mathias Nilsson ・ Dec 22 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 and was ready for more. &lt;iframe class="tweet-embed" id="tweet-1464600405300727808-493" src="https://platform.twitter.com/embed/Tweet.html?id=1464600405300727808"&gt;
&lt;/iframe&gt;

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





&lt;p&gt;The app was built using C#, Angularjs, JQuery, FabricJS, chartjs and MySQL as DB. The short version of what the app does is calculating reverberation-time of a room/connected rooms taking into consideration the NRC and absorption of the material in the room. Using graphs and adding material/absorption to the room the app can be used to get close to the RT-60 goal or at least as near as possible.&lt;/p&gt;

&lt;p&gt;I dicided to go with Remix.run, MongoDB (with Prisma), Fabricjs and chartjs and Tailwindcss. The app should live side by side with the original app. I planned to use Fly.io for deployment.&lt;/p&gt;

&lt;p&gt;I literally started with this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;remix&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My plan was to look at the db model, dive into how the old website looked and mimic the functionality and try to improve on user experience.&lt;/p&gt;

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

&lt;p&gt;I have made rewrites before, but to be honest I never felt this happy with the progress. In a couple of days, I had rewritten the material routes and entity routes. The Graphs were just client side but with &lt;code&gt;useEffect&lt;/code&gt; hook I could get them easily to not server render. &lt;/p&gt;

&lt;p&gt;My mongodb is located in Sweden using Mongo Atlas. The app was deployed with Fly.io running in Frankfurt. This is initial load with cache disabled and this kind of load from the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;materials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MaterialPick&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;absorbtionLevels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;absorberClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;physicalMaterial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;materialType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;materials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;absorbtionLevels&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JsonArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JsonArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;material&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;absorbtionLevels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JsonObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;absorbtion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;absorbtion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frequency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frequency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Frequency&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;absorbtion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;frequency&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
          &lt;span class="p"&gt;}),&lt;/span&gt;
          &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Pretty fast!!&lt;/p&gt;

&lt;p&gt;If I could do this all over again and pick whatever stack I wanted, I would never move away from Remix.run. Maybe I could have used PostgreSQL instead since MongoDB with Prisma is beta. The app is a work in progress, but the main bits are in place with a superfast iteration. &lt;/p&gt;

&lt;p&gt;Hands down! If you ever needed to rewrite legacy code and you had the luxury to choose for yourself. Give Remix.run a try and make a POC to see for yourself. It can only be explained by using it. &lt;/p&gt;

&lt;p&gt;I'm glad to be a frontend/backend coder again.&lt;/p&gt;

</description>
      <category>react</category>
      <category>mongodb</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Remix.run - Back to basics</title>
      <dc:creator>Mathias Nilsson</dc:creator>
      <pubDate>Wed, 22 Dec 2021 20:31:52 +0000</pubDate>
      <link>https://forem.com/edgesoft/remixrun-back-to-basics-2p55</link>
      <guid>https://forem.com/edgesoft/remixrun-back-to-basics-2p55</guid>
      <description>&lt;p&gt;This is my first blogpost ever, and I never actually thought I would write one. Remix.run is the root cause, because it got me so  excited that I could not resist. Let me explain!&lt;/p&gt;

&lt;p&gt;I started programming for the web in the days of ASP (Active server pages). It was done using Visual Basic syntax so it was very basic. The form post to server and response was simple even though we didn't do the fancy Javascript stuff we are doing today. &lt;/p&gt;

&lt;p&gt;Netscape navigator was the ruler among browsers then.&lt;br&gt;
I moved from Perl cgi to ASP to JSP and Java Servlets and then to PHP. The simple api remained, even though JQuery started to be more and more popular. I used handcrafted XMLHttpRequest then. Even before Jesse James Garrett coined the term AJAX. &lt;/p&gt;

&lt;p&gt;Lately I've been doing fontend with GWT and now React for the last couple of years. I love React but doing form, collecting server state and keeping state in sync on the client has been very challenging. I've used Redux, Jotai, Cerebral JS, Overmind JS (favorite) to name a few state libraries.&lt;/p&gt;

&lt;p&gt;When I first heard of Remix.run I though "this sound interesting". I follow &lt;a class="mentioned-user" href="https://dev.to/ryanflorence"&gt;@ryanflorence&lt;/a&gt; &lt;a class="mentioned-user" href="https://dev.to/mjackson"&gt;@mjackson&lt;/a&gt; and &lt;a class="mentioned-user" href="https://dev.to/kentcdodds"&gt;@kentcdodds&lt;/a&gt; so the tweets kept rolling in. &lt;/p&gt;

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

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



&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1319302624450019328-82" src="https://platform.twitter.com/embed/Tweet.html?id=1319302624450019328"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;I bought a license when Remix.run was still a paid product and to be honest, I didn't do anything with it. It was great but I'm sorry to say I've bought to many courses/products that just collected virtual dust. &lt;/p&gt;

&lt;p&gt;My daughter started a hobby making clay earrings and one night I said "I can build a website for you if you like". I didn't think she would be excited but a promise is a promise. That's when I really took Remix.run for a spin.&lt;br&gt;
I fell in love with Remix right away. To have the loader and action in the same file as my Component felt like doing what I did from the start but even simpler. The productivity using Remix.run is just insane.&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;I have never moved this fast to prod. Mongodb, Vercel &amp;amp; Stripe in 1.5 weeks. Remix is soo productive&lt;/p&gt;— Mathias Nilsson (@edgesofts) &lt;a href="https://twitter.com/edgesofts/status/1463288740353388544?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;November 23, 2021&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;Here are the main concepts of Remix that I just love.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with, not against, the foundations of the web: Browsers, HTTP, and HTML.&lt;/li&gt;
&lt;li&gt;Everything you need in a single file with easy to read code. If a loader get's complex just put it in your own file.&lt;/li&gt;
&lt;li&gt;No need to overthink over/underfetching of data. Just filter what you want to reach the client.&lt;/li&gt;
&lt;li&gt;SSR out of the box&lt;/li&gt;
&lt;li&gt;Deploy to whatever cloud service you like using built in adapters from Remix or roll your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Head over to Remix.run and get started. The docs are superclear and easy to follow. &lt;a href="https://remix.run/docs/en/v1" rel="noopener noreferrer"&gt;https://remix.run/docs/en/v1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head over to Discord and get help  immediately from the very friendly community. &lt;a href="https://discord.gg/AwHQjyVK" rel="noopener noreferrer"&gt;https://discord.gg/AwHQjyVK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking forward to 2020 of awesome Remix apps.&lt;/p&gt;

&lt;p&gt;Next blog post will be about how I ported a fairly large C# angularjs app to Remix!&lt;/p&gt;

</description>
      <category>react</category>
      <category>programming</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
