<?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: Navaneeth Pk</title>
    <description>The latest articles on Forem by Navaneeth Pk (@navaneethpk).</description>
    <link>https://forem.com/navaneethpk</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%2F666359%2Fd4daa89d-d8d4-436f-af10-11d910b90a55.png</url>
      <title>Forem: Navaneeth Pk</title>
      <link>https://forem.com/navaneethpk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/navaneethpk"/>
    <language>en</language>
    <item>
      <title>ToolJet x Hacktoberfest'22</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Fri, 30 Sep 2022 10:43:09 +0000</pubDate>
      <link>https://forem.com/tooljet/tooljet-x-hacktoberfest22-5bf2</link>
      <guid>https://forem.com/tooljet/tooljet-x-hacktoberfest22-5bf2</guid>
      <description>&lt;p&gt;It is October again!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In open source, we feel strongly that to really do something well, you have to get a lot of people involved - &lt;a href="https://en.wikipedia.org/wiki/Linus_Torvalds" rel="noopener noreferrer"&gt;Linus Torvalds&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hacktoberfest is a one-month event that encourages &lt;del&gt;developers&lt;/del&gt; everyone to contribute to the open-source projects that they love. We are excited to announce that ToolJet will be participating in Hacktoberfest 2022.&lt;/p&gt;

&lt;p&gt;ToolJet is an open-source low-code platform for building internal tools. We open-sourced ToolJet in June 2021. We have more than 13,000 stars and 200 contributors for our GitHub repository. The open-source community consistently help us improve ToolJet by contributing new features, reporting &amp;amp; fixing bugs, improving the documentation, helping us debug the bugs, and more.  &lt;/p&gt;

&lt;p&gt;Before we dive in to the details of Hacktoberfest 2022, let's quickly recap of last year's Hacktoberfest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2Fimage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2Fimage.png" alt="stats" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We merged 159 pull requests from 72 new contributors during Hacktoberfest 2021.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacktoberfest 2022
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest is an opportunity for everyone to get involved in open-source projects.&lt;/p&gt;

&lt;p&gt;With great opportunity comes great swag. Every valid PR is eligible for ToolJet swags!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1 valid PR&lt;/strong&gt;: ToolJet stickers and t-shirt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 valid PRs&lt;/strong&gt; - ToolJet stickers, t-shirt, water bottle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 valid PRs&lt;/strong&gt; - ToolJet stickers, t-shirt, hoodie, water bottle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Additionally, the top 5 contributors will get a surprise gift this time!&lt;/strong&gt; 🥳&lt;/p&gt;

&lt;h3&gt;
  
  
  How to participate
&lt;/h3&gt;

&lt;p&gt;Every contribution matters. It can be bug fixes, new features, new plugins, code refactoring, improving the documentation, creating tutorials, adding more unit tests etc.&lt;/p&gt;

&lt;p&gt;Not familiar with our codebase? no problem, we have tagged issues on Github with the label &lt;code&gt;good first issue&lt;/code&gt; . You can view them here: &lt;a href="https://github.com/ToolJet/ToolJet/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22" rel="noopener noreferrer"&gt;issues for newcomers&lt;/a&gt;. Additionally, we've added labels for the frontend (ReactJS) and backend (NestJS). Please make sure that you are creating PR only for issues that are assigned to you.&lt;/p&gt;

&lt;p&gt;We do not tolerate spamming. If you're finding it difficult to contribute code, you can still help by reporting spam PRs, which are PRs created just for the sake of creating PRs. Spam PRs should be labeled as &lt;code&gt;spam&lt;/code&gt; or &lt;code&gt;invalid&lt;/code&gt; as per the guidelines of Hacktoberfest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.tooljet.io/docs/contributing-guide/setup/docker" rel="noopener noreferrer"&gt;Setting up local dev environment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.tooljet.com/hacktoberfest-2022/Contributing%20guide.%20https://github.com/ToolJet/ToolJet/blob/develop/CONTRIBUTING.md" rel="noopener noreferrer"&gt;Contributing guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hacktoberfest.com/" rel="noopener noreferrer"&gt;Hacktoberfest resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where to get help during Hacktoberfest
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have a very active community on Slack. Feel free to join: &lt;a href="https://tooljet.com/slack" rel="noopener noreferrer"&gt;https://tooljet.com/slack.&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can email us at &lt;a href="mailto:hello@tooljet.com"&gt;hello@tooljet.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking forward to see you on GitHub!🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>From zero to 10,000 stars and 160 contributors on GitHub</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Mon, 16 May 2022 12:10:29 +0000</pubDate>
      <link>https://forem.com/tooljet/from-zero-to-10000-stars-and-160-contributors-on-github-3057</link>
      <guid>https://forem.com/tooljet/from-zero-to-10000-stars-and-160-contributors-on-github-3057</guid>
      <description>&lt;p&gt;We are excited to announce that our GitHub repository crossed 10,000 stargazers. It has been an amazing journey building ToolJet alongside our energetic and involved community. In this article, we will discuss about our learnings from this fast-paced journey of building an open-source product that the community loves.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those who haven't heard about &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt;, ToolJet is an open-source low-code framework for building custom internal tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first commit to our GitHub repository was on March 31, 2021, and we made the repository public on June 7, 2021, and &lt;a href="https://news.ycombinator.com/item?id=27421408" rel="noopener noreferrer"&gt;launched it on Hackernews&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our journey since we made our repository public!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F05%2Fs6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F05%2Fs6.png" alt="milestone" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  April 2021
&lt;/h3&gt;

&lt;p&gt;The first commit to the repository was on March 31st, 2021. Most of the April was spent on pushing more and more commits to the repository. Major challenges were to get the drag and drop builder working.&lt;/p&gt;

&lt;p&gt;ToolJet's POC looked like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F05%2Fs2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F05%2Fs2.png" alt="april2021" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and then improved to this at the end of April:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F05%2Fs3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F05%2Fs3.png" alt="april2021end" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  May 2021
&lt;/h3&gt;

&lt;p&gt;I reached out to a few companies that I had relationships with to try out ToolJet and worked more on iterating ToolJet based their feedback. Some of my friends also stepped in to help build ToolJet by contributing to the repository. At this point, the repository was private.&lt;/p&gt;

&lt;p&gt;At the beginning of  May, I tried to reach out to angel investors/VC firms and applied for Y Combinator but everyone rejected since there was no traction to convince the idea. I've written about this in detail in this article: &lt;a href="https://blog.tooljet.com/building-and-launching-tooljet/" rel="noopener noreferrer"&gt;Building and launching ToolJet&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  June 2021: The launch of public beta &amp;amp; fundraising.
&lt;/h3&gt;

&lt;p&gt;Building the website, creating graphics for posting on ProductHunt and finding a hunter was done in the last week of May and first week of June.&lt;/p&gt;

&lt;p&gt;ToolJet was launched on ProductHunt first and then a few hours later on Hacker News. &lt;a href="https://www.producthunt.com/posts/tooljet-0-5-3" rel="noopener noreferrer"&gt;ProductHunt post&lt;/a&gt; was among the top 5 of the day within a few minutes and later ended up being &lt;strong&gt;#1 product of the day&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now we have some inbound interest from VC firms since we got the initial traction that we needed to convince that this is an idea worth pursuing. Now the challenge is to find investors who understand developer tools and open-source. Long story short ( because we have another article that explains why we raised funding and how did we chose the partners - &lt;a href="https://blog.tooljet.com/raising-vc-funding-for-open-source-project/" rel="noopener noreferrer"&gt;link&lt;/a&gt; ), we were lucky that we quickly found &lt;a href="https://nexusvp.com/" rel="noopener noreferrer"&gt;Nexus&lt;/a&gt; interested in leading our seed round. They had great experience in developer tools and open-source as they were the early investors in companies like Hasura, Min.io and Postman.&lt;/p&gt;

&lt;p&gt;We also managed to onboard two other VC firms and a few angel investors. We did not try to get more termsheets or reach out to more firms as we were optimising for quickly closing the round so that we can go back to building ToolJet. In the end, we raised a $1.55 million seed round.&lt;/p&gt;

&lt;p&gt;Decision to go ahead with VC funding helped us in many ways, will write about it in in detail in the coming weeks.&lt;/p&gt;
&lt;h3&gt;
  
  
  July 2021: The importance of stack in open-source.
&lt;/h3&gt;

&lt;p&gt;ToolJet server was initially built using Ruby ( Ruby on Rails ) and ToolJet client was built using ReactJS. Having two languages ( Ruby and JavaScript ) in the codebase was a barrier for many to contribute to ToolJet. The suggestion of choosing the right stack and a plugin-based architecture for an open-source project came up when I had a chance to talk to Tanmai Gopal, co-founder of &lt;a href="https://hasura.io/" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since ToolJet was still in it's early stages, we decided to port the server completely to JavaScript/TypeScript. The whole process took around 6 weeks but it helped us change the architecture to make the server modular. It was a difficult decision to stop working on new features and spend more than a month on migration but this decision paid off in the long run.&lt;/p&gt;

&lt;p&gt;We've written in detail about this on our blog:&lt;br&gt;
&lt;a href="https://blog.tooljet.com/migrating-toojet-from-ruby-on-rails-to-nodejs/" rel="noopener noreferrer"&gt;Part1: Why we are migrating to Node.js&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.tooljet.com/how-we-migrated-tooljet-server-from-ruby-to-node-js/" rel="noopener noreferrer"&gt;Part2: How we migrated from Rails to NestJS&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  August &amp;amp; September 2021: Building the team.
&lt;/h3&gt;

&lt;p&gt;We hired our first four engineers in July and onboarded them in August. The first 15-20 team members sets the culture of the company and thus we were focusing more on culture and less on experience in Node.js. We managed to hire senior engineers from our networks as well as from hiring platforms.&lt;/p&gt;
&lt;h3&gt;
  
  
  The rest of 2021
&lt;/h3&gt;

&lt;p&gt;In the last quarter of 2021, we managed to ship a bunch of major features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Team collaboration features: users can comment anywhere on canvas and tag other team members.&lt;/li&gt;
&lt;li&gt;Ability to run JavaScript from within ToolJet.&lt;/li&gt;
&lt;li&gt;Application template library for users to get started easily.&lt;/li&gt;
&lt;li&gt;Connectors for cloud storages such as AWS S3, GCS &amp;amp; Min.io.&lt;/li&gt;
&lt;li&gt;Ability to export applications and import them into different environments.&lt;/li&gt;
&lt;li&gt;Permissions based on user groups.&lt;/li&gt;
&lt;li&gt;Support for authentication using Google SSO.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During this time, our GitHub repository crossed 4,000 stargazers &amp;amp; 100 contributors. We also added the first developer advocate to the team to address the needs of our growing community.&lt;/p&gt;
&lt;h3&gt;
  
  
  January 2022: De-coupling connectors as plugins &amp;amp; preparing for v1.0 launch.
&lt;/h3&gt;

&lt;p&gt;The initial version of ToolJet did not have the concept of plugins and every connector lived in the codebase. When we migrated to Node.js, the logic for connectors was abstracted into a &lt;code&gt;**plugins**&lt;/code&gt; folder within the directory for ToolJet server in the codebase.&lt;/p&gt;

&lt;p&gt;We soon realised that it will not be possible to scale connectors if they had to live within the codebase. Having hundreds of connectors can slow down the server and most of the users will not need more than 5 connectors.&lt;/p&gt;

&lt;p&gt;Majority of the low-code frameworks have very less number of connectors and often the long tail of connectors are ignored. We wanted to chase this long tail of connectors and also give users the ability to quickly build connectors as per their requirements.&lt;/p&gt;

&lt;p&gt;We decided to de-couple the connectors from the codebase as plugins and built a &lt;strong&gt;Plugin Development Kit&lt;/strong&gt; for the community to easily build plugins.&lt;/p&gt;

&lt;p&gt;Now the connectors can stay completely outside the codebase and these plugins can be easily bootstrapped using &lt;code&gt;tooljet-cli&lt;/code&gt; (&lt;a href="https://www.npmjs.com/package/@tooljet/cli" rel="noopener noreferrer"&gt;link&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We also decided to launch ToolJet v1.0 in February. ToolJet was being used by many large organisations in production since last few months but we did not want to call it a v1.0 unless we've de-coupled the plugins.&lt;/p&gt;

&lt;p&gt;In January, we smashed numerous bugs and user experience issues that were causing trouble to the users. We also spent time on adding more templates to our template library, adding more ways to deploy ToolJet on premises, support for more SSO providers, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  February: Launching v1.0
&lt;/h3&gt;

&lt;p&gt;On February 8th, we released ToolJet v1.0 and launched it on &lt;a href="https://www.producthunt.com/posts/tooljet-2" rel="noopener noreferrer"&gt;ProductHunt&lt;/a&gt;. Having the beta tag prevented many organisations from using ToolJet as beta is often read as "not stable, expect bugs". Now this issue is resolved!&lt;/p&gt;

&lt;p&gt;We've written in detail about the changes that we've made in v1.0 &lt;a href="https://blog.tooljet.com/announcing-tooljet-v1/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;We did not stop there, we shipped a lot of other features in February such as integrations with Snowflake, n8n, etc. Majority of our time was being spent on feature requests and bug reports from the community at this point.&lt;/p&gt;

&lt;p&gt;We also crossed 5,000 stars in February!&lt;/p&gt;

&lt;h3&gt;
  
  
  March: Meeting the team in person for the first time
&lt;/h3&gt;

&lt;p&gt;We've grown into a team of 12 at this point but most of the team members haven't met the others in person. Our plan was to organise team meetups every quarter but the covid situation did not let us do that until now. We spent a week in Goa, India collaborating and brainstorming on different features. It was exciting to meet the people with whom you talk on a daily basis ( mostly texts because we prefer asynchronous communication ) but never got a chance to meet in person.&lt;/p&gt;

&lt;p&gt;During this month, we were focusing on three main things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support for multiplayer editing.&lt;/li&gt;
&lt;li&gt;Ability to have multiple workspaces within ToolJet.&lt;/li&gt;
&lt;li&gt;More connectors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  April: ToolJet now supports multiplayer editing &amp;amp; custom React components
&lt;/h3&gt;

&lt;p&gt;At this point, large teams that were using ToolJet started facing issues because only one user will be able to edit an application at a given time. We started looking into making ToolJet a collaborative workspace. Figma has done this well and have also documented how they did it (&lt;a href="https://www.figma.com/blog/how-figmas-multiplayer-technology-works/" rel="noopener noreferrer"&gt;link&lt;/a&gt;). This resource was very helpful for us. Here is our article explaining a POC built using CRDTs: &lt;a href="https://blog.tooljet.com/multiplayer-tic-tac-toe-using-react-crdt-yjs/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We've also added support for bringing your own React components to ToolJet. Low-code frameworks are not known for their flexibility but now with ToolJet, you can bring your own React components, create connectors using our plugin development kit and even create JavaScript snippets and run them from within ToolJet. That covers almost all areas where a user will need flexibility.&lt;/p&gt;

&lt;p&gt;We also added support for multiple workspaces within ToolJet. Users can now be part of different workspaces and the workspaces can have their own SSO configurations.&lt;/p&gt;

&lt;p&gt;During this period, we also crossed 150 contributors on GitHub!&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;We also made it to #2 among the fastest growing open-source startups. &lt;a href="https://runacap.com/ross-index/q1-2022/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F05%2Fimage-18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F05%2Fimage-18.png" alt="topopensource" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What did we learn from this journey?
&lt;/h3&gt;

&lt;p&gt;Getting product-community fit is crucial for any open-source startup. We have been working closely with our community to understand their needs and improve accordingly and it worked well for us. Moving forward, we are allocating more resources to help the community. This involves providing better support through our Slack group, faster turnaround times for issues &amp;amp; pull requests, creating more content for the community to get started easily, creating more short reference videos and articles on how to use ToolJet, organising more community events and more!&lt;/p&gt;

&lt;h3&gt;
  
  
  What's going on and what's next?
&lt;/h3&gt;

&lt;p&gt;We believe we are still in the early days of ToolJet. A lot of things can be done that helps to get lot more things done using ToolJet. We are working on shipping more connectors and more complicated UI widgets. But that's not all, we are working on major features such as syncing applications with GitHub, support for even more SSO providers, improving query builders, making plugins installable, etc. We've a public roadmap &lt;a href="https://github.com/ToolJet/ToolJet/projects/2" rel="noopener noreferrer"&gt;here&lt;/a&gt;  that captures what's going to be built over the next few months.&lt;/p&gt;

&lt;p&gt;In short, we want to improve the productivity of developers by letting them build complicated business applications, internal tools and workflows with very minimal engineering effort. For this, we are expanding our engineering, product and community teams at the moment.&lt;/p&gt;

&lt;p&gt;Stay tuned for more exciting updates in the coming weeks. We write this at the end of every article but we have also kept that promise by releasing a new and improved version of ToolJet every other week!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>showdev</category>
      <category>github</category>
      <category>react</category>
    </item>
    <item>
      <title>Announcing ToolJet 1.0 - separating the platform from the product</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Tue, 08 Feb 2022 10:57:54 +0000</pubDate>
      <link>https://forem.com/tooljet/announcing-tooljet-10-separating-the-platform-from-the-product-2324</link>
      <guid>https://forem.com/tooljet/announcing-tooljet-10-separating-the-platform-from-the-product-2324</guid>
      <description>&lt;p&gt;&lt;strong&gt;We launched the public beta of ToolJet in June 2021. Today, we are excited to release the ToolJet 1.0.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F02%2FScreenshot-2022-02-05-at-16.12.40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F02%2FScreenshot-2022-02-05-at-16.12.40.png" alt="Tooljet-ui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What were we waiting for?
&lt;/h3&gt;

&lt;p&gt;A lot of users are using ToolJet on production environments since August and the platform did not show any stability or scalability issues. We were waiting for wrapping up one major feature before we call it 1.0.&lt;/p&gt;

&lt;p&gt;We are today making public the &lt;code&gt;ToolJet developer platform&lt;/code&gt; along with &lt;code&gt;tooljet&lt;/code&gt; command-line tool. ToolJet developer platform allows any JavaScript developer to build and publish plugins for ToolJet. For this phase one, developers will be able to build connectors for ToolJet. For example, building a ToolJet connector for BigQuery takes only 30 minutes including integration tests.&lt;/p&gt;

&lt;p&gt;We made this possible with the help of our command-line tool  &lt;code&gt;tooljet&lt;/code&gt;. Our command-line tool can bootstrap the file structure for plugins, add npm dependencies for the plugins and even run tests for specific plugins.&lt;/p&gt;

&lt;p&gt;Since our launch, we have been getting a lot of contributions from developers around the world. Our developer platform will make it easy for any JavaScript developer to extend ToolJet using plugins. This was one of the reasons for us &lt;a href="https://blog.tooljet.com/how-we-migrated-tooljet-server-from-ruby-to-node-js/" rel="noopener noreferrer"&gt;migrating the ToolJet server from Ruby to Node.js&lt;/a&gt; last year. We wanted to open up our platform for the growing JavaScript community.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F01%2Fimage-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F01%2Fimage-9.png" alt="top-language-graph" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plugins are useful for our users as they do not have to wait for the core team to build the connectors that they need. Imagine using a closed source product where the users are at the mercy of the company to build features and fix bugs. Will they even care if the extension will not be used by the majority of their customers?&lt;/p&gt;

&lt;h3&gt;
  
  
  What else is new and what changed since the beta launch?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;a) Ported ToolJet server from Ruby to Node.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, the server was built using Ruby when we launched ToolJet first. Right after the launch, we ported the server to Node.js. This has helped us leverage the contributions of the amazing and active JavaScript community. This has also helped us build the developer platform for a larger number of developers. We've written in detail about this in another blog post.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JavaScript is the most popular language of 2021.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-&lt;a href="https://www.jetbrains.com/lp/devecosystem-2021/" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b) Plugin based architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We altered the architecture to support extensibility. We built a plugin system so that any JavaScript developer will be able to extend ToolJet easily. For example, a simple plugin for connecting ToolJet with BigQuery can be built in less than 30 minutes.&lt;/p&gt;

&lt;p&gt;We believe our open-source and plugin-based approach helps the engineering teams to customise our low-code framework as per their requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;c) Team collaboration features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real-time collaboration between the team members is now possible with the conversations feature of ToolJet. Users can now tag their team members and comment on the canvas to collaborate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;d) Templates by ToolJet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you can choose from dozens of templates instead of creating applications from scratch. Templates even include full-fledged database viewer apps for PostgreSQL and MySQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;e) More data sources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We launched first with 7 data sources. Now we have integrations with more than 20 data sources. We've even added support for cloud storage like AWS S3, Google Cloud Storage and Minio. But that's not all, our new architecture will enable us to build and test new data sources easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;f) More UI widgets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We launched a public beta with 12 UI widgets. Now we have more than 35 widgets. We now have widgets for picking files, list layout, pagination, timer, tags and statistic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;g) Better application builder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We redesigned the application builder to make it super easy to use. We've also added a bunch of keyboard shortcuts for actions like undo, redo, delete widget and more. The focus of the redesign was the usability of the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;h) Support for running custom JavaScript snippets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can now run JavaScript code from within ToolJet. This adds to the flexibility of the framework. Libraries like momentjs, papaparse, lodash, etc are supported within the snippets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;i) Debugger&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Runtime errors that happen in your applications are now logged in the debugger. If a query failed or if a widget ran into an error, you can debug it easily using the debugger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;j) User groups and permissions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Permissions for every app and actions like user creation, folder creation, etc can now be controlled on a user group level as well as on an organization level.&lt;/p&gt;

&lt;p&gt;And obviously a lot of many other features, bug fixes and improvements. But that's not all, exciting new features will be released in the coming weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checkout ToolJet v1 on GitHub&lt;/strong&gt; — &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>12 ways to get more GitHub stars for your open-source project</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Mon, 17 Jan 2022 06:47:45 +0000</pubDate>
      <link>https://forem.com/tooljet/12-ways-to-get-more-github-stars-for-your-open-source-project-16ml</link>
      <guid>https://forem.com/tooljet/12-ways-to-get-more-github-stars-for-your-open-source-project-16ml</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The steps that we took to grow from 0 to 4,500 stars on GitHub within a few months.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We launched ToolJet (&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;) in June 2021, since then we've got &lt;strong&gt;more than 4500 stars&lt;/strong&gt; for our repository. Here is a list of things that worked for us. This is not an article about how to just get more stars for your repository. The article instead explains how to present your project well so that it is helpful for the open-source community. Some of these points have helped us get contributions from more developers, we have contributions from more than 100 developers now.&lt;/p&gt;

&lt;p&gt;PS: The graph above was generated using an app built with ToolJet. You can use it here to generate a star history chart for your project - &lt;a href="https://apps.tooljet.com/github-star-history" rel="noopener noreferrer"&gt;https://apps.tooljet.com/github-star-history&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Readme matters
&lt;/h2&gt;

&lt;p&gt;Readme is the first thing that a visitor to your repository sees. The readme should be able to convey what your project does, how to install the project, how to deploy the project ( if applicable ), how to contribute and how it works. Also, use badges that are helpful for the developers. We used &lt;a href="https://shields.io/" rel="noopener noreferrer"&gt;https://shields.io/&lt;/a&gt; for adding badges to our Readme.&lt;/p&gt;

&lt;p&gt;Here is how our Readme looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-1.png" alt="readme-matters" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examples of projects with great Readme:&lt;br&gt;
a) &lt;a href="https://github.com/nestjs/nest" rel="noopener noreferrer"&gt;https://github.com/nestjs/nest&lt;/a&gt;&lt;br&gt;
b) &lt;a href="https://github.com/typesense/typesense" rel="noopener noreferrer"&gt;https://github.com/typesense/typesense&lt;/a&gt;&lt;br&gt;
c) &lt;a href="https://github.com/airbytehq/airbyte" rel="noopener noreferrer"&gt;https://github.com/airbytehq/airbyte&lt;/a&gt;&lt;br&gt;
d) &lt;a href="https://github.com/strapi/strapi" rel="noopener noreferrer"&gt;https://github.com/strapi/strapi&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Documentation
&lt;/h2&gt;

&lt;p&gt;We get more traffic to our documentation portal (&lt;a href="https://docs.tooljet.com/" rel="noopener noreferrer"&gt;https://docs.tooljet.com/&lt;/a&gt;) than our main website. A well-documented project is always loved by the community. Open-source projects like &lt;a href="https://github.com/facebook/docusaurus/" rel="noopener noreferrer"&gt;Docusaurus&lt;/a&gt; makes it super easy to build documentation portals that look great just out of the box. Adding links to the repository from the documentation can drive more visitors to your repository.&lt;/p&gt;

&lt;p&gt;Here are some projects with great documentation:&lt;br&gt;
a) &lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;https://docs.nestjs.com/&lt;/a&gt;&lt;br&gt;
b) &lt;a href="https://docs.n8n.io/" rel="noopener noreferrer"&gt;https://docs.n8n.io/&lt;/a&gt;&lt;br&gt;
c) &lt;a href="https://guides.rubyonrails.org/" rel="noopener noreferrer"&gt;https://guides.rubyonrails.org/&lt;/a&gt;&lt;br&gt;
d) &lt;a href="https://plotly.com/python/" rel="noopener noreferrer"&gt;https://plotly.com/python/&lt;/a&gt;&lt;br&gt;
e) &lt;a href="https://docs.mapbox.com/" rel="noopener noreferrer"&gt;https://docs.mapbox.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Drive visitors from your website to GitHub
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F01%2Fimage-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F01%2Fimage-6.png" alt="drive-visitors" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of visitors checked out our repository after visiting our website first. Add banners, badges, etc to your website so that the website visitors will check out your repository. To drive more visitors to your website, writing blog posts about relevant topics helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  4) Be active in developer communities
&lt;/h2&gt;

&lt;p&gt;There are many discord/slack communities, forums, Reddit communities, etc where developers usually hang out. Be active in these communities without making it look like self-promotion ( which can get you banned for obvious reasons ). Try to add value to the communities by participating in relevant discussions. For example, if you are building a charting library and if someone is asking a question about plotting charts using React, you can pitch in to help.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Play nice. Do not try to link to your project if it does not add any value to the discussion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5) Email campaigns
&lt;/h2&gt;

&lt;p&gt;You might already have users signed up for your website. Add a link to your GitHub repository in the welcome email.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not spam people who haven't signed up for your updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6) Trending repositories on GitHub
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-4.png" alt="trending-repositories" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you make it to the list of trending GitHub repositories ( &lt;a href="https://github.com/trending?since=daily" rel="noopener noreferrer"&gt;https://github.com/trending?since=daily&lt;/a&gt; ), it can get your repository a lot more visibility. Whenever we made it to the trending list, we always got more visitors to our repository and website. There are trending lists for specific languages too. Many Twitter bots and other tools notify developers whenever there is a new repository that has made it to the trending list.&lt;/p&gt;

&lt;h2&gt;
  
  
  7) Ask for feedback from relevant communities
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1000%2F2022%2F01%2Fimage-5.png" alt="ask-for-feedback" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Communities such as &lt;a href="https://www.producthunt.com/posts/tooljet" rel="noopener noreferrer"&gt;ProductHunt&lt;/a&gt;, &lt;a href="https://news.ycombinator.com/item?id=27421408" rel="noopener noreferrer"&gt;Hackernews&lt;/a&gt;, Reddit communities, etc may find your project useful. This can bring in more visitors and stargazers to your repository.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Target only the relevant communities. If you think majority of the members won't find your project interesting, it is not a relevant community. Spamming can cause more harm than good. Also, it's just not nice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  8) Grow a community
&lt;/h2&gt;

&lt;p&gt;Start a community on Discord or Slack for your users and contributors to hang out. Communities can be helpful when the members are stuck with something and if they want to propose something new. If there is an active community, your future posts and announcements might get more reach. We created the community on Slack since most of the developers have a Slack account. Do not use lesser-known platforms for building your community as it would take an additional step for the person to join the community.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Play nice. Appreciate the work of others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  9) Add a public roadmap
&lt;/h2&gt;

&lt;p&gt;A public roadmap helps your users and contributors understand where your project is headed. There are many tools available for creating public roadmaps but in most cases, GitHub projects will be more than enough for creating a simple yet effective public roadmap. We have created one using GitHub projects - &lt;a href="https://github.com/ToolJet/ToolJet/projects/2" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet/projects/2&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10) Twitter
&lt;/h2&gt;

&lt;p&gt;Being active on posts related to your projects can create awareness, increase the number of followers on Twitter and drive more visitors to your repository. Make sure to link your repository on the project's Twitter profile. Also, add a tweet button to your GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  11) Respond to feedback
&lt;/h2&gt;

&lt;p&gt;Open-source communities are usually very helpful and give a lot of feedback. Respond to all this feedbacks as the person has taken their valuable time to help you improve your project. Positive feedback helps you stay motivated while negative feedback helps you rethink.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not try to evade negative feedback, work on it if it aligns with your vision, otherwise politely explain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  12) Add relevant labels for contributors
&lt;/h2&gt;

&lt;p&gt;Adding labels such as "good first issue" and "up for grabs" can attract more contributors to your repository. There are many platforms such as &lt;a href="https://goodfirstissue.dev/" rel="noopener noreferrer"&gt;https://goodfirstissue.dev/&lt;/a&gt; that scans for issues tagged with relevant labels to help contributors discover new repositories and issues to contribute to. Make sure you respond to contributors quickly. Contributors can be experienced developers as well as developers in the early stages of their careers or students. Try to help the first time contributors to help them onboard easily.&lt;/p&gt;

&lt;p&gt;You landed on this article possibly because you have an interesting open-source project. I'd love to see your project. I'm available at &lt;a href="mailto:navaneeth@tooljet.com"&gt;navaneeth@tooljet.com&lt;/a&gt; and on &lt;a href="https://twitter.com/navaneeth_pk" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope this article was helpful for you. We would really appreciate it if you can take a moment to give us feedback on ToolJet - &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>github</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Deploying a NestJS application with PostgreSQL database and react frontend on Heroku</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Fri, 30 Jul 2021 03:43:15 +0000</pubDate>
      <link>https://forem.com/navaneethpk/deploying-a-nestjs-application-with-postgresql-database-and-react-frontend-on-heroku-3ce</link>
      <guid>https://forem.com/navaneethpk/deploying-a-nestjs-application-with-postgresql-database-and-react-frontend-on-heroku-3ce</guid>
      <description>&lt;p&gt;Recently, we ported the &lt;a href="https://github.com/ToolJet/ToolJet"&gt;ToolJet&lt;/a&gt; server from Ruby on Rails to NestJS, ToolJet can be deployed to Heroku using the one-click deployment feature of Heroku. ToolJet server is built using Nest.js with TypeORM as the ORM and PostgreSQL as the database. This article will explain how to deploy a NestJS API application on Heroku using the one-click deployment feature of Heroku.&lt;/p&gt;

&lt;p&gt;Many of our users deploy the frontend and backend separately, the backend might be deployed on Heroku/K8S/EC2 while the frontend is served from Firebase/Netlify/etc. The first part of this guide explains how to deploy a NestJS API to Heroku and the last part explains how to deploy the frontend too.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Create app.json file in the root directory of your repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ToolJet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ToolJet is an open-source low-code framework to build and deploy internal tools."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://tooljet.io/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/tooljet/tooljet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"logo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://app.tooljet.io/assets/images/logo.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"predeploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm install &amp;amp;&amp;amp; npm run build"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"NODE_ENV"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Environment [production/development]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"formation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"heroku/nodejs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"addons"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"heroku-postgresql"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"buildpacks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"heroku/nodejs"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Environment variables, add-ons, buildpacks and other information about the app needs to be added to the app.json file. More details about the app.json manifest can be found &lt;a href="https://devcenter.heroku.com/articles/app-json-schema#stack"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using the predeploy hook, we are installing the npm packages required for the application and then build the application. &lt;code&gt;npm run build&lt;/code&gt; runs the nest build command. More details about nest build can be found &lt;a href="https://docs.nestjs.com/cli/usages#nest-build"&gt;here&lt;/a&gt;.We have also added &lt;code&gt;heroku-postgresql&lt;/code&gt; to the addons so that a Postgres database will be provisioned by Heroku. &lt;/p&gt;

&lt;h3&gt;
  
  
  2) Listen to the port assigned by Heroku
&lt;/h3&gt;

&lt;p&gt;Heroku dynamically assigns a port for your app. We need to make sure that the application is listening to requests on the port assigned by Heroku.  Modify the &lt;code&gt;main.ts&lt;/code&gt; file to listen to the port assigned by Heroku and fallback to 3000. We also need to set 0.0.0.0 as the binding address.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.listen(parseInt(process.env.PORT, '0.0.0.0') || 3000);&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Note: you will come across the following error if the application is listening on a different port. Error R10 (Boot timeout) -&amp;gt; Web process failed to bind to $PORT within 60 seconds of launch &lt;/p&gt;

&lt;h3&gt;
  
  
  3) Configuring TypeORM to use Postgres database provisioned by Heroku
&lt;/h3&gt;

&lt;p&gt;Add the following options to your &lt;code&gt;ormconfig(.json/.ts/.js)&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;url: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;DATABASE_URL&lt;/code&gt; config variable is added to your app's environment if a Postgres resource is provisioned for your app. Without setting the &lt;code&gt;rejectUnauthorizedoption&lt;/code&gt; as false, Error: self signed certificate will be thrown by the application (the reason is explained &lt;a href="https://stackoverflow.com/questions/61097695/self-signed-certificate-error-during-query-the-heroku-hosted-postgres-database"&gt;here&lt;/a&gt;). &lt;/p&gt;

&lt;h3&gt;
  
  
  4) Procfile
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;web: npm run start:prod&lt;/code&gt; as a new line to Procfile. We are assuming that the start:prod script is defined in package.json as &lt;code&gt;NODE_ENV=production node dist/src/main&lt;/code&gt;. TypeORM migrations can be run after every release. &lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;release: npm run typeorm migration:run&lt;/code&gt; as a new line to your Procfile. The Procfile will now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: npm run start:prod
release: npm run typeorm migration:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5) Deploy!
&lt;/h3&gt;

&lt;p&gt;You can visit &lt;a href="https://heroku.com/deploy?template=https://github.com/your-organization/your-repository/tree/your-branch"&gt;https://heroku.com/deploy?template=https://github.com/your-organization/your-repository/tree/your-branch&lt;/a&gt; to deploy the application using the one-click deployment feature of Heroku.&lt;/p&gt;

&lt;p&gt;If you want to deploy just NestJS API on Heroku, you can stop reading this guide. If you want to deploy the frontend too to Heroku, please continue. &lt;/p&gt;

&lt;p&gt;In the following steps, we will explain how to make NestJS serve a React single page application. We are assuming that the React application lives under the frontend directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Install serve-static NestJS plugin
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @nestjs/serve-static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Modify AppModule
&lt;/h3&gt;

&lt;p&gt;Add this to the imports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ServeStaticModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;rootPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;frontend/build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3) Routing
&lt;/h3&gt;

&lt;p&gt;Now the NestJS will serve  index.html in the build directory of the frontend. This can be a problem when there are similar routes on the frontend and backend. For example, if the frontend application's path for users page is /users and the path to fetch users from the backend is also the same, NestJS will not serve the static files for that path. To solve this issue, let's add a prefix to the backend endpoints.&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setGlobalPrefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line needs to be added to &lt;code&gt;main.ts&lt;/code&gt; to make sure the path for all API requests starts with api. For example: &lt;a href="http://localhost/api/users"&gt;http://localhost/api/users&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Build the frontend while deploying to Heroku
&lt;/h3&gt;

&lt;p&gt;We need to build the frontend for production to generate the build folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm --prefix frontend install &amp;amp;&amp;amp; NODE_ENV=production npm --prefix frontend run build &amp;amp;&amp;amp; npm --prefix server install &amp;amp;&amp;amp; NODE_ENV=production npm --prefix server run build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a frontend/build/. public/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"heroku-postbuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build &amp;amp;&amp;amp; npm run deploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"heroku-prebuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm --prefix frontend install &amp;amp;&amp;amp; npm --prefix server install "&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this to the package.json on the root directory of the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  5) Deploy!
&lt;/h3&gt;

&lt;p&gt;You can visit &lt;a href="https://heroku.com/deploy?template=https://github.com/your-organization/your-repository/tree/your-branch"&gt;https://heroku.com/deploy?template=https://github.com/your-organization/your-repository/tree/your-branch&lt;/a&gt; to deploy the application using the one-click deployment feature of Heroku.&lt;br&gt;
We would love you to check out ToolJet on GitHub: &lt;a href="https://github.com/ToolJet/ToolJet/"&gt;https://github.com/ToolJet/ToolJet/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>react</category>
      <category>heroku</category>
      <category>typeorm</category>
    </item>
    <item>
      <title>Migrating ToolJet server from Ruby on Rails to Node.js</title>
      <dc:creator>Navaneeth Pk</dc:creator>
      <pubDate>Tue, 13 Jul 2021 11:47:15 +0000</pubDate>
      <link>https://forem.com/navaneethpk/migrating-tooljet-server-from-ruby-on-rails-to-node-js-fb</link>
      <guid>https://forem.com/navaneethpk/migrating-tooljet-server-from-ruby-on-rails-to-node-js-fb</guid>
      <description>&lt;h2&gt;
  
  
  The background
&lt;/h2&gt;

&lt;p&gt;We recently open-sourced (ToolJet)[&lt;a href="https://github.com/ToolJet/ToolJet/"&gt;https://github.com/ToolJet/ToolJet/&lt;/a&gt;]. ToolJet is an open-source no-code platform for building and deploying custom internal tools.&lt;/p&gt;

&lt;p&gt;ToolJet has two main components, the client and the server. ToolJet client is a ReactJS application and ToolJet server is a Ruby on Rails API-only application. Whenever a new application is built using ToolJet, the frontend ( client ) generates the definition of the app in JSON and the server persists the versioned definitions on a PostgreSQL database. The server also acts as a proxy that run queries on top of the data sources ( data sources in ToolJet includes databases like MongoDB and API based services like Google Sheets ). &lt;/p&gt;

&lt;p&gt;Ruby accounts for only 14.5% of our codebase. When we built ToolJet, we chose Ruby on Rails as the backend because of its ability to quickly prototype and iterate due to its strong adherence to ‘convention over configuration’.&lt;/p&gt;

&lt;p&gt;We open-sourced ToolJet with the eventual goal of letting everyone build plugins ( database integrations, API integrations &amp;amp; UI widgets ) for ToolJet easily. But with the current architecture, if a developer wants to build a new data source integration for  ToolJet, he/she should be familiar with both Ruby and JavaScript because running queries is handled by Rails and building queries is handled by query editors in the ReactJS frontend. Thus when we migrate the server to Node.js, the developers will be able to build ToolJet plugins using just one language. &lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript
&lt;/h2&gt;

&lt;p&gt;The popularity of TypeScript has been exploding in recent years ( JavaScript Flavors ). TypeScript is a superset of JavaScript and provides an optional type system for JavaScript. The freedom of dynamic typing can cause bugs that are hard to detect. With TypeScript, you can avoid classic JS errors like undefined is not a function. We decided to use TypeScript as it helps us to avoid mundane errors and to improve the maintainability of our codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript analysis paralysis
&lt;/h2&gt;

&lt;p&gt;It's real! &lt;br&gt;
In the Rails world, everything is already decided for you. But in the Node.js world, there is an endless possibility of file structures, naming conventions and tooling. For example, in Rails, we used ActiveRecord but in Node.js, we get to ( or have to) choose ORM ( if any ). When we started looking for a suitable Node.js backend framework. A huge range of frameworks was available to choose from. This can lead to Choice Paralysis but on the bright side, having too many options at our disposal helps us choose what's best for our use case. &lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the framework
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SailsJS
&lt;/h3&gt;

&lt;p&gt;Since we are migrating from Ruby on Rails, SailsJS was the obvious choice because of its similarity with Rails. We decided not to use SailsJs when we came across issues raised by developers related to the built-in ORM, waterline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Express
&lt;/h3&gt;

&lt;p&gt;Express is a very minimal yet powerful framework. Express, being an un-opinionated framework, doesn't come with an error handler, body-parser etc. This gives the developer a lot of freedom but with a lot of freedom comes a lot of responsibilities to choose the right way to do something. We did not want to spend a lot of time discussing what framework to use for every single requirement. Hence, we decided not to use Express. &lt;/p&gt;

&lt;h3&gt;
  
  
  Meteor
&lt;/h3&gt;

&lt;p&gt;Meteor is a powerful full-stack Node.js framework. We did not go ahead with Meteor as it doesn't support PostgreSQL and migrating the database to MongoDB wasn't something we want to spend our time on. ( We came across meteor-postgres but as their documentation says, it is still a work in progress ).&lt;/p&gt;

&lt;h3&gt;
  
  
  NestJS
&lt;/h3&gt;

&lt;p&gt;NestJS has everything that we were looking for in a backend framework. NestJS is a slightly opinionated framework but gives some level of flexibility by allowing the usage of other libraries. For example, NestJS uses Express under the hood but it can be configured to use Fastify as well. &lt;/p&gt;

&lt;h2&gt;
  
  
  The new architecture for the server
&lt;/h2&gt;

&lt;p&gt;We decided to go ahead with NestJS because: a) It fully supports TypeScript b) Database agnostic: we can directly use any Node.js database integration libraries or ORM. NestJS documentation explains in detail integrating TypeORM and Sequelize. c) Excellent documentation: everything is explained well. &lt;/p&gt;

&lt;p&gt;We started looking for an Object Relational Mapper (ORM) because we do not want to spend our time building and debugging SQL queries. TypeORM and Sequelize were the most mature choices. We chose TypeORM because it is a matured ORM available for TypeScript.&lt;/p&gt;

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

&lt;p&gt;In the coming days, we will be working on migrating the Ruby on Rails endpoints and query services to Node.js in a way that the users will not have to change the existing data in their PostgreSQL database.&lt;/p&gt;

&lt;p&gt;We would love you to check out ToolJet on GitHub: &lt;a href="https://github.com/ToolJet/ToolJet/"&gt;https://github.com/ToolJet/ToolJet/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
