<?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: haimantika mitra</title>
    <description>The latest articles on DEV Community by haimantika mitra (@haimantika).</description>
    <link>https://dev.to/haimantika</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%2F401142%2Fafaae4c7-9e8a-4d9c-9b9e-c9ef3d4b5a0d.jpg</url>
      <title>DEV Community: haimantika mitra</title>
      <link>https://dev.to/haimantika</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/haimantika"/>
    <language>en</language>
    <item>
      <title>Automating onboarding emails with n8n and AutoSend</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Tue, 23 Dec 2025 04:15:43 +0000</pubDate>
      <link>https://dev.to/haimantika/automating-onboarding-emails-with-n8n-and-autosend-3480</link>
      <guid>https://dev.to/haimantika/automating-onboarding-emails-with-n8n-and-autosend-3480</guid>
      <description>&lt;p&gt;Building a SaaS? The first thing you will build in your SaaS platform is the onboarding process. In my &lt;a href="https://dev.to/haimantika/building-otp-based-authentication-system-with-clerk-and-autosend-13mm"&gt;last article, you learned&lt;/a&gt; how to build the authentication system, and in this article, you will learn how you can automate the welcome emails during sign-up.&lt;/p&gt;

&lt;p&gt;To build this, we will be using n8n and AutoSend, here’s a little about both the tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n: &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt; is an automation tool that lets you connect apps and services without writing glue code everywhere. You build workflows visually, trigger something (like a webhook), run logic, call APIs, transform data, and ship results where you need them. It’s open-source, self-hostable, and flexible enough to power everything from simple automations to production-grade backend workflows.
&lt;/li&gt;
&lt;li&gt;AutoSend: &lt;a href="https://autosend.com/" rel="noopener noreferrer"&gt;AutoSend&lt;/a&gt; is a developer-first email API that makes sending transactional emails simple and reliable. You define templates once, trigger emails via an API or webhook, and AutoSend handles delivery, retries, and tracking. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s what we will be building today:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vM6WrAxtCnE"&gt;
&lt;/iframe&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3g9i2blm6s1ysnjlwg2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3g9i2blm6s1ysnjlwg2.png" alt="Email" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the workflow
&lt;/h2&gt;

&lt;p&gt;What happened above is, as soon as the user signed up with their details, a webhook was triggered which then made a Http call to the AutoSend API and sent the welcome email.&lt;br&gt;&lt;br&gt;
Here’s the entire workflow diagram:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc68eas4qa6zysvxt7ejm.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc68eas4qa6zysvxt7ejm.png" alt="Mermaid diagram" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To explain the entire process step-by-step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User fills signup form&lt;br&gt;&lt;br&gt;
Frontend collects and sends this to n8n Webhook via &lt;code&gt;POST&lt;/code&gt;:&lt;br&gt;&lt;br&gt;
&lt;code&gt;{&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"name": "Haimantika",&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;"email": "test@gmail.com"&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Webhook receives the request&lt;br&gt;&lt;br&gt;
Data lands in:&lt;br&gt;&lt;br&gt;
&lt;code&gt;$json.body.name&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;$json.body.email&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;n8n makes an API call to AutoSend:&lt;br&gt;&lt;br&gt;
&lt;code&gt;POST https://api.autosend.com/v1/mails/send&lt;/code&gt;&lt;br&gt;&lt;br&gt;
And sends structured email payload:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
`{`  
 `"from": { "email": "no-reply@saascode.in", "name": "Team SaaSCode"`   
`},`  
    `"to":   { "email": "test@gmail.com", "name": "Haimantika" },`  
  `"subject": "Welcome to SaaSCode 🎉",`  
  `"html": "&amp;lt;h1&amp;gt;Hello Haimantika&amp;lt;/h1&amp;gt;"`  
    `}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Finally, AutoSend validates the request, renders the template and sends the email&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Building the n8n workflow
&lt;/h2&gt;

&lt;p&gt;The n8n workflow is simple, all that it includes is a webhook and a http request. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipeo6vdjgodz0u9yb7p9.jpeg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipeo6vdjgodz0u9yb7p9.jpeg" alt="Workflow" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To build the workflow, here’s how you need to configure them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a webhook, change the HTTP method to &lt;code&gt;POST&lt;/code&gt;, give the path a unique name, e.g &lt;code&gt;user-signup&lt;/code&gt; and then keep the response timing to &lt;code&gt;Immediate&lt;/code&gt;. Copy the production URL and then keep it saved, we will add it to our application later.
&lt;/li&gt;
&lt;/ol&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclkuege1fpdkkqznmlb8.jpeg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclkuege1fpdkkqznmlb8.jpeg" alt="Webhook node" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Then you need to add a HTTP request, in that add the &lt;code&gt;https://api.autosend.com/v1/mails/send&lt;/code&gt; endpoint and keep the method as &lt;code&gt;POST&lt;/code&gt;.
a. Once this done, you need to add two headers:
i. Authorization: Bearer &amp;lt;API key&amp;gt;
ii. Content-type: application/json
b. Next, you will need to add a JSON body. Copy and paste the JSON below. Update the email and the message:
&lt;/li&gt;
&lt;/ol&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;"from"&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;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test@saascode.in"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Team SaaSCode"&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;"to"&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;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{$json.body.email}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{$json.body.name}}"&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;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Welcome to SaaSCode 🎉"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello {{$json.body.name}}&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Thanks for joining!&amp;lt;/p&amp;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;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello {{$json.body.name}}, Thanks for joining!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.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%2Fup5navpjiuzkxbx5avr4.jpeg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup5navpjiuzkxbx5avr4.jpeg" alt="Http node" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The final step is to save and publish the workflow.
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Frontend integration
&lt;/h2&gt;

&lt;p&gt;The next step is to connect the frontend to the n8n workflow. For this particular demo, we are using a single &lt;code&gt;index.html&lt;/code&gt; file and you can find the &lt;a href="https://github.com/Haimantika/autosend-n8n-workflow" rel="noopener noreferrer"&gt;reference code here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The frontend uses the native fetch API to communicate with n8n. When the user submits the sign-up form, we prevent the default browser behavior and aggregate the input values into a JavaScript object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&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="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we send a POST request to the n8n webhook endpoint.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Note&lt;/em&gt;: &lt;em&gt;We include the &lt;code&gt;Content-Type: application/json\&lt;/code&gt; header so n8n can automatically parse the body.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://hmitra.app.n8n.cloud/webhook-test/user-signup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//the url we copied from n8n&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;That’s really all there is to it.&lt;br&gt;&lt;br&gt;
With one webhook and one HTTP request in n8n, you’ve automated one of the most important parts of any SaaS: the first email a user receives after signing up. No background jobs, no custom mailer logic, no retry handling code scattered across your backend.&lt;/p&gt;

&lt;p&gt;What I like about this setup is the clear separation of responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The frontend just collects user input and sends it somewhere.
&lt;/li&gt;
&lt;li&gt;n8n acts as the glue and the control plane.
&lt;/li&gt;
&lt;li&gt;AutoSend sends emails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this is in place, you can keep extending it without touching your application code. Want to send a follow-up email after 24 hours? Add a Delay node. Want to route enterprise signups to a different template? Add a condition. Want to notify your internal team on Slack? Same workflow, one more node.&lt;br&gt;&lt;br&gt;
This is also why I prefer workflows for things like onboarding. These flows change often, especially early on. Keeping them outside your core codebase makes iteration much faster and much safer.&lt;br&gt;&lt;br&gt;
If you’re building a SaaS, this is one of those “set it up once and forget about it” pieces that pays off immediately.&lt;/p&gt;

&lt;p&gt;Here’s some resources if you would like to learn more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://community.n8n.io/c/getting-started-with-n8n/docs-and-tutorials/6" rel="noopener noreferrer"&gt;n8n documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.autosend.com/" rel="noopener noreferrer"&gt;AutoSend documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.twilio.com/en-us/blog/insights/marketing-email-vs-transactional-email-whats-difference" rel="noopener noreferrer"&gt;Transactional vs marketing emails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope you enjoyed reading this quick tutorial. Will see you next year with more such quick and fun content!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>automation</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building OTP based authentication system with Clerk and Autosend</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Wed, 26 Nov 2025 17:05:17 +0000</pubDate>
      <link>https://dev.to/haimantika/building-otp-based-authentication-system-with-clerk-and-autosend-13mm</link>
      <guid>https://dev.to/haimantika/building-otp-based-authentication-system-with-clerk-and-autosend-13mm</guid>
      <description>&lt;p&gt;Vibe-coding has got us thinking more about security. Earlier this year, we saw Leo’s SaaS under attack, it was experiencing bypassed subscriptions, abused API keys, and database corruption.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y5xy6wihimabch27l2e.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y5xy6wihimabch27l2e.jpg" alt=" " width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Big tech giants are focusing a lot on building applications that are AI+security first. As developers, every solution that we build now needs security to be built into the design phase. The first step to any application (SaaS or not) is authentication, and companies like Clerk, Auth0, etc., have already made it easier for us to build authentication systems that are secure.&lt;/p&gt;

&lt;p&gt;While you can also use their pre-built solutions, you might also need to plug and play custom solutions, and this is exactly what we will learn in this blog: how we can use Clerk’s authentication system with Autosend to build a secure authentication system.&lt;/p&gt;

&lt;p&gt;To follow this article end-to-end, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working knowledge of Next.js
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://clerk.com/" rel="noopener noreferrer"&gt;A Clerk account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://autosend.com/" rel="noopener noreferrer"&gt;An Autosend account&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is Autosend?
&lt;/h1&gt;

&lt;p&gt;I recently discovered &lt;a href="http://autosend.com" rel="noopener noreferrer"&gt;Autosend&lt;/a&gt; on X and thought about playing around with it over the weekend. By definition, Autosend is an email platform for developers and marketers to send and track transactional and marketing emails. If you have used other platforms like Resend and Twilio, it does compare with them. What stood out for me is the developer experience; the product is easy to use with a clear developer journey outlining the steps to follow to send a successful email, and the documentation is very easy to follow as well. Although it does not have a free account, the paid tier for someone like us starts from $1, where you can send up to 3000 emails, which is more than enough for people like us building hobby projects.&lt;/p&gt;

&lt;h1&gt;
  
  
  Integration flow
&lt;/h1&gt;

&lt;p&gt;To build this entire thing wouldn’t take you more than an hour. To make things easy, we are using Clerk’s &lt;a href="https://clerk.com/docs/nextjs/getting-started/quickstart" rel="noopener noreferrer"&gt;Next.js starter guide&lt;/a&gt; (you can also copy the prompt and get started faster in your AI IDE of choice/use the Cursor button) and then replace the email verification part with Autosend.&lt;/p&gt;

&lt;p&gt;In this implementation, Clerk manages user accounts and sessions, while Autosend handles email delivery for verification codes. Unlike Clerk's built-in email verification, we generate and validate our own codes, giving us complete control over the email content, delivery, and user experience.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsexoew7tnb9xtf46ikv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsexoew7tnb9xtf46ikv.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step-by-Step Process: Building the Authentication Flow
&lt;/h1&gt;

&lt;p&gt;The authentication flow consists of six main stages: &lt;strong&gt;User Registration&lt;/strong&gt;, &lt;strong&gt;Code Generation&lt;/strong&gt;, &lt;strong&gt;Email Delivery&lt;/strong&gt;, &lt;strong&gt;Code Verification&lt;/strong&gt;, &lt;strong&gt;Validation&lt;/strong&gt;, and &lt;strong&gt;Session Creation&lt;/strong&gt;. Let's break down each step to understand how Clerk and Autosend work together to create a secure authentication experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: User initiates signup
&lt;/h2&gt;

&lt;p&gt;When a user visits the &lt;code&gt;/signup&lt;/code&gt; page and submits their credentials, the process begins.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxb5ohop396d69pk2ex57.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxb5ohop396d69pk2ex57.png" alt=" " width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The signup page (&lt;code&gt;app/signup/page.tsx&lt;/code&gt;) presents a beautiful gradient-styled form where users enter their email and password. When they click "Sign Up", the &lt;code&gt;handleSubmit&lt;/code&gt; function is triggered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FormEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Create the sign-up with Clerk&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;emailAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Send verification code via Autosend&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/send-verification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setPendingVerification&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="c1"&gt;// Show code input screen&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;
  
  
  What's happening under the hood
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Clerk's &lt;code&gt;signUp.create()&lt;/code&gt; creates a user account in their system
&lt;/li&gt;
&lt;li&gt;The account is created but &lt;strong&gt;not yet verified&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A POST request is sent to the &lt;code&gt;/api/send-verification&lt;/code&gt; endpoint
&lt;/li&gt;
&lt;li&gt;The UI switches to show the verification input screen&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Important configuration
&lt;/h3&gt;

&lt;p&gt;Disable Clerk’s built-in email verification:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Clerk Dashboard
&lt;/li&gt;
&lt;li&gt;User &amp;amp; Authentication → Email, Phone, Username
&lt;/li&gt;
&lt;li&gt;Turn OFF “Verify at sign-up”
&lt;/li&gt;
&lt;li&gt;Save changes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This allows verification to be handled by Autosend instead of Clerk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Backend generates verification code
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/api/send-verification&lt;/code&gt; endpoint generates and stores a verification code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code generation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateCode&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;900000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&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;
  
  
  Storage with expiration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateCode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;verificationCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;expiresAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 10 minutes&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Triggering email delivery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendVerificationEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;verificationCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;success&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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Verification code sent via Autosend&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;h2&gt;
  
  
  Step 3: Autosend delivers the email
&lt;/h2&gt;

&lt;p&gt;The email is constructed and sent through Autosend’s API.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flhql95fyn2kt5ibjhhbe.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flhql95fyn2kt5ibjhhbe.png" alt=" " width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Email construction
&lt;/h3&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendVerificationEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AutosendResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Your verification code: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;plainTextVersion&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;h3&gt;
  
  
  &lt;strong&gt;API call&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.autosend.com/v1/mails/send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTOSEND_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTOSEND_FROM_EMAIL&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTOSEND_FROM_NAME&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Your verification code: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;h2&gt;
  
  
  &lt;strong&gt;Step 4: User enters verification code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The user enters the 6-digit code in the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Verification screen&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-blue-50 border border-blue-200 rounded-lg p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm text-blue-800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="err"&gt;📧&lt;/span&gt; &lt;span class="nx"&gt;We&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ve sent a verification code to &amp;lt;strong&amp;gt;{email}&amp;lt;/strong&amp;gt; via Autosend.
  &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;input
  type="text"
  value={code}
  onChange={(e) =&amp;gt; setCode(e.target.value)}
  placeholder="Enter 6-digit code"
  maxLength={6}
  className="text-center text-2xl font-mono tracking-widest"
/&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Backend validates the code
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/api/verify-code&lt;/code&gt; endpoint performs strict validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;POST&lt;span class="o"&gt;(&lt;/span&gt;req: NextRequest&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const &lt;span class="o"&gt;{&lt;/span&gt; email, code &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await req.json&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const stored &lt;span class="o"&gt;=&lt;/span&gt; verificationCodes.get&lt;span class="o"&gt;(&lt;/span&gt;email&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;stored&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;NextResponse.json&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt; success: &lt;span class="nb"&gt;false&lt;/span&gt;, error: &lt;span class="s2"&gt;"No verification code found. Please request a new one."&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;{&lt;/span&gt; status: 400 &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;stored.expiresAt &amp;lt; Date.now&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    verificationCodes.delete&lt;span class="o"&gt;(&lt;/span&gt;email&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;NextResponse.json&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt; success: &lt;span class="nb"&gt;false&lt;/span&gt;, error: &lt;span class="s2"&gt;"Verification code has expired. Please request a new one."&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;{&lt;/span&gt; status: 400 &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;stored.code &lt;span class="o"&gt;!==&lt;/span&gt; code&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;NextResponse.json&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt; success: &lt;span class="nb"&gt;false&lt;/span&gt;, error: &lt;span class="s2"&gt;"Invalid verification code. Please try again."&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;{&lt;/span&gt; status: 400 &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  verificationCodes.delete&lt;span class="o"&gt;(&lt;/span&gt;email&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;NextResponse.json&lt;span class="o"&gt;({&lt;/span&gt;
    success: &lt;span class="nb"&gt;true&lt;/span&gt;,
    message: &lt;span class="s2"&gt;"Email verified successfully"&lt;/span&gt;,
  &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Complete signup and create session
&lt;/h2&gt;

&lt;p&gt;After verification, Clerk finalizes signup and creates the user session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;SignUp status: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;Created session ID: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.createdSessionId&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the session
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdSessionId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdSessionId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;setIsRedirecting&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="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;setTimeout&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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;And finally, users see a success screen and are then redirected to the homepage fully authenticated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete flow visualization
&lt;/h2&gt;

&lt;p&gt;A visual diagram showing how Clerk, the API routes, Autosend, and the frontend connect together to build the entire authentication system.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizka80nrw92awtuqr95p.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizka80nrw92awtuqr95p.png" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ending Notes
&lt;/h1&gt;

&lt;p&gt;And that’s how you can easily build a fully functional and customizable authentication flow for your applications.&lt;/p&gt;

&lt;p&gt;A few things to keep in mind as you build on top of this: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security enhancements&lt;/strong&gt;: Consider adding rate limiting to prevent abuse, you don't want someone spamming your verification endpoint. Also, think about implementing attempt limits (maybe 3-5 tries) before requiring a new code.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User experience&lt;/strong&gt;: The 10-minute expiration works well, but you might want to add a "Resend code" button with a cooldown timer. Users appreciate this when emails take longer to arrive or they accidentally delete them. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern isn't limited to just signup flows either. You can use the same Clerk + Autosend combination for password resets, or magic link authentication. The beauty is that once you understand how these pieces fit together, you can adapt them to whatever authentication pattern your application needs.&lt;/p&gt;

&lt;p&gt;If you are interested to learn more about authentication,email platforms, and 2FA here are some helpful resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.microsoft.com/en-in/security/business/security-101/what-is-two-factor-authentication-2fa" rel="noopener noreferrer"&gt;What is two-factor authentication?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://auth0.com/docs/get-started/identity-fundamentals/authentication-and-authorization" rel="noopener noreferrer"&gt;Authentication vs Authorization&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.autosend.com/" rel="noopener noreferrer"&gt;Autosend documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://clerk.com/docs" rel="noopener noreferrer"&gt;Clerk documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Mood Map - Draw all your feelings</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Sun, 19 Jan 2025 17:56:53 +0000</pubDate>
      <link>https://dev.to/haimantika/mood-map-draw-all-your-feelings-4eim</link>
      <guid>https://dev.to/haimantika/mood-map-draw-all-your-feelings-4eim</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github"&gt;GitHub Copilot Challenge &lt;/a&gt;: Transitions and Transformations&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;This year started with being diagnosed with PCOD, which means mood swings are a common part of my life. I go from feeling a ton of emotions in a day to nothing at all. Along with me, 60% of other women have it (yes, PCOD is that common).&lt;/p&gt;

&lt;p&gt;But mood swings are not just limited to people with a uterus. Every human being experiences certain moods and emotions daily. So I built the &lt;a href="https://mood-mapdraw.vercel.app/" rel="noopener noreferrer"&gt;Mood Map app&lt;/a&gt; to help turn these moods and feelings into masterpieces.&lt;/p&gt;

&lt;p&gt;Sneak peek of the app:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1881038179018690665-252" src="https://platform.twitter.com/embed/Tweet.html?id=1881038179018690665"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the app
&lt;/h2&gt;

&lt;p&gt;I started building the app with listing 12 basic emotions that a human might feel, here’s a list of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Happiness&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sadness&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fear&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disgust&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anger&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Excitement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confusion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Envy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Empathetic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sympathy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Triumph&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Satisfaction&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then, asked GitHub Copilot to list me one shape and colour that represents these moods. This is what it suggested:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Mood&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Shape&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Color&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Happiness&lt;/td&gt;
&lt;td&gt;Circle&lt;/td&gt;
&lt;td&gt;Bright Yellow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sadness&lt;/td&gt;
&lt;td&gt;Teardrop&lt;/td&gt;
&lt;td&gt;Deep Blue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fear&lt;/td&gt;
&lt;td&gt;Sharp Triangle&lt;/td&gt;
&lt;td&gt;Dark Purple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disgust&lt;/td&gt;
&lt;td&gt;Irregular Blob&lt;/td&gt;
&lt;td&gt;Olive Green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anger&lt;/td&gt;
&lt;td&gt;Jagged Spike&lt;/td&gt;
&lt;td&gt;Fiery Red&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excitement&lt;/td&gt;
&lt;td&gt;Starburst&lt;/td&gt;
&lt;td&gt;Electric Blue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confusion&lt;/td&gt;
&lt;td&gt;Spiral&lt;/td&gt;
&lt;td&gt;Pale Gray&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Envy&lt;/td&gt;
&lt;td&gt;Twisting Vine&lt;/td&gt;
&lt;td&gt;Deep Green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empathetic&lt;/td&gt;
&lt;td&gt;Interlocking Loop&lt;/td&gt;
&lt;td&gt;Warm Peach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sympathy&lt;/td&gt;
&lt;td&gt;Gentle Wave&lt;/td&gt;
&lt;td&gt;Light Blue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Triumph&lt;/td&gt;
&lt;td&gt;Upward Arrow&lt;/td&gt;
&lt;td&gt;Gold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Satisfaction&lt;/td&gt;
&lt;td&gt;Square&lt;/td&gt;
&lt;td&gt;Earthy Brown&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the final step before coding, I went to &lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;Excalidraw&lt;/a&gt; to visualize how my app would look like, and then built this structure:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw1kkzx6lcjrtshtntyt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw1kkzx6lcjrtshtntyt.png" alt="Architecture diagram" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You may not know how to use a paintbrush, but with technology, everyone can be an artist. So try out the app here 👉 &lt;a href="https://mood-mapdraw.vercel.app/" rel="noopener noreferrer"&gt;https://mood-mapdraw.vercel.app/&lt;/a&gt; , and when you do, feel free to share and tag me on X &lt;a href="https://x.com/HaimantikaM" rel="noopener noreferrer"&gt;@HaimantikaM&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Haimantika" rel="noopener noreferrer"&gt;
        Haimantika
      &lt;/a&gt; / &lt;a href="https://github.com/Haimantika/Mood-map" rel="noopener noreferrer"&gt;
        Mood-map
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Mood Map Creator&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A web-based interactive tool for creating drawings, based on mood. This can help you relax and relieve stress.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Draw and manipulate shapes on a canvas&lt;/li&gt;
&lt;li&gt;Color selection for shapes&lt;/li&gt;
&lt;li&gt;Shape customization
&lt;ul&gt;
&lt;li&gt;Resize shapes using slider controls&lt;/li&gt;
&lt;li&gt;Rotate shapes with precise angle control&lt;/li&gt;
&lt;li&gt;Copy, cut, and paste shapes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Download created mood maps as PNG files&lt;/li&gt;
&lt;li&gt;Fully keyboard accessible&lt;/li&gt;
&lt;li&gt;Screen reader friendly&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Technologies&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Next.Js&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;Lucide React (for icons)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Clone the repository&lt;/span&gt;
git clone https://github.com/{username}/Mood-map

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install dependencies&lt;/span&gt;
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; mood-map
npm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start development server&lt;/span&gt;
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Select a shape from the shape selector&lt;/li&gt;
&lt;li&gt;Choose a color from the color picker&lt;/li&gt;
&lt;li&gt;Click on the canvas to place the shape&lt;/li&gt;
&lt;li&gt;Modify shapes using:
&lt;ul&gt;
&lt;li&gt;Size slider (10-100)&lt;/li&gt;
&lt;li&gt;Rotation slider (0-360 degrees)&lt;/li&gt;
&lt;li&gt;Click on shapes to select them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Keyboard Shortcuts&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Ctrl/Cmd + C&lt;/code&gt;: Copy selected shape&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl/Cmd + V&lt;/code&gt;: Paste copied shape&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl/Cmd&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Haimantika/Mood-map" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Copilot Experience
&lt;/h2&gt;

&lt;p&gt;This entire application was built with the help of Copilot, from ideation to fixing deployment errors.&lt;br&gt;
Here's how I used it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For generating color and shape for different moods, and the prompt was, &lt;code&gt;I am building a mood based drawing app, I have these moods: happiness, sadness, anger, etc, can you help me suggest a color and shape for each of them&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For improving accessibility in the &lt;code&gt;page.tsx&lt;/code&gt; file, and the prompt for it was &lt;code&gt;Make this code more accessible&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvo9zg0h0lyxg0m3ppte.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvo9zg0h0lyxg0m3ppte.png" alt="Code updates" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To fix deployment errors, and the prompt was:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Got this error while deploying in Vercel:

Type error: Type '{}' is missing the following properties from type 'DrawingCanvasProps': selectedShape, selectedColor, shapes, setShapes, and 4 more.
  17 |           onShapeChange={setCurrentShape}
  18 |         /&amp;gt;
&amp;gt; 19 |         &amp;lt;Drawing /&amp;gt;
     |          ^
  20 |       &amp;lt;/div&amp;gt;
  21 |     &amp;lt;/div&amp;gt;
  22 |   )
Static worker exited with code: 1 and signal: null
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Command "yarn build" exited with 1` can you help me fix it?
- To generate the project README using the prompt, `Read the entire project and add a simply Readme for it that includes all about the project and what it does.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitHub Models
&lt;/h2&gt;

&lt;p&gt;I used two GitHub models for the entire project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPT4 - To help in code generation and update&lt;/li&gt;
&lt;li&gt;Claude 3.5 - To write the README for the projects&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi39k5016uuvq44o6f8lo.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi39k5016uuvq44o6f8lo.png" alt="Generating README" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I love building, and when I build for a cause, it is even better. I first discovered the painting concept in 2024, while casually strolling through the streets of Bangalore. Everything seemed to pause and feel peaceful for a moment when I picked up the sketch paints based on my mood and started coloring. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwk7fi1ms9dr1ik2hisv.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwk7fi1ms9dr1ik2hisv.jpg" alt="Haimantika painting" width="800" height="1427"&gt;&lt;/a&gt;&lt;br&gt;
Now that I finally have an opportunity to build something, I want you all to feel that moment of peace with me. Embrace every feeling, every transition that you are going through with my &lt;a href="https://mood-mapdraw.vercel.app/" rel="noopener noreferrer"&gt;Mood Map&lt;/a&gt; app. The application is open-source, and I would love to have your ideas on what else I can add. As for my future plans, I want to make the app more scalable, add more features, and provide an option to generate the sketch while you just sit and paint.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to become a Microsoft MVP</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Fri, 17 Jan 2025 14:58:46 +0000</pubDate>
      <link>https://dev.to/haimantika/how-to-become-a-microsoft-mvp-3jj4</link>
      <guid>https://dev.to/haimantika/how-to-become-a-microsoft-mvp-3jj4</guid>
      <description>&lt;p&gt;The year started with a good news, I received an email from Microsoft saying that I have been selected as an MVP in the web development category.&lt;/p&gt;

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

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



 &lt;/p&gt;

&lt;p&gt;For those of you who aren’t aware of the term, &lt;a href="https://mvp.microsoft.com/en-us/mvp" rel="noopener noreferrer"&gt;Microsoft Most Valued Professionals&lt;/a&gt; is a program by Microsoft to recognize the efforts of technical community members who help in building, creating, advocating, and promoting their products. Unlike any other ambassador program, this program adds weight and can help you in your professional life ahead. Getting in is not easy, and you need to prove your merits/contribution to get selected and also continue contributing to stay an MVP.&lt;/p&gt;

&lt;p&gt;In this article, I will share how I became an MVP, and hoping it can help you prepare, if you are planning to become one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I apply to become an MVP?
&lt;/h2&gt;

&lt;p&gt;You cannot apply to become an MVP. You have to be nominated by an existing MVP or a Microsoft employee to be able to apply to become one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you are interested, you can also DM me with your work on&lt;/em&gt; &lt;a href="https://www.linkedin.com/in/haimantika-mitra/" rel="noopener noreferrer"&gt;&lt;em&gt;LinkedIn&lt;/em&gt;&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href="https://x.com/HaimantikaM" rel="noopener noreferrer"&gt;&lt;em&gt;X(Twitter)&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  When does the application open?
&lt;/h3&gt;

&lt;p&gt;The MVP application stays open throughout the year. Whenever you are ready, ask your referrer to nominate you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the process look like?
&lt;/h2&gt;

&lt;p&gt;Once you have been nominated, you will receive an email with links to a portal where you need to submit proof of the different kinds of contributions you have made to the Microsoft community. This could be blogs, videos, GitHub contributions, projects, or even social media posts. You can submit a maximum of 24 contributions under various categories. Along with that, you will need to answer a few questions about your interest in the program and how you plan to contribute in the future. You will have around 45 days to complete this, and you will get the decision within 90 days.&lt;/p&gt;

&lt;p&gt;For example, I was nominated on September 24th, 2024, had time until November 7th, 2024, to apply, and heard back from the team on January 1st, 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do I get when I become a Microsoft MVP?
&lt;/h2&gt;

&lt;p&gt;There are a LOT of perks that you get as an MVP. Not sharing them all here (let’s save the best for when you get selected 😉)&lt;/p&gt;

&lt;p&gt;Here are some of the perks that I love:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Access to LinkedIn Premium for free for a year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discount on Microsoft certification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The MVP Award kit, the Credly badge, the recommendation letter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Early access to product releases, invite-only meetups, and Microsoft conferences like Build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access to fellow MVPs, Microsoft advocates, and the wider community with an opportunity to build and network with everyone. &lt;em&gt;(I used to be a Microsoft Student Ambassador, and the network can be very helpful. You not only get friends but also people who can motivate you and help you professionally.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tips to keep in mind while applying:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Try to contribute to the Microsoft ecosystem for at least a year. If you've been doing it for longer, that's even better. In my case, I worked extensively with Microsoft Power Platform in 2020 and continued through 2021. A few months later, I started working at Microsoft, then moved to different companies, built many projects with web technologies, and refocused on Microsoft technologies in late 2023. I applied for the MVP program in mid-2024.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even though you can report a maximum of 24 contributions, try to have a few more and keep a list of what you did in a separate sheet for easy tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep your contributions paced out throughout the year. Do not try to do a lot of things in a month and then have no activity for months. This is a volunteering role, and what helps is being consistent throughout the year rather than jampacking everything in a month or two.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to contribute in multiple areas. Writing blogs might be your forte, but also try to make a social media post out of it, or maybe use this content to help a few folks in the Microsoft forums. While this is not mandatory, it is a good practice and shows that you can contribute in multiple areas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;And that’s a wrap for this article. If you have any followup questions, I am just a DM away &lt;a href="https://x.com/HaimantikaM" rel="noopener noreferrer"&gt;@HaimantikaM&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>microsoft</category>
      <category>community</category>
      <category>coding</category>
    </item>
    <item>
      <title>Interpreting Low-Code from the perspective of open-source SPL</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Thu, 09 Nov 2023 13:15:40 +0000</pubDate>
      <link>https://dev.to/haimantika/interpreting-low-code-from-the-perspective-of-open-source-spl-5o0</link>
      <guid>https://dev.to/haimantika/interpreting-low-code-from-the-perspective-of-open-source-spl-5o0</guid>
      <description>&lt;h1&gt;
  
  
  What kind of code is considered low？
&lt;/h1&gt;

&lt;p&gt;In recent years, the term "Low-Code" has gained popularity, giving rise to numerous entrepreneurial teams. Unlike the binary classification of long and short codes, Low-Code introduces the dimensions of high and low codes. Simply put, Low-Code aims to simplify coding, reducing the workload and lowering the expertise requirements for developers.&lt;/p&gt;

&lt;p&gt;In the Low-Code landscape, it's essential to assess the actual codebase. Many self-proclaimed low-code development platforms rely on frameworks and templates, offering simplicity for basic requirements. However, as complexity grows, these platforms often necessitate traditional coding languages like Java or C#.&lt;/p&gt;

&lt;p&gt;The essence of Low-Code lies in minimizing the amount of code, not just relying on templates. While templates address straightforward needs, many businesses require intricate coding solutions. The effectiveness of Low-Code is intricately tied to development efficiency.&lt;/p&gt;

&lt;p&gt;So, what qualifies as Low-Code? Primarily tailored for information system development (MIS), Low-Code is crucial for handling diverse and ever-changing requirements efficiently. In the realm of MIS, the core tasks revolve around Input, Process, and Output (IPO), with coding focusing on the 'Process' aspect, particularly efficient data processing.&lt;/p&gt;

&lt;p&gt;Structured data, prevalent in relational databases, is the primary focus for Low-Code. Java and C# struggle in this domain due to a lack of structured data objects and the inherent complexities of these languages. SQL, while accessible, faces challenges in ordered computation and procedural logic, leading to convoluted code and increased development costs.&lt;/p&gt;

&lt;p&gt;Python offers some relief with Pandas' dataframe, serving as a structured data object. However, Python's integration challenges and the dataframe's matrix-like nature limit its applicability. Scala provides a dataframe option but falls short in professionalism and imposes a learning curve, coupled with complex project environments.&lt;/p&gt;

&lt;p&gt;In conclusion, Low-Code thrives in simplifying code for structured data processing within information systems, offering efficiency benefits. Choosing the right Low-Code solution involves considering the language's proficiency in handling structured data and its overall suitability for complex business requirements.&lt;/p&gt;




&lt;h1&gt;
  
  
  SPL is the low code
&lt;/h1&gt;

&lt;p&gt;Is there not a kind of low enough code?&lt;/p&gt;

&lt;p&gt;Absolutely, there exists a form of code that meets the criteria of being low enough—enter SPL (Structured Process Language) from the open-source esProc.&lt;/p&gt;

&lt;p&gt;SPL emerged from Raqsoft's need for a robust solution in handling intricate operations within reporting tools. Traditional coding in SQL and Java proved challenging, leading Raqsoft to pioneer a new language tailored for these tasks—SPL.&lt;/p&gt;

&lt;p&gt;SPL boasts well-defined structured data objects, capable of efficiently managing both big and small datasets. While incorporating a modest amount of object-oriented syntax, SPL sidesteps esoteric concepts, focusing squarely on streamlined data processing. Resembling the simplicity of early BASIC language in program logic, SPL features fundamental constructs like branches, loops, and subprograms, ensuring ease of comprehension. Notably, SPL excels in supporting complex set and ordered operations, enhancing the simplicity of code composition.&lt;/p&gt;

&lt;p&gt;Let's move beyond words and delve into code. SPL code is structured in a grid, leveraging cells as variable names, a familiar concept for Excel users. Noteworthy characteristics include seamless support for stepwise operations, clear code hierarchy through grid indentation, and robust debugging functionalities. SPL stands as a testament to practical low-code solutions for intricate data operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aEzJhYMK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpz22eorgaaewfl0fktv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aEzJhYMK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpz22eorgaaewfl0fktv.png" alt="Image description" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In SPL, you can even use SQL directly (independent of database):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDate&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-01-01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDate&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2020-12-31'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="nb"&gt;year&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDate&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;  
&lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nb"&gt;year&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderDate&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;  
&lt;span class="k"&gt;having&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dept&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;  
&lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SellerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Eid&lt;/span&gt;

&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;  
&lt;span class="k"&gt;left&lt;/span&gt; &lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;ClientTable&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SPL itself has the process control capability similar to Java, therefore, SPL can achieve the effect of Java + SQL whether there is database or not.&lt;/p&gt;

&lt;p&gt;Let’s compare it with other codes. For example, we want to calculate the maximum consecutive days that a stock keeps rising.&lt;br&gt;
Write it in SQL is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consecutive_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;consecutive_days&lt;/span&gt;
      &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updown_flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;sdate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no_up_days&lt;/span&gt;
            &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;sDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;LAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;sDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                              &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="n"&gt;updown_flag&lt;/span&gt;
                  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="k"&gt;share&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;no_up_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is a bit difficult to understand, right? You can take it as an exercise and think about how it works.&lt;/p&gt;

&lt;p&gt;Coding in Python is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="n"&gt;aapl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;AAPL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlsx&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;continue_inc_days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;max_continue_inc_days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;aapl&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;aapl&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;continue_inc_days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;continue_inc_days&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;max_continue_inc_days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;continue_inc_days&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;max_continue_inc_days&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;continue_inc_days&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;max_continue_inc_days&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_continue_inc_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this logic is not complicated, it is not very simple to code.&lt;/p&gt;

&lt;p&gt;As for Java, we won't try. You can imagine its complexity yourself.&lt;/p&gt;

&lt;p&gt;For the same operation, coding in SPL is as follows:&lt;br&gt;
| Header 1   | &lt;br&gt;
|------------|&lt;br&gt;
|1 =T("d:/AAPL.xlsx") |&lt;br&gt;
|2 =a=0,A1.max(a=if(price&amp;gt;price[-1],a+1,0)) |&lt;/p&gt;

&lt;p&gt;There is no loop statement in this code, because SPL has a large number of strong lambda syntax-style set functions. Many tasks that can only be achieved with loops in other languages can be done with a single statement in SPL.&lt;/p&gt;

&lt;p&gt;SPL solves the serious flaws of SQL, and combines the common advantages of Java and SQL. In addition, SPL can easily support the big data operation and multi-thread parallel computing, but for Python, it will find it at a loss when it encounters such situation. If you are interested in learning more SPL code examples, go to Raqforum.&lt;/p&gt;


&lt;h1&gt;
  
  
  More than a kind of low code
&lt;/h1&gt;

&lt;p&gt;SPL provides perfect data source support; it can support almost all data sources that you may or may not have heard of:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4nF10WkU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdgy6ekc2zp1c0lea0sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4nF10WkU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdgy6ekc2zp1c0lea0sc.png" alt="Image description" width="454" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, it reduces a lot of work load of preparing the data interface and conversion.&lt;/p&gt;

&lt;p&gt;Since SPL is implemented in Java, it is provided with JDBC driver, and can be seamlessly embedded into Java applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.esproc.jdbc.InternalDriver"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;DriverManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jdbc:esproc:local://"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.();&lt;/span&gt;
&lt;span class="nc"&gt;CallableStatement&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareCall&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{call xxxx(?, ?)}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="err"&gt;…&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, SPL can be easily integrated into some application framework. Most developers only need to care about business logic and data structure, and don't even need to understand complex application architecture.&lt;/p&gt;

&lt;p&gt;In particular, for those “low code platforms” without code, they will have real low code after integrating the open-source SPL. Letting template and code to complement each other is a complete low-code platform.&lt;/p&gt;

&lt;p&gt;SPL is also the interpreted-execution dynamic language, and the scripts written can be placed outside the main application. In this way, not only does it reduce the coupling between the script and the main application, but it also brings the benefits of hot swap. After all, the business logic (especially query and report)is often changing. When the requirement changed, it can take effect immediately as long as the script is rewritten, and there is no need to restart the application. If Java code is used in this case, then... (it also shows that Java code is not low at all).&lt;/p&gt;

&lt;p&gt;To know more about SPL, check them out on &lt;a href="https://t.co/OZX5HXjqoz"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://blog.scudata.com/interpreting-low-code-from-the-perspective-of-open-source-spl/"&gt;https://blog.scudata.com/interpreting-low-code-from-the-perspective-of-open-source-spl/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Behind the pull request: tales from the open source world</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Mon, 30 Oct 2023 11:18:23 +0000</pubDate>
      <link>https://dev.to/appwrite/behind-the-pull-request-tales-from-the-open-source-world-19em</link>
      <guid>https://dev.to/appwrite/behind-the-pull-request-tales-from-the-open-source-world-19em</guid>
      <description>&lt;h3&gt;
  
  
  What is Hacktoberfest
&lt;/h3&gt;

&lt;p&gt;In the world of software development, October is more than just a month, it's a season of collaboration, innovation, and celebration. Welcome to Hacktoberfest – a global event that unites tech enthusiasts from every corner of the globe to celebrate open-source software.&lt;/p&gt;

&lt;p&gt;Hacktoberfest isn't just an event; it's a testament to the incredible impact that contributors can make in the open-source community. It's a time when the digital realm comes alive with the buzz of creativity and camaraderie, where individuals of all backgrounds and expertise levels come together to contribute their skills and passion to open-source projects.&lt;/p&gt;

&lt;p&gt;In this blog, we'll explore the significance of Hacktoberfest in the open-source community. We'll highlight how it guides newcomers and seasoned developers toward collaboration and shared knowledge. Additionally, we'll showcase inspiring success stories that exemplify the true spirit of open source.&lt;/p&gt;

&lt;p&gt;Now, let's dive into some real-life stories of contributors who have participated in Hacktoberfest and experienced the transformative power of open-source collaboration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspiring stories from the community
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A journey of discovery and connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first story is from &lt;a href="https://www.linkedin.com/in/sarthakroy2002/"&gt;Sarthak Roy&lt;/a&gt;, who says, “Well, I started using GitHub properly from February 2021. Hacktoberfest was the reason I found out Appwrite and many more orgs/tools/services in 2021 October. Then I started exploring various stuffs and learnt a ton. During Hacktoberfest 2022, I again contributed in multiple projects, including Appwrite. It all started with the hope of getting a swag in 2021, to enjoying open source and contributing. It also helped me connect with some amazing folks. ”&lt;/p&gt;

&lt;p&gt;Sarthak's story highlights the transformative power of Hacktoberfest, from initially participating for the swag to discovering the joy of open source and connecting with amazing people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inspiring journey: From novice to maintainer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, let's hear from &lt;a href="https://www.linkedin.com/in/moumita-podder-663507217/"&gt;Moumita Roy&lt;/a&gt;, who had an amazing experience with Hacktoberfest. In her own words, "Well, first, I participated in Hacktoberfest 2022 after a friend encouraged me to register for it. Before that, I only knew that GitHub was for pushing code. But through Hacktoberfest, I learned about schemas and other terminologies. Since then, I have contributed to numerous open-source projects. I'm grateful to my friend for introducing me to the world of open source. As a student, I'm still learning and excited about Hacktoberfest 2023. This year, I plan to contribute and participate as a maintainer." Now, let's dive into Moumita's inspiring journey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embracing the open-source culture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The final story is from &lt;a href="https://www.linkedin.com/in/krishnendudg/"&gt;Krishnendu Dasgupta&lt;/a&gt; and he says, “One of the best things about Hacktoberfest for me is that it helped me become familiar with and accustomed to the open-source culture. I can still vividly remember Hacktoberfest 2018, when I was asking questions like "What is GitHub?" and learning about version control and collaboration through Git and GitHub. This experience was life-changing, as it continues to enable me to collaborate effectively with my teammates on any project.”&lt;/p&gt;

&lt;p&gt;Krishnendu added: “Another valuable lesson from events like Hacktoberfest is that open source is not just about making significant feature contributions or bringing about major changes. Every contribution matters, as long as it adds value to the main codebase.Last but not least, even if I didn't directly contribute to certain repositories, simply browsing through them made me realize the importance of maintaining good coding practices.”&lt;/p&gt;

&lt;p&gt;He further explained, “Overall, Hacktoberfest is definitely an event worth participating in. It was an eye-opener for me, highlighting the significance of collaboration and creating something great for others!”&lt;/p&gt;

&lt;p&gt;From the above stories, one thing is common: everyone needs to start from somewhere, and for them, that somewhere was Hacktoberfest! If you are someone who is looking to get started in open source, this is your chance!&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips to start contributing
&lt;/h3&gt;

&lt;p&gt;Now that we've heard the inspiring stories of Hacktoberfest contributors, it's time to take the next step and embark on your own journey of contribution. If you're eager to make a meaningful impact in the open-source community, but unsure of where to begin, don't worry – we've got you covered. Starting your journey as a contributor can feel overwhelming, but fear not! &lt;/p&gt;

&lt;p&gt;These tips will help you make the most out of Hacktoberfest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiarize yourself with the official &lt;a href="https://hacktoberfest.com/"&gt;Hacktoberfest&lt;/a&gt; rules.&lt;/li&gt;
&lt;li&gt;Look for projects that align with your interests and skills.&lt;/li&gt;
&lt;li&gt;Choose 1-2 projects and join their communities.&lt;/li&gt;
&lt;li&gt;If you get stuck, don't hesitate to reach out to project maintainers or the community for help.&lt;/li&gt;
&lt;li&gt;Take the time to learn about the project and always read its contribution guidelines before you start.&lt;/li&gt;
&lt;li&gt;Begin with beginner-friendly or good-first issues.&lt;/li&gt;
&lt;li&gt;Provide clear descriptions and comments when documenting your pull requests.&lt;/li&gt;
&lt;li&gt;Lastly, remember to have fun and enjoy the process of contributing to open source. It's a rewarding experience that can lead to personal and professional growth.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are a few projects that are participating in Hacktoberfest this year and you can contribute to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/search?q=owner%3Aappwrite+owner%3Autopia-php+owner%3Aopen-runtimes+label%3Ahacktoberfest+is%3Aopen+is%3Aissue&amp;amp;type=issues&amp;amp;state=open"&gt;Appwrite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/illacloud/illa"&gt;ILLA Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/novuhq/novu/labels/Hacktoberfest"&gt;Novu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find more participating repositories &lt;a href="https://github.com/search?q=hacktoberfest&amp;amp;type=repositories"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Data ownership and Backend-as-a-Service</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Tue, 17 Oct 2023 17:54:01 +0000</pubDate>
      <link>https://dev.to/haimantika/data-ownership-and-backend-as-a-service-1oi7</link>
      <guid>https://dev.to/haimantika/data-ownership-and-backend-as-a-service-1oi7</guid>
      <description>&lt;p&gt;A comment in our product hunt launch triggered an interesting discussion on data ownership when using BaaS (Backend-as-a-Service) platforms. &lt;/p&gt;

&lt;p&gt;We believe open sourced code bases and flexible choice of Cloud providers for database and storage can help, but that may also make the experience more complex and difficult for developers.&lt;/p&gt;

&lt;p&gt;What are trade offs you're willing to make to own more of your data, and what are trade offs you're willing to make for a more integrated and seemless expereince?&lt;/p&gt;

&lt;p&gt;Where would you benefit from more choices when building with a BaaS platform?&lt;/p&gt;

&lt;p&gt;Context: &lt;a href="https://www.producthunt.com/posts/appwrite-cloud-beta?comment=2848192"&gt;https://www.producthunt.com/posts/appwrite-cloud-beta?comment=2848192&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building Apps with Bun and Appwrite</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Fri, 22 Sep 2023 11:26:08 +0000</pubDate>
      <link>https://dev.to/appwrite/building-apps-with-bun-and-appwrite-1k92</link>
      <guid>https://dev.to/appwrite/building-apps-with-bun-and-appwrite-1k92</guid>
      <description>&lt;p&gt;If you are a developer, your definition of &lt;code&gt;bun&lt;/code&gt; must have recently changed. From what we knew to be a round piece of bread, it is now a new runtime in JavaScript, and as Bun claims, it is faster than the rest! In this article, we will find out what Bun really is, how it compares with Node.js and Deno, and how you can build apps with Bun and Appwrite.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Bun?
&lt;/h3&gt;

&lt;p&gt;Bun is an all-in-one JavaScript runtime &amp;amp; toolkit designed for speed, complete with a bundler, &lt;a href="https://bun.sh/docs/cli/test"&gt;test runner&lt;/a&gt;, and Node.js-compatible &lt;a href="https://bun.sh/package-manager"&gt;package manager&lt;/a&gt;. &lt;br&gt;
To install Bun, follow the instructions here 👉 &lt;a href="https://bun.sh/"&gt;bun.sh&lt;/a&gt;&lt;br&gt;
It is built from scratch to serve the modern JavaScript ecosystem. It has three major design goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elegant APIs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cohesive Developer Experience&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may think, what is all the hype about? Building with JavaScript is now faster with Bun, which is production-ready with its latest version 1.0 release.&lt;/p&gt;

&lt;p&gt;Bun lets you read environment variables from a &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/strong&gt; file and utilize the familiar &lt;strong&gt;&lt;code&gt;fetch()&lt;/code&gt;&lt;/strong&gt; method, enabling you to access and handle data from external sources within your application.&lt;/p&gt;

&lt;p&gt;Bun also natively supports TypeScript out of the box. Other than that, it also supports &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.cjs&lt;/code&gt;, &lt;code&gt;.mjs&lt;/code&gt;, &lt;code&gt;.jsx&lt;/code&gt;, and &lt;code&gt;.tsx&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bonus: Bun package manager is known for its speed, offering faster package management as one of its key features. Even if you don't use Bun as a runtime, you can use Bun's built-in package manager, that can significantly speed up your development workflow.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Try it for yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install
&lt;/span&gt;bun add &amp;lt;package&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--dev&lt;/span&gt;|--production|--peer]
bun remove &amp;lt;package&amp;gt;
bun update &amp;lt;package&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The powers of Bun are endless. If you are interested to know more about the capabilities, read the &lt;a href="https://bun.sh/blog/bun-v1.0"&gt;release announcement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is Bun so fast?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bun made some bold decisions to make this happen! It is not because they are using Zig or not using V8 nor because it's machine code. It is because of the mindset to make everything as highly performant as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Other than that, there are things like: While installing a package, Bun doesn’t do a network check to see if it is downloading in the latest version. &lt;code&gt;@latest&lt;/code&gt; tags are effectively ignored in Bun. &lt;/p&gt;

&lt;p&gt;Also, making small adjustments, such as creating a list of labeled pointers instead of keeping the function pointers separately, greatly improved the speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to Appwrite
&lt;/h3&gt;

&lt;p&gt;Explore the capabilities of Bun with &lt;a href="https://appwrite.io/"&gt;Appwrite&lt;/a&gt; - a backend platform to help you minimize time to create value. Appwrite abstracts away the complexities and repetitiveness of building a modern application so you can jump straight to the fun parts, building impactful features. &lt;/p&gt;

&lt;p&gt;We recently released version 1.4, which is packed with a lot of great features ranging from AI command center, one-click migration service, the next generation of Appwrite functions. You can read more about the 1.4 release in our &lt;a href="https://dev.to/appwrite/appwrite-14-brings-command-center-ai-one-click-migrations-and-upgraded-functions-1ch2#:~:text=We've%20just%20released%20Appwrite,even%20better%20security%20for%20users"&gt;announcement article&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Using Appwrite, you can quickly deploy and scale your Bun/JavaScript code base with ease. To achieve that, you can use Appwrite Functions.&lt;/p&gt;

&lt;p&gt;Appwrite Functions is available in multiple languages and runtimes (and Bun is one of them). This gives developers the ability to plug and play with Appwrite in the language of their choice. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitgx5s2e45nfw0f9uyqz.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%2Fitgx5s2e45nfw0f9uyqz.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Appwrite functions are capable of doing more. In our latest release, we have added &lt;code&gt;Function templates&lt;/code&gt;, which means you’ll be able to add Functions engineered by the Appwrite team and community to your Appwrite project. Functions also have their own &lt;code&gt;domain&lt;/code&gt;, either custom or generated by Appwrite. This lets you write Appwrite Functions that act like typical REST endpoints to handle webhooks, custom integrations, or even serve HTML content. Appwrite Functions will now also fit into your existing workflow right alongside the rest of your code as you can deploy them directly from &lt;code&gt;Git&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Integrating Bun in Appwrite
&lt;/h3&gt;

&lt;p&gt;Now that you have been introduced to Bun and Appwrite, it is time to test them out! To use Bun in Appwrite, you need to use the latest version of Appwrite. &lt;/p&gt;

&lt;p&gt;Installing a self-hosted version of Appwrite is pretty straight-forward, all you need to do is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Have Docker installed&lt;/li&gt;
&lt;li&gt;Run the command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/appwrite:/usr/src/code/appwrite:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/appwrite:1.4.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For one-click setups, check out the &lt;a href="https://appwrite.io/docs/self-hosting"&gt;installation docs&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To use Bun in Appwrite, you need to add it to &lt;code&gt;_APP_FUNCTIONS_RUNTIMES&lt;/code&gt; in the &lt;code&gt;.env&lt;/code&gt; file and restart your Appwrite instance with &lt;code&gt;docker compose up -d&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd7lft45xwee9gw42n5cp.jpeg" 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%2Fd7lft45xwee9gw42n5cp.jpeg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, go ahead and create a Bun function using the &lt;a href="https://appwrite.io/docs/command-line"&gt;Appwrite CLI&lt;/a&gt; by running &lt;code&gt;appwrite init function&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Here’s a video showing you how to enable Bun and execute the function👇&lt;/p&gt;

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

&lt;p&gt;Now that your function is set up, let us see some examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Bun aims to provide a consistent and predictable module resolution system that just works. The specialty of Bun is that you can use &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;require&lt;/code&gt; in the same file—they both work all the time.&lt;/p&gt;

&lt;p&gt;Use the following code in your function to test the above statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;lodash&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;underscore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;res&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;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;withLodash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lodash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;without&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;withUnderscore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;without&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="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;The output will be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsby27pak58sux2z1bx8s.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%2Fsby27pak58sux2z1bx8s.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bun supports &lt;code&gt;.jsx&lt;/code&gt; and &lt;code&gt;.tsx&lt;/code&gt; files out of the box. Bun's internal transpiler converts JSX syntax into vanilla JavaScript before execution.&lt;/p&gt;

&lt;p&gt;Let us test with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;res&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;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello World!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Current time is &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:  For the code to work, you need to run &lt;code&gt;bun install react react-dom&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When the function successfully executes, you will get the following output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7il8rft4ujvdqnviyqn.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%2Fz7il8rft4ujvdqnviyqn.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;In this article, we learned about Bun and using it with Appwrite. While we support Node.js, Deno, and Bun within Appwrite, it is up to you to choose which one you want to build with. &lt;/p&gt;

&lt;p&gt;While comparing the performance of these three runtimes with Appwrite, we have come up with some interesting results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build time - Bun is almost 3x faster than Node.js when installing un-cached dependencies for a Next.js project&lt;/li&gt;
&lt;li&gt;Cold-start - Bun is almost 2x faster than Node.js, and 3x faster than Deno&lt;/li&gt;
&lt;li&gt;Warm-start - All runtimes in similar ranges with differences ranging between 1-3ms&lt;/li&gt;
&lt;li&gt;Load testing - All in similar ranges, with Bun and Node.js being the most stable&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Benchmarks above are related to runtime used in Appwrite Functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are some resources to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Appwrite Function Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bun.sh/docs"&gt;Bun Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/appwrite"&gt;Appwrite Discord&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the benchmarks shared above and having the flexibility within Appwrite to build with any runtime, what would be your choice? 👀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Add a Search Function to your application</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Mon, 18 Sep 2023 14:32:04 +0000</pubDate>
      <link>https://dev.to/appwrite/searching-simplified-with-meilisearch-and-appwrite-functions-287i</link>
      <guid>https://dev.to/appwrite/searching-simplified-with-meilisearch-and-appwrite-functions-287i</guid>
      <description>&lt;p&gt;As a part of Appwrite 1.4, one of the new features we have introduced to Appwrite Functions is Function Templates. Function templates are pre-built Appwrite Functions that can be integrated into your Appwrite project with just a few clicks. Using them, you can easily incorporate new features and integrations into your app without writing additional code or managing infrastructure.&lt;/p&gt;

&lt;p&gt;One such integration you can implement using Appwrite Functions is &lt;strong&gt;Searching&lt;/strong&gt; using &lt;strong&gt;Meilisearch&lt;/strong&gt;. In this blog we show how you can use an Appwrite Function Template to integrate search with Meilisearch.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up the Template
&lt;/h1&gt;

&lt;p&gt;Meilisearch is a flexible and powerful user-focused search engine that can be added to any website or application. The purpose of this function template is to sync documents in an Appwrite database collection to a Meilisearch index. Using this function template, users can explore, search, and retrieve information from the connected database collection. Through this template, documents from the Appwrite collection are systematically indexed within Meilisearch.&lt;/p&gt;

&lt;p&gt;To use the function, you need the following set of keys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APPWRITE_KEY - API Key to talk to Appwrite backend APIs.To generate API Keys you can follow the documentation &lt;a href="https://appwrite.io/docs/getting-started-for-server#apiKey"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;APPWRITE_ENDPOINT - To get the Appwrite endpoint, you need to go to &lt;a href="https://cloud.appwrite.io/"&gt;Appwrite&lt;/a&gt; and find it under “Settings”&lt;/li&gt;
&lt;li&gt;APPWRITE_DATABASE_ID - The ID of the Appwrite database that contains the collection to sync. You can find the documentation &lt;a href="https://appwrite.io/docs/databases"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;APPWRITE_COLLECTION_ID - The ID of the collection in the Appwrite database to sync.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use Meilisearch, you can either self-host it using the command 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;https://install.meilisearch.com]&lt;span class="o"&gt;(&lt;/span&gt;https://install.meilisearch.com/&lt;span class="o"&gt;)&lt;/span&gt; | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use &lt;a href="https://www.meilisearch.com/cloud"&gt;Meilisearch Cloud&lt;/a&gt;. For this example, we will assume that you are using Meilisearch Cloud. &lt;/p&gt;

&lt;p&gt;Here’s the keys you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MEILISEARCH_ENDPOINT - This is the host URL of the Meilisearch server. Once you have logged in to Meilisearch Cloud and created a new project, you will find the URL under “Overview” and this is how it should look like 👇&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%2F73s2ed614ks90s6sgaot.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%2F73s2ed614ks90s6sgaot.png" alt="Overview Meilisearch" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; MEILISEARCH_ADMIN_API_KEY - This is the admin API key for Meilisearch. You will find it in the Meilisearch Console under “API Key”. &lt;/li&gt;
&lt;li&gt; MEILISEARCH_SEARCH_API_KEY - This is the API Key for Meilisearch search operations. To get this, you need you create a new index from the Meilisearch Console. Once created you will find it under &lt;code&gt;Overview&lt;/code&gt; as &lt;code&gt;Default Search API Key&lt;/code&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%2F6i30ebit62tcvglm7gn9.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%2F6i30ebit62tcvglm7gn9.png" alt="Creating an index from the Console" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugchdl1zgh8g7enkueea.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%2Fugchdl1zgh8g7enkueea.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MEILISEARCH_INDEX_NAME - Name of the Meilisearch index to which the documents will be synchronized. For e.g, in the above picture, the Index name is &lt;code&gt;Newindex&lt;/code&gt;. You can also find it under &lt;code&gt;Settings&lt;/code&gt; as &lt;code&gt;Index Name&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preparing the Function
&lt;/h2&gt;

&lt;p&gt;The function template syncs documents in an Appwrite database collection to a Meilisearch index. It should get you up and running, but you will need to add real data to build a useful search index.&lt;/p&gt;

&lt;p&gt;If you want to see the source code, you can find it on our &lt;a href="https://github.com/appwrite/templates/tree/main/node/sync-with-meilisearch"&gt;templates GitHub repository&lt;/a&gt;. Now, let’s navigate to our functions page on &lt;strong&gt;&lt;a href="https://cloud.appwrite.io/"&gt;Appwrite&lt;/a&gt;&lt;/strong&gt;. From there, we will select the &lt;strong&gt;Templates&lt;/strong&gt; tab, search for and select the &lt;strong&gt;Sync with Meilisearch&lt;/strong&gt; function template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8snmcbufp27q5kptbua.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%2Fk8snmcbufp27q5kptbua.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The function requires &lt;code&gt;APPWRITE_API_KEY&lt;/code&gt;, &lt;code&gt;APPWRITE_DATABASE_ID&lt;/code&gt;, &lt;code&gt;APPWRITE_COLLECTION_ID&lt;/code&gt; , &lt;code&gt;MEILISEARCH_ENDPOINT&lt;/code&gt;, &lt;code&gt;MEILISEARCH_ADMIN_API_KEY&lt;/code&gt;, &lt;code&gt;MEILISEARCH_SEARCH_API_KEY&lt;/code&gt;, &lt;code&gt;MEILISEARCH_INDEX_NAME&lt;/code&gt;. Once you have added them you can proceed to the Connect step.&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Create a new repository&lt;/strong&gt; (this will generate a GitHub repository for you with the function), and leave the production branch and root settings as default to create this function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn6j1146nyl3js6iswnp.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%2Fcn6j1146nyl3js6iswnp.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing the Template
&lt;/h1&gt;

&lt;p&gt;Visit the &lt;strong&gt;Domains&lt;/strong&gt; tab on the function page and copy the domain URL to test the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fva05oaxklo04x6xh6fka.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%2Fva05oaxklo04x6xh6fka.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We’ve added search functionality to our app and opened up many possibilities to improve the experience of our app’s users.&lt;/p&gt;

&lt;p&gt;How can the &lt;em&gt;template&lt;/em&gt; be extended ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using events to automatically index new collections&lt;/li&gt;
&lt;li&gt;Using weights and other meilisearch features to optimise search such as excluding certain fields from indexing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some examples are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Data Exploration:&lt;/strong&gt; It can be used to provide real-time search capabilities for datasets and data streams, allowing users to explore and analyze data in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Management Systems:&lt;/strong&gt; The function template can be integrated into content management systems (CMS) to facilitate efficient content retrieval for editors and site visitors. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Be sure to check out the other available Function Templates. We’ve created multiple that could be of use in your projects. You can find the &lt;a href="https://github.com/appwrite/templates"&gt;templates GitHub repository here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more information about Appwrite and Appwrite Functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Appwrite Function Docs&lt;/a&gt;&lt;/strong&gt;: These documents provide more information on how to use Appwrite Functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/appwrite/serverless-your-way-unleashing-appwrite-functions-true-potential-2l4f"&gt;Functions Announcement&lt;/a&gt;&lt;/strong&gt;: Read the full announcement on Functions 1.4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://discord.com/invite/appwrite"&gt;Appwrite Discord&lt;/a&gt;&lt;/strong&gt;: Connect with other developers and the Appwrite team for discussion, questions, and collaboration.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Add a URL Shortener Function to Your Application</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Wed, 13 Sep 2023 08:52:49 +0000</pubDate>
      <link>https://dev.to/appwrite/add-a-url-shortener-to-your-application-with-functions-19hl</link>
      <guid>https://dev.to/appwrite/add-a-url-shortener-to-your-application-with-functions-19hl</guid>
      <description>&lt;p&gt;As a part of Appwrite 1.4, one of the new features we have introduced to Appwrite Functions is Function Templates. Function templates are pre-built Appwrite Functions that can be integrated into your Appwrite project with just a few clicks. Using them, you can easily incorporate new features and integrations into your app without writing additional code or managing infrastructure.&lt;/p&gt;

&lt;p&gt;A URL shortener takes a long or complex URL and generates a shorter, more concise version. The primary purpose of a URL shortener function is to make links easier to share, manage, and remember.&lt;br&gt;
For e.g &lt;a href="https://dev.to/appwrite/introducing-appwrite-migrations-effortless-data-migration-from-your-platforms-5dhh"&gt;https://dev.to/appwrite/introducing-appwrite-migrations-effortless-data-migration-from-your-platforms-5dhh&lt;/a&gt; to &lt;a href="http://tinyurl.com/bd5usb3n"&gt;http://tinyurl.com/bd5usb3n&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In this blog, we’ll learn to build a URL shortener using Appwrite Functions template. The template benefits from the built-in scalability, reliability, and security of Appwrite Functions.&lt;/p&gt;

&lt;p&gt;You can find the source code on our &lt;a href="https://github.com/appwrite/templates/tree/main/node/url-shortener"&gt;templates GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Template
&lt;/h2&gt;

&lt;p&gt;To get started, you need to navigate to the functions page on the &lt;strong&gt;&lt;a href="https://appwrite.io/cloud"&gt;Appwrite&lt;/a&gt;&lt;/strong&gt; console. From there, we will select the &lt;strong&gt;Templates&lt;/strong&gt; tab, search for and select the &lt;strong&gt;URL Shortener&lt;/strong&gt; function template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F308fo6122x6ykrkwxj2u.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%2F308fo6122x6ykrkwxj2u.png" alt="functions" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The function requires two variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APPWRITE_API_KEY&lt;/li&gt;
&lt;li&gt;SHORT_BASE_URL&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%2Ftthf0alfwhce03zr6c8b.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%2Ftthf0alfwhce03zr6c8b.png" alt="Appwrite console - adding variables" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have populated those, you can go straight to the &lt;strong&gt;Connect&lt;/strong&gt; step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F014safbw7f71zgl7l3vv.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%2F014safbw7f71zgl7l3vv.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Create a new repository&lt;/strong&gt; (this will generate a GitHub repository for you with the function), and leave the production branch and root settings as default to create this function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Function
&lt;/h2&gt;

&lt;p&gt;Visit the &lt;strong&gt;Domains&lt;/strong&gt; tab on the function page and copy the domain URL to test the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwtl9qvov73r46b10bqn.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%2Fxwtl9qvov73r46b10bqn.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the function URL in your web browser, and you'll see a short url like the one shown below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;URL shorteners often offer additional features such as tracking click-through rates, providing analytics on link usage, and allowing users to customize the shortened URL to some extent.This Function Template can be extended to perform a lot of functionalities. Some examples are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Link Analytics and Tracking:&lt;/strong&gt; Enhance the URL shortener to track click-through rates, geographical location of users, referral sources, and other analytics data. This could provide valuable insights into the popularity and effectiveness of shared links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link Management Dashboard:&lt;/strong&gt; Create a user-friendly dashboard where users can manage their shortened links, view statistics, and perform various actions on their links.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Be sure to check out the other available Function Templates. We’ve created many that could be of use in your projects. You can find the &lt;a href="https://github.com/appwrite/templates"&gt;templates GitHub repository here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more information about Appwrite and Appwrite Functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Appwrite Function Docs&lt;/a&gt;&lt;/strong&gt;: These documents provide more information on how to use Appwrite Functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/appwrite/serverless-your-way-unleashing-appwrite-functions-true-potential-2l4f"&gt;Functions Announcement&lt;/a&gt;&lt;/strong&gt;: Read the full announcement on Functions 1.4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://discord.com/invite/appwrite"&gt;Appwrite Discord&lt;/a&gt;&lt;/strong&gt;: Connect with other developers and the Appwrite team for discussion, questions, and collaboration.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>tutorial</category>
      <category>functions</category>
      <category>git</category>
    </item>
    <item>
      <title>Introducing 1.4 Lightning Hackathon: Functions</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Mon, 11 Sep 2023 11:38:01 +0000</pubDate>
      <link>https://dev.to/appwrite/lightning-hackathon-functions-3fhf</link>
      <guid>https://dev.to/appwrite/lightning-hackathon-functions-3fhf</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/appwrite/serverless-your-way-unleashing-appwrite-functions-true-potential-2l4f"&gt;Appwrite Functions&lt;/a&gt; has just had a fresh upgrade, and we are so excited we are hosting a lightning-round hackathon focusing on functions. It will last 10 days only - but no worries! With our newly released functions, you can add functionality to your application with just a few clicks!&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;No registration is required. Just start coding using function templates!&lt;/li&gt;
&lt;li&gt;Join the Appwrite Discord community in channel #lightninghackathon&lt;/li&gt;
&lt;li&gt;Please choose the MIT license on your GitHub repo.&lt;/li&gt;
&lt;li&gt;Submit your GitHub repo and the requested information here: &lt;a href="https://apwr.dev/LightningHackathon"&gt;https://apwr.dev/LightningHackathon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Submit your project to &lt;a href="https://builtwith.appwrite.io"&gt;https://builtwith.appwrite.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Share your creation on social media using #LightningHackathon and by tagging @appwrite&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key dates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start date: Sept 21st, 2023, 11:00AM CST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End date: Oct 1st, 2023, 11:00AM CST &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rules &amp;amp; Criteria
&lt;/h3&gt;

&lt;p&gt;So, what are the rules for joining the hackathon?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build whatever you like using Appwrite functions.&lt;/li&gt;
&lt;li&gt;You can be part of a team or join individually, but do note there is only one prize per winning team or individual.&lt;/li&gt;
&lt;li&gt;You or your team can submit as many projects as you like, so long as you use Appwrite functions.&lt;/li&gt;
&lt;li&gt;You can use any language or framework.&lt;/li&gt;
&lt;li&gt;Please choose the MIT license on your GitHub repo.&lt;/li&gt;
&lt;li&gt;Submit your repo using this form and share your repo online while tagging Appwrite and using #LightningHackathon.&lt;/li&gt;
&lt;li&gt;Only one person per team has to submit the &lt;a href="https://apwr.dev/LightningHackathon"&gt;Typeform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You are allowed to add as many submissions as you want to increase your chances of winning.&lt;/li&gt;
&lt;li&gt;Some criteria our judges will look out for are creativity, usage of functions, technical components, visually pleasing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prizes
&lt;/h3&gt;

&lt;p&gt;The prizes are a customized Appwriter or an Appwrite t-shirt. Each winning entry will receive one of the prizes. In case you enter as a team, only one prize will be shipped.&lt;/p&gt;

&lt;p&gt;We will have a total of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 winners, each winning one Appwriter keyboard&lt;/li&gt;
&lt;li&gt;10 runner-ups, each winning one Appwrite t-shirt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: We only give out one prize per team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Community help
&lt;/h3&gt;

&lt;p&gt;You can find the Appwrite team and the rest of the community on Discord. We will be here to help you build, find project partners, or just come and hang out and learn! &lt;/p&gt;

&lt;p&gt;In order to get support, you will need to join our #lightning-hackathon Discord channel. &lt;a href="https://appwrite.io/discord"&gt;Join us on Discord.&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;For you to get you started, we collected some useful resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://appwrite.io/docs/functions"&gt;Appwrite Functions Docs&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/appwrite/serverless-your-way-unleashing-appwrite-functions-true-potential-2l4f"&gt;Functions introduced&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite/deploy-a-pdf-generation-service-in-minutes-with-appwrite-functions-4p5f"&gt;PDF Function Template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite/deploy-a-pdf-generation-service-in-minutes-with-appwrite-functions-4p5f"&gt;ChatGPT Function Template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/appwrite/send-whatsapp-messages-with-vonage-and-appwrite-functions-14hp"&gt;WhatsApp x Vonage Function Template&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/templates"&gt;Functions Templates GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/client/functions"&gt;Function Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hackathon</category>
      <category>opensource</category>
      <category>git</category>
    </item>
    <item>
      <title>Less Clicking, More Coding: Appwriter x Command Center</title>
      <dc:creator>haimantika mitra</dc:creator>
      <pubDate>Wed, 30 Aug 2023 15:17:47 +0000</pubDate>
      <link>https://dev.to/appwrite/less-clicking-more-coding-appwriter-x-command-center-37h8</link>
      <guid>https://dev.to/appwrite/less-clicking-more-coding-appwriter-x-command-center-37h8</guid>
      <description>&lt;p&gt;Appwrite 1.4 is here, and with it comes a swag giveaway that we have been working on for a while: the Appwriter, an exclusively designed keyboard that celebrates keyboard shortcuts for Appwrite devs. It fits hand in hand with our newly released &lt;a href="https://dev.to/appwrite/introducing-ai-enhanced-command-center-for-appwrite-console-3lmp"&gt;Command Center with AI assistant&lt;/a&gt; on the Appwrite console.&lt;/p&gt;

&lt;p&gt;In this blog, we will briefly explain why keyboard shortcuts save devs' lives, how the Command Center supports this, examples of commands it triggers, and most of all, how you win one of the exclusive Appwriters?!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Keyboard shortcuts: Dedication to dev experience&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We cannot stress it enough. We are dedicated to the developer experience. We consider it in everything we do, from our social posts to docs to our console, and with the release of our new AI-enhanced Command Center and the keyboard shortcuts it enables, we add to that commitment. &lt;/p&gt;

&lt;p&gt;So let’s take a deeper look at the wonderful world of keyboard shortcuts, according to ChatGPT:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Keyboard shortcuts are essential to developers because they significantly enhance efficiency by enabling quick and seamless execution of tasks without the interruption of navigating menus or reaching for the mouse. They minimize context switching, allowing developers to maintain concentration while coding, and facilitate rapid navigation through codebases, ensuring smooth movement within complex projects.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But let's be honest. We like keyboard shortcuts because hitting a bunch of keys looks cooler than clicking a mouse.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Smoother navigation: Command Center&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://medium.com/appwrite-io/announcing-console-2-0-2e0e96891cb0"&gt;The Appwrite Console&lt;/a&gt; is the main way developers manage their Appwrite instances. Since a lot of time is spent here, we wanted to make this experience as smooth as possible, which led us to build the Command Center. The Command Center is operated from your keyboard to minimize friction and maximize experience. The new feature combines smooth navigation with helpful AI search support to speed up your work. &lt;/p&gt;

&lt;p&gt;Here’s a brief overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Command Center is a menu that contains a large variety of shortcuts to the most used Console-related tasks. You can search through these commands or execute them with shortcuts. Some commands are context-aware, though, and will only appear on certain pages, as some commands may even open up sub-panels to enable advanced functionality.&lt;/li&gt;
&lt;li&gt;With the AI assistant sub-panel, you can ask any Appwrite-related question, and it will answer in detail, fetching information from our public documentation, and giving code snippets where applicable. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Commands without a click&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As we mentioned in our &lt;a href="https://dev.to/appwrite/inside-appwrites-new-command-center-4n0m"&gt;how it’s made blog&lt;/a&gt;, we know using a mouse is an extra action that is rather unwanted, so adding a keyboard-oriented feature that allows you to navigate the Appwrite Console with shortcuts alone will make certain devs very happy. &lt;/p&gt;

&lt;p&gt;So let’s dive into what commands you can use, and how this would work.&lt;/p&gt;

&lt;p&gt;Trigger warning, as we previously mentioned, some commands are context-aware, so you will need to understand which commands trigger what in each screen. In general, but not always, the keys &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;S&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, and &lt;code&gt;F&lt;/code&gt; navigate to &lt;code&gt;Auth&lt;/code&gt;, &lt;code&gt;Storage&lt;/code&gt;, &lt;code&gt;Database&lt;/code&gt;, and &lt;code&gt;Functions&lt;/code&gt; screens. You can press any of these keys to navigate instantly to one of these screens. You will also notice that some commands have keyboard shortcuts next to them. If you press these shortcuts while the Command Center is closed, the command will immediately be executed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fywil532l4kqdpr4pcbh8.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%2Fywil532l4kqdpr4pcbh8.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to be sure you don't forget, we added them as icons to the new Appwriters - more on that later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnxt5j885m2bh1s3bxzd.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%2Fxnxt5j885m2bh1s3bxzd.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In each of these screens, you will see a button to &lt;code&gt;create&lt;/code&gt;, either a &lt;code&gt;User&lt;/code&gt;, &lt;code&gt;Function&lt;/code&gt;, &lt;code&gt;Database&lt;/code&gt;, or &lt;code&gt;Bucket&lt;/code&gt; like in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftekw5wpa737pt74jibi9.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%2Ftekw5wpa737pt74jibi9.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By pressing the &lt;code&gt;C&lt;/code&gt; key, you activate this command and open up the screen where you can create your database in this case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjeczq1vmz52lnvvfmeje.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%2Fjeczq1vmz52lnvvfmeje.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your database a name, we will use &lt;code&gt;Database 1&lt;/code&gt; here and press &lt;code&gt;Enter&lt;/code&gt; to successfully create your database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44889ahk95ze1zc88okg.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%2F44889ahk95ze1zc88okg.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51qgur2jr9oalc8os27l.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%2F51qgur2jr9oalc8os27l.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have your first database set up, you can go on and add your first collection by pressing &lt;code&gt;C&lt;/code&gt; which will show the screen in which you can create your &lt;code&gt;Collection&lt;/code&gt;. Add a &lt;code&gt;Name&lt;/code&gt;, we will call our collection &lt;code&gt;Movies&lt;/code&gt; and press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yuxdk9t74k8jwn9zilq.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%2F1yuxdk9t74k8jwn9zilq.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F022nwgy1g9cyn67gw3jl.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%2F022nwgy1g9cyn67gw3jl.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have a collection within your database! We now want to add &lt;code&gt;Attributes&lt;/code&gt; to our &lt;code&gt;Collections&lt;/code&gt;. For this, we will activate the Command Center using &lt;code&gt;Command&lt;/code&gt; &lt;code&gt;K&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F435nnabxwk51scli57ue.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%2F435nnabxwk51scli57ue.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down using the &lt;code&gt;Arrow&lt;/code&gt; keys to &lt;code&gt;Create attribute&lt;/code&gt; and press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsl4um130ochns3qeh6cw.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%2Fsl4um130ochns3qeh6cw.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we get the option to choose an attribute. You can use the same logic as before using your &lt;code&gt;Arrow&lt;/code&gt; and &lt;code&gt;Enter&lt;/code&gt; keys to navigate to the next screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgn0zaflpesfixro9whbj.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%2Fgn0zaflpesfixro9whbj.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we could run you through each screen of the Appwrite Console, but that wouldn’t be the point of this blog. We just wanted to show you how it works and its capabilities. So, with that in mind, let’s move on to the next part: the AI assistant.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Don’t search, just ask!&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We have all been there, searching endlessly for an answer, while the best way is to ask someone who knows the answer. The same goes for searching on the Appwrite Console. Instead of clicking through the platform, you can just ask the AI. To navigate through the Appwrite Console with AI you activate the Command Center again and navigate to the &lt;code&gt;Ask the AI&lt;/code&gt; field using the &lt;code&gt;Arrow&lt;/code&gt; keys and pressing &lt;code&gt;Enter&lt;/code&gt;, or don't activate the Command Center and just use &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;I&lt;/code&gt;. This will open up the AI sub panel where you can enter your queries and get AI to search &lt;a href="https://appwrite.io/docs"&gt;Appwrite documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zianqnd59h79yg5viae.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%2F6zianqnd59h79yg5viae.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screen shows examples of questions previously asked or you can use the search bar to enter your own query. Now this is still very much an experimental feature and we are looking into adding more capabilities in the future, but for now, you can use the AI to search for answers and save time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmnylpk54vo5pb6hih68.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%2Fzmnylpk54vo5pb6hih68.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, you can enter the query Flutter SDK, and the AI sub-panel will reply on how to get started with the Appwrite Flutter SDK, saving you time searching through the documentation and saving you from context switching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdooubb4of0gufzj263b.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%2Fwdooubb4of0gufzj263b.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or ask how you can add the REST API to your project and get an answer instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frusc2iy6386ikh6s4v2b.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%2Frusc2iy6386ikh6s4v2b.png" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now that you know a bit more about the use of keyboard shortcuts and the Command Center on the Appwrite Console, we hope you are excited to start using the new feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Going beyond: an exclusively designed keyboard 💫&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So what about this Appwriter then? At Appwrite, we love swag, and with the release of the Command Center, we had to do something special to complement the new feature. And what better way to celebrate a keyboard shortcut than an Appwrite mechanical keyboard. (Yes it is mechanical, no the image doesn’t do it justice.)&lt;/p&gt;

&lt;p&gt;As you can see on the design, we added some of the most common icons to the keyboard itself so you can easily recognize what commands those keys trigger. And for obvious reasons, it’s pink.&lt;/p&gt;

&lt;p&gt;We are very excited and cannot wait to get these Appwriters out into the hands of the community, as much as our own! The team has been geeking out about these beauties for a while now, and it’s great to finally be able to share what we have in store, literally. If you don’t win one, you can buy one in the future in our &lt;a href="https://store.appwrite.io/"&gt;swag store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7961ttjm5nlkyna166x8.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%2F7961ttjm5nlkyna166x8.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How you can get yourself An Appwriter 🤩&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;All you have to do is join our giveaway by following these simple steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to our giveaway post on X&lt;/li&gt;
&lt;li&gt;Comment what you plan to build with the Appwriter&lt;/li&gt;
&lt;li&gt;Like &amp;amp; RT the tweet&lt;/li&gt;
&lt;li&gt;And submit your entry here: &lt;a href="https://apwr.dev/keyboard"&gt;https://apwr.dev/keyboard&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will give away three keyboards to three lucky winners, and there also ten Appwrite T-shirts up for grabs!&lt;/p&gt;

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

&lt;p&gt;The Command Center is an exciting addition to our Console, and I hope this article gave you the information you needed to get started with keyboard shortcuts. If you have any feedback or questions, please let us know in the comments, or hop on over to our &lt;a href="https://appwrite.io/discord"&gt;Discord server&lt;/a&gt; to talk with us!&lt;/p&gt;

&lt;p&gt;For those who are curious to learn more about the Command Center and AI assistant, here are more resources for you to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Console repo: &lt;a href="https://github.com/appwrite/console"&gt;https://github.com/appwrite/console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The AI assistant repo: &lt;a href="https://github.com/appwrite/assistant"&gt;https://github.com/appwrite/assistant&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite/introducing-ai-enhanced-command-center-for-appwrite-console-3lmp"&gt;The Command Center and AI assistant product tour&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appwrite/inside-appwrites-new-command-center-4n0m"&gt;A how it’s made blog on the Command Center and AI assistant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And last but not least the &lt;a href="https://appwrite.io/docs"&gt;Appwrite Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
