<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Khalil Najjar</title>
    <description>The latest articles on DEV Community by Khalil Najjar (@knajjars).</description>
    <link>https://dev.to/knajjars</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%2F630369%2Faa2aed39-3da1-4a89-b4af-64a00e574237.jpeg</url>
      <title>DEV Community: Khalil Najjar</title>
      <link>https://dev.to/knajjars</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/knajjars"/>
    <language>en</language>
    <item>
      <title>My chatbot builder is over-engineered, and I love it</title>
      <dc:creator>Khalil Najjar</dc:creator>
      <pubDate>Mon, 12 Aug 2024 19:52:12 +0000</pubDate>
      <link>https://dev.to/knajjars/my-chatbot-builder-is-over-engineered-and-i-love-it-4d87</link>
      <guid>https://dev.to/knajjars/my-chatbot-builder-is-over-engineered-and-i-love-it-4d87</guid>
      <description>&lt;p&gt;Over the past year, I've been working on a chatbot builder called &lt;a href="https://fastmind.ai" rel="noopener noreferrer"&gt;Fastmind&lt;/a&gt;. My goal with this project was to learn how to build a fully automated service that could scale to thousands of users without breaking the bank. Given the nature of a chatbot builder, I encountered several interesting challenges, such as exposing an AI model to the web, preventing malicious users from abusing the service (which, in contrast to traditional CRUD apps, could turn out to be insanely expensive), and handling a large number of concurrent users for the chat stream without performance bottlenecks. These challenges were in addition to the more common SaaS issues like billing, user management, and monitoring.&lt;/p&gt;

&lt;p&gt;In this post, I'll share the lessons I learned during this long journey and offer my advice on building software as a solo developer (spoiler alert: don't do what I did). By the time you finish reading this, I hope you'll find it useful whether you're building a similar product or just curious about how over-engineered chatbots work behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Behind Fastmind
&lt;/h2&gt;

&lt;p&gt;When building a new project, it's important to choose the right tools for the job.&lt;/p&gt;

&lt;p&gt;So what is the best tool for this job? Well, you guessed it! &lt;strong&gt;Always choose what you know.&lt;/strong&gt; In my case, I've been working with the JavaScript ecosystem for a while, so I decided to stick with &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt; for the frontend and &lt;a href="https://hono.dev" rel="noopener noreferrer"&gt;Hono&lt;/a&gt; for the backend. I also used &lt;a href="https://convex.dev" rel="noopener noreferrer"&gt;Convex&lt;/a&gt; heavily for the database, cron jobs, real-time capabilities, and more, all bundled together in a &lt;a href="https://turbo.build/repo" rel="noopener noreferrer"&gt;Turborepo&lt;/a&gt;. I'll go into more detail about each part of the architecture in the following sections.&lt;/p&gt;

&lt;p&gt;Here is a rough overview of the folder structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;apps&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;chatbot-builder&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chat-widget&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;marketing-website&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hono-api&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;packages&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;convex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;utils&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;I have three separate frontend applications. This separation was intentional to maintain a clear division between the chatbot builder (dashboard), the chatbot itself (the chat widget embedded on your website), and the marketing website. This separation makes it easier to maintain and scale the applications independently and push updates without affecting other parts of the system. For me, this setup works because it's the same one I use at work, so I feel very comfortable with this architecture. Again, this might not be your case, and that’s perfectly fine. I won’t go into too much detail about the marketing website, as it's not the focus of this post, but it’s a &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; app hosted on &lt;a href="https://vercel.com" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chatbot Builder
&lt;/h4&gt;

&lt;p&gt;For the main app (chatbot builder), I used Next.js paired with &lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;Shadcn&lt;/a&gt; for UI components and &lt;a href="https://tailwindcss.com" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; for styling. Since I use Convex for the DB layer, I used their React library to connect to the DB to perform queries and mutations with real-time features and to call serverless functions with what they call "actions." I'll delve deeper into Convex and all of its amazing features in another post if you're interested. For authentication, I used &lt;a href="https://clerk.com" rel="noopener noreferrer"&gt;Clerk&lt;/a&gt; to avoid dealing with user management and building all the different auth flows, allowing me to focus on product development. This is one of my favorite tools out there—you have to check them out if you're a React developer. This app is hosted on Vercel, which is a great platform for hosting Next.js apps.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chat Widget
&lt;/h4&gt;

&lt;p&gt;The chat widget is a basic &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; application that connects to the long-running API to get the chatbot configuration, stream, and send messages. The chat widget is hosted on &lt;a href="https://workers.cloudflare.com" rel="noopener noreferrer"&gt;Cloudflare Workers&lt;/a&gt;, a serverless platform that allows you to run JavaScript code at the edge of the network. This is very useful for a chat widget, as it’s closer to the user and can significantly reduce latency and costs, especially if a large number of users start using the chat widget. This could easily be hosted alongside the chatbot builder, and it would be perfectly fine—and cheaper. But I am a bit of a performance freak, so I decided to go with Cloudflare Workers. Also, I've heard horror stories about the costs of apps hosted on Vercel being DDoSed, so I decided to go with Cloudflare Workers to prevent this from happening.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Long-Running API Server
&lt;/h4&gt;

&lt;p&gt;The backend consists of a long-running Hono server that handles most of the chat widget requests, as explained above. It’s a &lt;a href="https://bun.sh" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; application that connects to Convex to read and write data to the database. It’s hosted on &lt;a href="https://railway.app" rel="noopener noreferrer"&gt;Railway&lt;/a&gt;, a platform that allows you to deploy and scale your applications without worrying about infrastructure. This server could be replaced with Convex and use their serverless functions or even &lt;a href="https://docs.convex.dev/functions/http-actions" rel="noopener noreferrer"&gt;HTTP solution&lt;/a&gt;, but I prefer to have a long-running API server for the chat widget to prevent DDoS attacks on my serverless functions. To achieve this, I have a local Redis instance available for the server to rate-limit requests by IP. Then I have another rate-limit layer directly on the DB (Convex) to block multiple requests for an account. Believe it or not, this helps me sleep at night.&lt;/p&gt;

&lt;h4&gt;
  
  
  Convex
&lt;/h4&gt;

&lt;p&gt;Now the star of the show—most of the backend logic runs in Convex. It is very similar to Firebase or Supabase, but with an even better developer experience, in my opinion. I highly recommend checking them out if you're building a new project, especially in React. Caching, real-time updates, serverless functions, and cron jobs development environment are all handled by Convex. I also use their HTTP actions to handle incoming webhooks from &lt;a href="https://www.lemonsqueezy.com" rel="noopener noreferrer"&gt;Lemonsqueezy&lt;/a&gt; and Clerk. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did I choose Convex over Firebase, Supabase, or even a self-hosted solution?&lt;/strong&gt; I initially started Fastmind using the T3 stack, but found it to be too much work to handle some of the real-time features I needed. I also required a lot of background jobs, for which I tried solutions like &lt;a href="https://bullmq.io/" rel="noopener noreferrer"&gt;Bull&lt;/a&gt;, and services like &lt;a href="https://www.inngest.com/" rel="noopener noreferrer"&gt;Inngest&lt;/a&gt; and &lt;a href="https://trigger.dev" rel="noopener noreferrer"&gt;Trigger.dev&lt;/a&gt;. While these are great services, I wanted everything in one place, so I decided to give Convex a try, and I’m very happy with the results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;p&gt;As mentioned above, I use &lt;a href="https://vercel.com" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; for the frontend apps, &lt;a href="https://workers.cloudflare.com" rel="noopener noreferrer"&gt;Cloudflare Workers&lt;/a&gt; for the chat widget, and &lt;a href="https://railway.app" rel="noopener noreferrer"&gt;Railway&lt;/a&gt; for the backend. I also use &lt;a href="https://sentry.io" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt; for error tracking, &lt;a href="https://www.lemonsqueezy.com" rel="noopener noreferrer"&gt;Lemonsqueezy&lt;/a&gt; for billing as my Merchant of Record so I don't have to worry about taxes, &lt;a href="https://clerk.com" rel="noopener noreferrer"&gt;Clerk&lt;/a&gt; for authentication, and &lt;a href="https://convex.dev" rel="noopener noreferrer"&gt;Convex&lt;/a&gt; for the database, cron jobs, and real-time features. The AI models are Command R and Command R+ from &lt;a href="https://cohere.com" rel="noopener noreferrer"&gt;Cohere&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another star of the show is &lt;strong&gt;&lt;a href="https://www.cloudflare.com" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt;&lt;/strong&gt;. I use them heavily in Fastmind. In addition to what I’ve mentioned above, I use their &lt;a href="https://developers.cloudflare.com/ai-gateway/" rel="noopener noreferrer"&gt;AI Gateway&lt;/a&gt; service. This is a great product to use when you need to expose an AI model to the web; it handles rate limiting, caching, and DDoS protection for chat requests. All my domains are managed by Cloudflare—they are second to none when it comes to handling DNS and SSL certificates and preventing DDoS attacks. Lastly, their &lt;a href="https://getdeploying.com/reference/data-egress" rel="noopener noreferrer"&gt;zero-egress pricing&lt;/a&gt; for storage is a great deal for me. I use it to store chatbot assets and scripts. Eventually, I plan to allow users to upload PDFs and other files to train their chatbots, as well as conversation logs so they can export them and analyze them later.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Key Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It Doesn't Have to Be Perfect
&lt;/h3&gt;

&lt;p&gt;I spent a lot of time trying to make everything perfect, but I realized it's better to have something that works and iterate on it. I waited too long to ship Fastmind, and I was going to postpone it even further. But my competition is already making bank while I was just building, and I must say I don't think Fastmind is missing any features; if anything, it has more. Since realizing this, I adopted a "ship fast, iterate often" mentality, and I’ve been able to launch Fastmind and get users without everything being perfect, and that is &lt;strong&gt;okay&lt;/strong&gt;. I’ve been able to fix bugs and add features as I go, and users are happy. This is the beauty of building a SaaS product—you can always improve it; it’s never finished. So don't worry too much about making everything perfect—just get it out there and start getting feedback. This is something other successful founders have taught me, but being an engineer first, I always focused on the "fun" part of building the product and not on the "hard" part of getting users. I’m still learning this, but I’m getting better at it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focus on the User
&lt;/h3&gt;

&lt;p&gt;After I launched, I started to realize what users wanted, and trust me, it's very different from what you think they want. I’ve been able to gather a lot of feedback from users and improve the product based on that feedback. For example, I thought users would want a lot of customization options for the chat widget, but it turns out they just want a simple chatbot that works and does one thing very well. I also thought users would want a lot of AI features, but it turns out they just want a chatbot that can answer their questions accurately. I’ve been able to focus on the features that users want and ignore the ones they don’t care about. This has helped me build a product that users love and are willing to pay for. Onboarding is key—I've seen a lot of users drop off because they don't know how to use the product, so I've been working on improving the onboarding process to make it easier for users to get started. I’ve built the easiest chatbot builder out there; in just 2 minutes you can have a chatbot up and running on your website (yes, I timed it).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tech Stack Doesn't Matter
&lt;/h3&gt;

&lt;p&gt;I’ve been able to build Fastmind using the tech stack I know and love, but I’ve seen other successful founders build their products using entirely different tech stacks. What matters is that you build something that works and that users want. Don’t get too caught up in the tech stack—just build something functional and valuable. In the end, if your product is successful, you can always rewrite it in a different tech stack, but by then, you'll have the users, revenue, and motivation to do so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Wait Too Long to Launch
&lt;/h3&gt;

&lt;p&gt;I’ve been building Fastmind in the shadows since August 2023. Meanwhile, I have competitors who entered the market with a product similar to mine—not perfect, but they’re making money and collecting feedback while I was just building alone without a clear direction of what my users wanted. I should have launched Fastmind earlier; I would have received insanely valuable feedback from users and been able to improve the product based on that feedback faster. I was afraid of launching because I thought the product wasn't perfect, but I realized that it's better to launch something that works and iterate on it than to wait for it to be perfect.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Regret Being a Hipster in Tech</title>
      <dc:creator>Khalil Najjar</dc:creator>
      <pubDate>Sun, 27 Jun 2021 10:08:19 +0000</pubDate>
      <link>https://dev.to/knajjars/learnings-after-5-years-of-being-a-hipster-in-tech-1b0n</link>
      <guid>https://dev.to/knajjars/learnings-after-5-years-of-being-a-hipster-in-tech-1b0n</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;For the last five or more years &lt;strong&gt;I've been doing it all wrong&lt;/strong&gt;. I thought that learning the newest, trendiest, and hippest library, framework or language out there was the way to go. I've curated a list of &lt;strong&gt;some&lt;/strong&gt; of the technologies I've learned thought-out the years:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Docker, Kubernetes, Terraform, Rancher, Helm, Angular, React, Vue, Adonis.js, Prisma, Gatsby, GraphQL, Postgres, MongoDB, Cassandra, Socket.io, Webpack, SASS, Gulp, Next.js, Nuxt.js, Meteor, Express, Koa, Elastic, Algolia, jQuery, TypeScript, Node.js, Deno.js, Go, Python, Ruby, PHP, Java, among many more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is the problem with this list? Well if you look closely, I learned many tools that solve similar problems, I am getting ahead of my self but &lt;strong&gt;pro-tip&lt;/strong&gt;: you don't have to learn every single one out there 😉.&lt;/p&gt;

&lt;p&gt;Also, there's been a lot of software architecture changes during this time, we've had the &lt;strong&gt;monolithic&lt;/strong&gt; approach, then &lt;strong&gt;client-service&lt;/strong&gt; came along, need I remind you of the complicated &lt;strong&gt;microservices&lt;/strong&gt; architecture? and now we have &lt;strong&gt;serverless&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Look, I could keep going on... As you can see (and probably you've been in a similar situation) I've invested a lot of my free time learning different tools that &lt;strong&gt;achieve similar results&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Like so many developers out there, I started to &lt;strong&gt;burn out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Long story short, I took some vacations and went to the German Alps 🏔 to contemplate about life and find what was I doing wrong. During my mountain retreat, Apple had the WWDC﹡, and of course, me being a nerd, I just couldn't miss the event therefore I joined.&lt;/p&gt;

&lt;p&gt;And all of a sudden it was clear to me what do I needed... it was &lt;strong&gt;stability&lt;/strong&gt; in my day-to-day as a developer. Something Apple offers with their WWDC.&lt;/p&gt;

&lt;p&gt;Allow me to explain...&lt;/p&gt;

&lt;p&gt;The beauty of this is that it gives guidance to the Apple developers, there are no new disruptive technologies that pop out of nowhere, it's a clear and predictable roadmap, which allows the developers to follow this guided path, and simply focus on getting better at what they do and very &lt;strong&gt;occasionally learn&lt;/strong&gt; the new way of doing things.&lt;/p&gt;

&lt;p&gt;Now... I love the web, I was not going to change my career and become a mobile developer overnight. So naturally, I started looking for alternatives in my domain. That's when I crossed paths with the well-known and &lt;strong&gt;battle-tested MVC frameworks&lt;/strong&gt; 🐍 💎.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New Hope
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftspz75bhbk6ic7fcmu0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftspz75bhbk6ic7fcmu0w.png" alt="Luke Skywalker - A New Hope" width="612" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've worked with different MVC frameworks in the past, like &lt;strong&gt;Django&lt;/strong&gt;, but they were more like stepping stones towards my career as a &lt;strong&gt;&lt;strong&gt;wheel-reinventor engineer&lt;/strong&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I tried &lt;strong&gt;Adonis.js&lt;/strong&gt;, which is a very good JavaScript MVC framework, I truly enjoyed working with it, although at the time it had a &lt;strong&gt;small community&lt;/strong&gt; and many &lt;strong&gt;new breaking-changes were being introduced&lt;/strong&gt; to the framework as it was being actively developed.&lt;/p&gt;

&lt;p&gt;That's when I decided to go with something more mature, hence boring, &lt;strong&gt;and what is more boring than Rails?&lt;/strong&gt;&lt;br&gt;
I immediately fell in love with the framework and the community behind it.&lt;/p&gt;

&lt;p&gt;After a few months of learning the Rails way, I started to realize something... I felt lazy, before I used to learn new skills for at least 4 hours/day (after working 8 hours). Now, all of a sudden I was finally using my free time in a different and healthier way, &lt;strong&gt;but why was I feeling lazy?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Throughout the years I got used to the idea that I had to be studying every single day, &lt;strong&gt;like if I had some sort of homework&lt;/strong&gt; because you know - that's the life that I chose by becoming a software engineer (although it's true to some extent).&lt;/p&gt;

&lt;p&gt;Don't get me wrong, &lt;strong&gt;learning new skills during your free time is important&lt;/strong&gt;, but it's &lt;strong&gt;also&lt;/strong&gt; important to enjoy other aspects of &lt;strong&gt;life&lt;/strong&gt;, while still learning occasionally in your free time or during work.&lt;/p&gt;

&lt;p&gt;This is what I did, instead of using most of my free time to keep up to date with tools I &lt;strong&gt;probably will never use&lt;/strong&gt;. I leveraged my job to introduce new technologies (when the need arises). This way I can stay relevant and scratch my itch for learning new stuff.&lt;/p&gt;

&lt;p&gt;Nonetheless, it took me some time to &lt;strong&gt;stop feeling guilty&lt;/strong&gt; and start appreciating the stability that I was looking for, and let me tell you something, it is well worth it ✌️.&lt;/p&gt;

&lt;p&gt;Now after work, I don't open Udemy or Hacker News, I'd rather go for a stroll 🚶‍♂️, bike 🚵‍♂️, cook for my girlfriend 🧑‍🍳, do some yoga 🧘‍♂️ - you get the point. I am no longer a &lt;strong&gt;prisoner&lt;/strong&gt; of tech and guess what? I enjoy my work, coding and life more now than ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learnings
&lt;/h2&gt;

&lt;p&gt;There will always be something new to learn, you can try and stay up-to-date, get burned out, take some vacations and repeat this &lt;strong&gt;never-ending cycle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's okay (and encouraged) to &lt;strong&gt;learn&lt;/strong&gt; new and hipster tech every once in a while, I certainly still do it &lt;strong&gt;occasionally&lt;/strong&gt; for fun, but it's not longer (and thankfully) part of my day-to-day life.&lt;/p&gt;

&lt;p&gt;If you feel that you are in a similar situation &lt;strong&gt;don't wait to get burned out&lt;/strong&gt;, act - make a change. I did it and it has improved my life drastically.&lt;/p&gt;

&lt;p&gt;Being a good, happy and healthy developer it's &lt;strong&gt;not&lt;/strong&gt; knowing everything, but rather understanding what you need to know.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Life is really simple, but we insist on making it complicated." &lt;br&gt;
~ Confucius&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Appendix
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WWDC&lt;/strong&gt;&lt;br&gt;
It is a yearly event where Apple presents to their community of developers the improvements coming to the Swift language as well as new features arriving to their operating systems.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>react</category>
      <category>javascript</category>
      <category>django</category>
    </item>
  </channel>
</rss>
