<?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: Kalpit Rathore</title>
    <description>The latest articles on DEV Community by Kalpit Rathore (@kalpitrathore).</description>
    <link>https://dev.to/kalpitrathore</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F502197%2Fa8062695-b2f0-49e5-8bc4-b9694a0cf829.jpg</url>
      <title>DEV Community: Kalpit Rathore</title>
      <link>https://dev.to/kalpitrathore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kalpitrathore"/>
    <language>en</language>
    <item>
      <title>I type-check AI-generated SDK code against the real package. Claude refused a third of my Stripe tasks.</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Wed, 05 Aug 2026 06:12:31 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/i-type-check-ai-generated-sdk-code-against-the-real-package-claude-refused-a-third-of-my-stripe-1afo</link>
      <guid>https://dev.to/kalpitrathore/i-type-check-ai-generated-sdk-code-against-the-real-package-claude-refused-a-third-of-my-stripe-1afo</guid>
      <description>&lt;p&gt;I build a small tool called SDKProof. It measures whether AI coding agents write a library's &lt;em&gt;current&lt;/em&gt; API or an older one they remember. A model solves 10-15 real tasks, each answer gets dropped into a project with the real installed package, then &lt;code&gt;tsc --noEmit&lt;/code&gt;. Pass = compiles clean. No LLM judging another LLM, the compiler decides.&lt;/p&gt;

&lt;p&gt;Last night I added Stripe to it. First run came back &lt;strong&gt;100/100, 15 of 15&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is not a normal score for a library that shipped two breaking majors in eight days. So before I published anything I opened the raw candidates file.&lt;/p&gt;

&lt;p&gt;Four of the fifteen were empty. Not short. &lt;strong&gt;Empty. Zero bytes.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An empty file compiles clean
&lt;/h2&gt;

&lt;p&gt;Here is the whole bug, and it is embarrassing in how simple it is.&lt;/p&gt;

&lt;p&gt;My verifier writes the model's code to &lt;code&gt;candidate.ts&lt;/code&gt; and runs the TypeScript compiler on it. Zero errors means pass. An empty file produces zero errors. So an empty file was a perfect answer.&lt;/p&gt;

&lt;p&gt;My harness had been quietly converting &lt;em&gt;"the model produced nothing"&lt;/em&gt; into &lt;em&gt;"the model got it right"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;First thing I did was check every other library on the board. Prisma, Zod, the Vercel AI SDK, TanStack Query, Next.js, React Router. &lt;strong&gt;No empty candidates in any of them&lt;/strong&gt;, so the published scores were fine. It only showed up on Stripe because Stripe was the first library where generation was actually failing.&lt;/p&gt;

&lt;p&gt;The fix is four lines and it should have been there from day one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Every task skeleton asks for an export. A candidate with no export&lt;/span&gt;
&lt;span class="c1"&gt;// has not answered. That is a harness failure, not model drift.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;emptyCandidate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;candidate&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="nx"&gt;empty&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;passed&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="na"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SDKP001&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;line&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="na"&gt;column&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="na"&gt;libraryRelated&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="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;code&gt;SDKP001&lt;/code&gt; sits deliberately outside my API-shape error codes, so a broken harness can never be counted as a library problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  So why was it empty?
&lt;/h2&gt;

&lt;p&gt;I logged the raw API response. This is what came back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stop_reason: refusal
block types: thinking
text length: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;stop_reason: "refusal"&lt;/code&gt;. The model declined the task. Not a text refusal you can read, a completion-level one. Which is exactly why it landed in my pipeline as an empty string instead of something obviously wrong.&lt;/p&gt;

&lt;p&gt;The task it refused:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a PaymentIntent for the given amount in USD, letting Stripe decide which payment methods to offer automatically. Return the client secret.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the first example in Stripe's own quickstart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then I did the thing I should have done first
&lt;/h2&gt;

&lt;p&gt;My initial reaction was to write a blog post about it. I had three trials on four tasks. That is not a measurement, that is an anecdote with a chip on its shoulder.&lt;/p&gt;

&lt;p&gt;So I built a proper rig instead. Same prompts my pipeline builds, called directly so my retry logic could not hide anything, &lt;code&gt;stop_reason&lt;/code&gt; recorded and nothing else. 10 trials on every task. And &lt;strong&gt;a control library&lt;/strong&gt;, because "Stripe refuses a lot" means nothing without something to compare it to.&lt;/p&gt;

&lt;p&gt;250 requests, claude-opus-5:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Refused&lt;/th&gt;
&lt;th&gt;Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;stripe&lt;/td&gt;
&lt;td&gt;62/150&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;41.3%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zod&lt;/td&gt;
&lt;td&gt;0/100&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Zero out of a hundred on the control. That is what turns this from a vibe into a result.&lt;/p&gt;

&lt;p&gt;Per task it is a gradient, not a switch:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Refusals&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;payment-intent&lt;/code&gt;, &lt;code&gt;auto-paginate&lt;/code&gt;, &lt;code&gt;connect-account&lt;/code&gt;, &lt;code&gt;per-request-key&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9/10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;expand-customer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4/10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;subscription-create&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3/10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;checkout-session&lt;/code&gt;, &lt;code&gt;decimal-fx-rate&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1/10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;refund-partial&lt;/code&gt;, &lt;code&gt;card-error&lt;/code&gt;, &lt;code&gt;client-config&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0/10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;create-customer&lt;/code&gt;, &lt;code&gt;webhook-verify&lt;/code&gt;, &lt;code&gt;idempotent-create&lt;/code&gt;, &lt;code&gt;invoice-finalize&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The part I did not expect
&lt;/h2&gt;

&lt;p&gt;Look at two rows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take a payment: refused 10 times out of 10.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Issue a refund: refused 1 time out of 10.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same SDK. Same money. Opposite direction.&lt;/p&gt;

&lt;p&gt;It holds elsewhere too. Create &lt;em&gt;a&lt;/em&gt; customer, 0/10. Read &lt;em&gt;every&lt;/em&gt; customer, 10/10. Pull one customer's full record with &lt;code&gt;expand&lt;/code&gt;, 9/10. Use a different API key for one request, 10/10. Verify a webhook signature, finalize an invoice, configure the client, read an FX rate, all basically clean.&lt;/p&gt;

&lt;p&gt;So it is not "Stripe" that is the trigger. It is a fairly specific shape: &lt;strong&gt;moving money toward you, reading customer data in bulk or in full, or acting with credentials that might not be yours.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  My best guess at why, and then I tested it
&lt;/h2&gt;

&lt;p&gt;Here was my theory.&lt;/p&gt;

&lt;p&gt;My harness gives the model &lt;strong&gt;almost no context on purpose&lt;/strong&gt;. One line naming the library, the task, a skeleton. No project, no README, no explanation of who I am or whose Stripe account this is. That is the whole design, it is how you measure what a model &lt;em&gt;reaches for&lt;/em&gt; instead of what it copies from the code around it.&lt;/p&gt;

&lt;p&gt;Now read one of my prompts with nothing else to go on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;List the first five customers that belong to a connected account, given that account's id.&lt;/p&gt;

&lt;p&gt;Retrieve a customer using a different secret key for this one request only.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Stripped of context those are structurally identical to the code half of a fraud task. Nothing says I own this account. A real developer asking this has a repo, a job, a reason. My benchmark has none of that, by design.&lt;/p&gt;

&lt;p&gt;Neat theory. So I wrote the fix: one clause of ownership context on each of the five worst tasks, nothing else touched, same API surface under test.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Our platform onboards sellers as Stripe connected accounts. For the seller's own dashboard&lt;/strong&gt;, list the first five customers belonging to one of our connected accounts...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I ran it as a paired A/B. Both versions of all five tasks in the same batch, interleaved, 10 trials each. That way if the refusal rate drifts over the hour, it drifts on both arms &amp;amp; the comparison survives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payment-intent    v1 10/10   v2 10/10
auto-paginate     v1 10/10   v2 10/10
connect-account   v1 10/10   v2 10/10
per-request-key   v1 10/10   v2 10/10
expand-customer   v1  9/10   v2 10/10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nothing. Not one task moved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The v1 arm reproducing 10/10 is what makes this a real comparison instead of me getting unlucky, &amp;amp; it means my theory is just wrong. Telling the model whose account it is changes nothing. &lt;strong&gt;The trigger is the shape of the operation, not the absence of a stated reason.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take a payment: refused. Say please, explain it is your own checkout, refused. Issue a refund: fine.&lt;/p&gt;

&lt;p&gt;I do not have a better theory. That is where I am.&lt;/p&gt;

&lt;h2&gt;
  
  
  I broke it once more, in the same way
&lt;/h2&gt;

&lt;p&gt;Worth telling on myself here. The first version of my measuring script reported &lt;strong&gt;0% refusals for both libraries&lt;/strong&gt;. Great news, finding retracted, except I believed it for about ten minutes.&lt;/p&gt;

&lt;p&gt;It never loaded &lt;code&gt;.env&lt;/code&gt;. Every single request failed authentication. And my summary counted an errored request as "not refused", so 30 auth failures rendered as a confident, clean zero.&lt;/p&gt;

&lt;p&gt;That is the exact same bug I had just spent two hours fixing in the verifier. A failure showing up as a good result. I wrote it straight into the tool I built to investigate it.&lt;/p&gt;

&lt;p&gt;Now it excludes errored requests from the denominator and refuses to print a percentage at all if more than half the requests failed. Rule I am keeping: &lt;strong&gt;anything that computes a rate should refuse to show you one when its inputs broke.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it leaves me
&lt;/h2&gt;

&lt;p&gt;Stripe is on the board now, at 100/100, with the refusal count on the page above the fold rather than in a footnote. That felt like the only honest way to publish it: the score covers ten of fifteen written tasks &amp;amp; the page says so next to the number.&lt;/p&gt;

&lt;p&gt;I nearly did not publish it at all. What changed my mind is that the three tasks written specifically to catch version drift &lt;strong&gt;all ran &amp;amp; all passed&lt;/strong&gt;. The model writes the exact pinned &lt;code&gt;apiVersion&lt;/code&gt; string literal the installed SDK expects, where any remembered older one is a compile error. It treats &lt;code&gt;decimal_string&lt;/code&gt; fields as &lt;code&gt;Stripe.Decimal&lt;/code&gt;, which v21 changed from &lt;code&gt;string&lt;/code&gt;. It puts &lt;code&gt;idempotencyKey&lt;/code&gt; in the second argument instead of mixing it into params, which is the v22 change. So the 100 is a real measurement, not what was left after the hard tasks fell out.&lt;/p&gt;

&lt;p&gt;Scorecard, refusal table &amp;amp; method: &lt;a href="https://sdkproof.dev/stripe.html" rel="noopener noreferrer"&gt;sdkproof.dev/stripe.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The harness is open source if you want to poke holes in it: &lt;a href="https://github.com/Kalpitrathore/sdkproof" rel="noopener noreferrer"&gt;github.com/Kalpitrathore/sdkproof&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you run something similar &amp;amp; get a different number, I would genuinely like to know.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>testing</category>
      <category>stripe</category>
    </item>
    <item>
      <title>Claude Opus 5 closed last year's SDK gaps — not this year's</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Sun, 26 Jul 2026 20:45:36 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/claude-opus-5-closed-last-years-sdk-gaps-not-this-years-31k3</link>
      <guid>https://dev.to/kalpitrathore/claude-opus-5-closed-last-years-sdk-gaps-not-this-years-31k3</guid>
      <description>&lt;p&gt;A while back I built a small tool called SDKProof. it checks how well an AI coding agent writes an SDK's &lt;em&gt;current&lt;/em&gt; API — the stuff that changed in the last major, that the model tends to get wrong because it learned the old version.&lt;/p&gt;

&lt;p&gt;Claude Opus 5 came out today. so I re-ran the whole board on it.&lt;/p&gt;

&lt;p&gt;short version: it fixed last year's SDKs. it did not fix this year's.&lt;/p&gt;

&lt;h2&gt;
  
  
  The board, now on Opus 5
&lt;/h2&gt;

&lt;p&gt;Same tasks, same libraries, new model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SDK&lt;/th&gt;
&lt;th&gt;shipped its major&lt;/th&gt;
&lt;th&gt;Opus 5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prisma 7&lt;/td&gt;
&lt;td&gt;late 2025 (freshest)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;87&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js 16&lt;/td&gt;
&lt;td&gt;late 2025&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;92&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel AI SDK 7&lt;/td&gt;
&lt;td&gt;mid 2025&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zod 4&lt;/td&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TanStack Query 5&lt;/td&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The way each score works: the model solves ~10–15 real tasks, the code gets type-checked against the real installed package, pass = it compiles. no LLM judging another LLM, the compiler decides.&lt;/p&gt;

&lt;p&gt;The two that jumped: &lt;strong&gt;Vercel AI SDK 7 and Zod 4 were both 90 on the previous model (Opus 4.8). Opus 5 took them to 100.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What flipped
&lt;/h2&gt;

&lt;p&gt;Here's the kind of thing that changed. Define a tool with the AI SDK.&lt;/p&gt;

&lt;p&gt;Opus 4.8 wrote it the old (v4) way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getWeather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;   &lt;span class="c1"&gt;// renamed to inputSchema&lt;/span&gt;
  &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&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;city&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getWeather&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;maxSteps&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="c1"&gt;// removed&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That doesn't compile against &lt;code&gt;ai&lt;/code&gt; v7. &lt;code&gt;parameters&lt;/code&gt; is now &lt;code&gt;inputSchema&lt;/code&gt;, and &lt;code&gt;maxSteps&lt;/code&gt; is gone (it's &lt;code&gt;stopWhen: stepCountIs(5)&lt;/code&gt; now).&lt;/p&gt;

&lt;p&gt;Opus 5 writes the current shape by itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getWeather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&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;city&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getWeather&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;stopWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stepCountIs&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean compile. same for Zod — Opus 4.8 kept reaching for the removed &lt;code&gt;required_error&lt;/code&gt;, Opus 5 writes the new unified &lt;code&gt;error&lt;/code&gt; option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What didn't move
&lt;/h2&gt;

&lt;p&gt;Prisma 7 and Next 16 barely changed. they shipped their breaking changes most recently, and even the newest model hasn't caught up.&lt;/p&gt;

&lt;p&gt;Prisma still writes the pre-v7 client setup — it skips the driver adapter that v7 now requires, and uses the removed &lt;code&gt;datasourceUrl&lt;/code&gt;. Next still calls &lt;code&gt;revalidateTag()&lt;/code&gt; with one argument, when it takes two now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;this is the whole reason SDKProof exists.&lt;/p&gt;

&lt;p&gt;the score isn't about how good the model is. it's about how recently your SDK changed. the newer your last major, the more the model still writes your old API — because that's what it was trained on.&lt;/p&gt;

&lt;p&gt;and the gap moves every time a new model ships. I watched it move today: two SDKs went from 90 to 100 on a model bump. it'll re-open the next time any of these libraries ships a major.&lt;/p&gt;

&lt;p&gt;so if you maintain an SDK, this is a thing to watch, not measure once.&lt;/p&gt;

&lt;h2&gt;
  
  
  One honest note
&lt;/h2&gt;

&lt;p&gt;while re-running this I found a bug in my own harness — the part that pulls code out of the model's reply was grabbing the wrong chunk on one Prisma task &amp;amp; failing it for the wrong reason. fixed it. that's why Prisma reads 87 here and not the 80 from my first post. calling it out so I'm not quietly moving my own goalposts.&lt;/p&gt;




&lt;p&gt;Full board, the exact tasks, and how to add your own SDK: &lt;strong&gt;&lt;a href="https://sdkproof.dev" rel="noopener noreferrer"&gt;https://sdkproof.dev&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Github: &lt;strong&gt;&lt;a href="https://github.com/Kalpitrathore/sdkproof" rel="noopener noreferrer"&gt;https://github.com/Kalpitrathore/sdkproof&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(if you saw my first post on this — same tool, just re-run on the new model.)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>AI coding agents still write your SDK's old API — so I built a type-checker to measure it</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Mon, 20 Jul 2026 19:32:26 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/ai-coding-agents-still-write-your-sdks-old-api-so-i-built-a-type-checker-to-measure-it-alk</link>
      <guid>https://dev.to/kalpitrathore/ai-coding-agents-still-write-your-sdks-old-api-so-i-built-a-type-checker-to-measure-it-alk</guid>
      <description>&lt;p&gt;Here's a bug I kept hitting. I'd ask an AI assistant to write some code against a library — Prisma, the Vercel AI SDK, Zod — and the code would look completely right. Clean, idiomatic, exactly the shape I expected. Then I'd run it, and it wouldn't compile.&lt;/p&gt;

&lt;p&gt;The reason was always the same: the library had shipped a new major version, and the model was writing the &lt;em&gt;previous&lt;/em&gt; major's API from memory. &lt;code&gt;parameters&lt;/code&gt; instead of &lt;code&gt;inputSchema&lt;/code&gt;. &lt;code&gt;required_error&lt;/code&gt; instead of &lt;code&gt;error&lt;/code&gt;. A &lt;code&gt;new PrismaClient({ datasources })&lt;/code&gt; call that no longer exists. Small things — but enough to break the build on the first try.&lt;/p&gt;

&lt;p&gt;Models are frozen at their training cutoff. Libraries are not. So there's a gap between "the API the model reaches for" and "the API you actually have installed" — and that gap is widest right after a library ships a breaking change.&lt;/p&gt;

&lt;p&gt;I wanted to know: &lt;strong&gt;how big is that gap, exactly — and can I measure it objectively?&lt;/strong&gt; So I built &lt;a href="https://sdkproof.dev" rel="noopener noreferrer"&gt;SDKProof&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The method: let the compiler be the judge
&lt;/h2&gt;

&lt;p&gt;The trick to measuring this without hand-waving is to &lt;em&gt;not&lt;/em&gt; use an LLM to grade an LLM. Instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate.&lt;/strong&gt; Have a model solve 10–15 realistic tasks for a given SDK ("define a tool that returns the weather", "make an optional field with a custom error message").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-check.&lt;/strong&gt; Drop each solution into a fixture that has the &lt;em&gt;real, current&lt;/em&gt; package installed, and run &lt;code&gt;tsc --noEmit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score.&lt;/strong&gt; Pass = compiles clean. Fail = the compiler's own diagnostics, classified into failure patterns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No LLM judge. No "looks plausible." The installed package's type definitions are the ground truth, and &lt;code&gt;tsc&lt;/code&gt; is the referee. A pass means the code would actually build against the version you have.&lt;/p&gt;

&lt;p&gt;One design detail that matters: the prompts name the &lt;em&gt;functions&lt;/em&gt; but never the &lt;em&gt;option names&lt;/em&gt;. I ask for "a tool with a description and an input schema," not "use &lt;code&gt;inputSchema&lt;/code&gt;." That way I'm measuring what the model naturally reaches for — not whether it can echo back a name I already handed it.&lt;/p&gt;

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

&lt;p&gt;Running &lt;code&gt;claude-opus-4-8&lt;/code&gt; across three SDKs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SDK&lt;/th&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Where it breaks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prisma 7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@prisma/client&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;80 / 100&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;still writes removed v6 setup — &lt;code&gt;new PrismaClient()&lt;/code&gt; with &lt;code&gt;datasources&lt;/code&gt;, &lt;code&gt;$use&lt;/code&gt; middleware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel AI SDK 7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ai&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;90 / 100&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;old tool wiring — &lt;code&gt;parameters&lt;/code&gt; (now &lt;code&gt;inputSchema&lt;/code&gt;), removed &lt;code&gt;maxSteps&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zod 4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zod&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;90 / 100&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;removed &lt;code&gt;required_error&lt;/code&gt; (now &lt;code&gt;error&lt;/code&gt;) — but nails the new 2-arg &lt;code&gt;z.record()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here's a representative miss. Ask for a tool definition with the AI SDK and you tend to get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tool&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="s1"&gt;ai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&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="s1"&gt;zod&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;weatherTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Get the weather for a city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="c1"&gt;// ✗ this was the v4 API&lt;/span&gt;
  &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&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;city&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;city&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;Looks right. But against &lt;code&gt;ai&lt;/code&gt; v7, &lt;code&gt;tsc&lt;/code&gt; says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error TS2353: Object literal may only specify known properties,
and 'parameters' does not exist in type 'Tool&amp;lt;...&amp;gt;'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the option was renamed to &lt;code&gt;inputSchema&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;weatherTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Get the weather for a city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="c1"&gt;// ✓ v5+&lt;/span&gt;
  &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&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;city&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;city&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;Everything else about the code is fine. It's one renamed key — and it's exactly the kind of thing that slips past a quick read but stops the build cold.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern: readiness tracks the drift window
&lt;/h2&gt;

&lt;p&gt;The interesting part isn't any single score — it's &lt;em&gt;why&lt;/em&gt; they differ.&lt;/p&gt;

&lt;p&gt;Notice the newest breaking change scores worst. The Vercel AI SDK and Zod shipped their renames in 2025; by now the model has largely absorbed them and mostly gets them right (90/100). Prisma 7 is more recent, and the model hasn't caught up (80/100) — it still writes setup calls that were removed.&lt;/p&gt;

&lt;p&gt;That's the whole thesis: &lt;strong&gt;a model's "readiness" for an SDK tracks how recently that SDK changed.&lt;/strong&gt; Which means this isn't a one-time audit. The gap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;re-opens&lt;/strong&gt; every time a library ships a new major, and&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shifts&lt;/strong&gt; every time a model is retrained.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it's something to &lt;em&gt;monitor&lt;/em&gt;, not measure once. A library that scores 95 today can drop to 70 the week it ships v-next — then climb back as the next model generation learns it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;p&gt;I'd rather you trust the number than oversell it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type-check only.&lt;/strong&gt; It measures whether the code uses the real, current API surface — &lt;em&gt;not&lt;/em&gt; whether it runs correctly. Compiling clean ≠ bug-free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One model, for now.&lt;/strong&gt; Comparing across models over time is the plan; a single model is a starting point, not the whole story.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A snapshot.&lt;/strong&gt; Every score is tied to a specific package version and model version. Both move.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that breaks the signal — it just scopes it. "Does the model reach for API surface that still exists?" is a real, useful question, and the compiler answers it without opinion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If you use AI to write code:&lt;/strong&gt; be most skeptical right after a library ships a major. That's exactly when "looks right" and "compiles" diverge. Pin your versions and read the diff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you maintain an SDK:&lt;/strong&gt; the day you ship a breaking major, AI-assisted users hit broken code on their first try — until the models catch up. That's a support-and-perception cost that's currently invisible. SDKProof makes it visible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  It's open source — add your own SDK
&lt;/h2&gt;

&lt;p&gt;Adding an SDK is about an afternoon: install the package, add a &lt;code&gt;tsconfig&lt;/code&gt;, write a tasks file, register it. The harness handles generation, type-checking, and scoring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Board + full breakdowns:&lt;/strong&gt; &lt;a href="https://sdkproof.dev" rel="noopener noreferrer"&gt;sdkproof.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/Kalpitrathore/sdkproof" rel="noopener noreferrer"&gt;github.com/Kalpitrathore/sdkproof&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm looking for the next SDKs to score. &lt;strong&gt;What library have you watched an AI assistant get wrong since its last major?&lt;/strong&gt; Tell me and I'll run it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing Adashta: Server-Side Real-Time Charting &amp; More</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Wed, 05 Jun 2024 22:10:59 +0000</pubDate>
      <link>https://dev.to/adashta/introducing-adashta-server-side-real-time-charting-more-2jb3</link>
      <guid>https://dev.to/adashta/introducing-adashta-server-side-real-time-charting-more-2jb3</guid>
      <description>&lt;p&gt;We are thrilled to announce the launch of Adashta, an advanced SDK designed to simplify real-time communication for developers. With Adashta, you can focus on your core business logic while we handle the intricacies of real-time data streaming. Our goal is to make it easier than ever to integrate real-time functionalities into your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Adashta?
&lt;/h2&gt;

&lt;p&gt;In the ever-evolving landscape of web development, real-time communication has become a critical component for delivering dynamic and responsive user experiences. Whether you're building a live data dashboard, a collaborative tool, or a real-time notification system, Adashta has you covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adashta Charts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvnq57rr0iq82w0b7b5c9.gif" 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%2Fvnq57rr0iq82w0b7b5c9.gif" alt="Adashta Charts" width="600" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of Adashta's standout features is Adashta Charts, &lt;strong&gt;a server-side charting solution&lt;/strong&gt; that enables you to create real-time charts with little to no frontend coding. With Adashta Charts, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate various chart types, including line, bar, and pie charts.&lt;/li&gt;
&lt;li&gt;Update charts in real-time with new data from server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Server-Side Installation and Initialization
&lt;/h3&gt;

&lt;p&gt;To get started with Adashta on the server side, follow these simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Adashta via npm:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;adashta
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialize Adashta:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Adashta&lt;/span&gt; &lt;span class="p"&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="s1"&gt;adashta&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;adashta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Adashta&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;adashtaHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;adashtaPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3011&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;loadAdashta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;clientId&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Client connected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disconnection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;clientId&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Client disconnected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;loadAdashta&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Client-Side Integration
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Include Adashta SDK in Your HTML:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Adashta&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="s1"&gt;https://cdn.skypack.dev/adashta-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialize Adashta in the Client:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adashta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Adashta&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;adashtaHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;adashtaPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3011&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No extra configuration is needed on the client side. Adashta will automatically connect to the server and handle real-time communication between the server and client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Real-Time Charts
&lt;/h3&gt;

&lt;p&gt;Wooho! You're all set up with Adashta on the server and client sides. Now, let's see how you can create real-time charts with Adashta Charts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Define Your Chart:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;chartId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dummy-company-stock-chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;labels&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="s1"&gt;Day 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dummy Company Stock Price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;borderWidth&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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;display&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Share Price ($)&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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;display&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Days&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;autoSkip&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;maxTicksLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Send Chart Data to Client:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charts&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update Chart Data:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Day &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;days&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="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;datasets&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getRandomInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charts&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Complete Example:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Adashta&lt;/span&gt; &lt;span class="p"&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="s1"&gt;adashta&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;adashta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Adashta&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;adashtaHost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;adashtaPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3011&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;loadAdashta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientIdInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;clientId&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;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;chartId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dummy-company-stock-chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;labels&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="s1"&gt;Day 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dummy Company Stock Price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="na"&gt;borderWidth&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="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;display&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Share Price ($)&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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;display&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Days&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;autoSkip&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;maxTicksLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charts&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;clientIdInterval&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Day &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;days&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="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;datasets&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getRandomInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charts&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="o"&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;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;adashta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disconnection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;clientId&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="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIdInterval&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;clientIdInterval&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Client disconnected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getRandomInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&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="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="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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;loadAdashta&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run Your Adashta Server:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open Your HTML File in a Browser: HTTP server is required to serve the HTML file. You can use &lt;code&gt;http-server&lt;/code&gt; or any other HTTP server of your choice.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With Adashta, integrating real-time charts into your application has never been easier. You can dynamically update charts with new data, providing users with up-to-the-minute information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Adashta Community
&lt;/h2&gt;

&lt;p&gt;Adashta is an open-source project, and we welcome contributions and feedback from the developer community. If you have any questions or suggestions, please feel free to reach out to us at &lt;a href="mailto:hello@adashta.co"&gt;hello@adashta.co&lt;/a&gt;. You can also contribute to the project by visiting our &lt;a href="https://github.com/adashta/adashta" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; repository.&lt;/p&gt;

&lt;p&gt;We are excited to see how you will use Adashta to create engaging, real-time experiences for your users. Thank you for choosing Adashta, and happy coding!&lt;/p&gt;

&lt;p&gt;Feel free to share your thoughts and experiences with Adashta in the comments below. We're eager to hear how Adashta is making a difference in your projects!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to get time spent by users on a webpage using Node.js?</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Sat, 08 May 2021 17:24:28 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/how-to-get-time-spent-by-users-on-a-webpage-using-node-js-530f</link>
      <guid>https://dev.to/kalpitrathore/how-to-get-time-spent-by-users-on-a-webpage-using-node-js-530f</guid>
      <description>&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%2F1u00tt9x8gymt3uygo5r.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%2F1u00tt9x8gymt3uygo5r.png" alt="Alt Text" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As the internet users increasing exponentially, It is very important for enterprises to know how a user interacts with their website so that they can improve user experience accordingly.&lt;/p&gt;

&lt;p&gt;In this article, We will be going to talk about how to get time spent by users on a webpage using simple Javascript and Node.js. At first, We will try to understand the concept or working behind it then will implement it using code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Working
&lt;/h2&gt;

&lt;p&gt;Before deep dive into the code, Let's try to understand the working behind it with the help of the below flow chart.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngube2wayp2xty8asfpj.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%2Fngube2wayp2xty8asfpj.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Let's get some hands dirty on code.&lt;/p&gt;

&lt;p&gt;1) Create a project folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir time-spent-by-user &amp;amp;&amp;amp; cd time-spent-by-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Initialize npm in the folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Install the required dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
npm install --save ejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Create an "app.js" file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//app.js
const express = require('express');
const ejs = require('ejs');
const bodyParser= require('body-parser');
const app = express()
const port = 80

app.set('view engine', 'ejs');
app.use(bodyParser.json());

var analytics = {};

// It will render home page
app.get('/', (req, res) =&amp;gt; {    
    res.render('index');
})
// ------------------------

// It will render dashboard page
app.get('/dashboard', (req, res) =&amp;gt; {
    res.render('dashboard', {"analytics": analytics});
})
// ------------------------

// It will catch the data sent from "sendBeacon" method on home page
app.post('/updatetimespentonpage', bodyParser.text(), function(req,res){  
    var body = JSON.parse(req.body)    
    analytics[body["uid"]] = (analytics[body["uid"]]) ? (analytics[body["uid"]] + body["timeSpentOnPage"]) : (body["timeSpentOnPage"]);
    res.send({"status": "done"});
});

app.listen(port, () =&amp;gt; {
  console.log(`App listening at http://localhost:${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Create a "views" folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views &amp;amp;&amp;amp; cd views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) Create an "index.ejs" file in the views folder &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--index.ejs--&amp;gt;
&amp;lt;html&amp;gt;
   &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;Home page&amp;lt;/title&amp;gt;
   &amp;lt;/head&amp;gt;
   &amp;lt;body&amp;gt;
      User Id: &amp;lt;span id="uid"&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;/br&amp;gt;
      Time spent on this page: &amp;lt;span id="time-spent"&amp;gt;0s&amp;lt;/span&amp;gt;
   &amp;lt;/body&amp;gt;
   &amp;lt;script type="text/javascript"&amp;gt;

    // Check if uid already exist in cookie.     
    if (!getCookie("uid")) {

        // if not, then create a new uid and store it in cookie.
        document.cookie = "uid=U" + (Date.now().toString(36)).toUpperCase() + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
    }
    // -------------------------------------------

    document.getElementById('uid').innerHTML = getCookie("uid");


    // This setInterval function increment the value of "timeSpent" variable each second.
    var timeSpent = 0;
    var timeSpentInterval = setInterval(
        function() {
            timeSpent++;
            document.getElementById('time-spent').innerHTML = timeSpent + "s";
        }, 1000);
    // ---------------------------------------------

    // The beforeunload event triggers right before unloading of the window has begun
    window.addEventListener("beforeunload", function() {

        // When user close or refresh the web page, sendBeacon method asynchronously sends a small amount of data over HTTP to a web server.
        navigator.sendBeacon('http://localhost/updatetimespentonpage', JSON.stringify({
            uid: getCookie("uid"),
            timeSpentOnPage: timeSpent
        }))
    });
    // ---------------------------------------------

    // Method used to get cookie
    function getCookie(cname) {
        var name = cname + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var ca = decodedCookie.split(';');
        for (var i = 0; i &amp;lt; ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return "";
    }
    // -----------------------------------
   &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) Create "dashboard.ejs" file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--dashboard.ejs--&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Dashboard&amp;lt;/title&amp;gt;
        &amp;lt;style type="text/css"&amp;gt;
            table, th, td {
                border: 1px solid black;
                border-collapse: collapse;
                padding: 10px;
            }
        &amp;lt;/style&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h2&amp;gt;Dashboard&amp;lt;/h2&amp;gt;
        &amp;lt;table&amp;gt;
            &amp;lt;tr&amp;gt;                
                &amp;lt;th&amp;gt;User Id&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Time Spent&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;            
                &amp;lt;%  
                    var total_time_spent = 0                    
                    for(i in analytics)
                    {
                        %&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;%= i %&amp;gt;&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;%= analytics[i] %&amp;gt;s&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;%
                            total_time_spent = total_time_spent + analytics[i];
                    }
                %&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;%
                        if(Object.keys(analytics).length&amp;gt;0){
                    %&amp;gt;
                        &amp;lt;th&amp;gt;Total Users: &amp;lt;%= Object.keys(analytics).length %&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Avg Time Spent: &amp;lt;%= (total_time_spent/Object.keys(analytics).length).toFixed(2) %&amp;gt;s&amp;lt;/th&amp;gt;
                    &amp;lt;%
                        }
                        else{
                    %&amp;gt;
                        &amp;lt;td&amp;gt;NA&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;NA&amp;lt;/td&amp;gt;
                    &amp;lt;%
                        }
                    %&amp;gt;
                &amp;lt;/tr&amp;gt;            
        &amp;lt;/table&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8) Execute the "app.js" file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//if you are inside the views folder
cd ..
node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) Open a browser &amp;amp; point to &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt;, It will show you "UID" &amp;amp; time spent by you on the webpage.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rdc23tkos0hei6wnbeb.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%2F0rdc23tkos0hei6wnbeb.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10) Now, Close the browser tab &amp;amp; point to &lt;a href="http://localhost/dashboard" rel="noopener noreferrer"&gt;http://localhost/dashboard&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3dz9w5uzblnuo1f4uak.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%2Fw3dz9w5uzblnuo1f4uak.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;11) Here you can see the list of all the users with their corresponding time spent on the page.&lt;/p&gt;

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

&lt;p&gt;When the user closes or refreshes the home page, It fires the "beforeunload" event &amp;amp; lets the "sendBeacon" method send the time spent data to the server asynchronously. The server catches the data &amp;amp; store it in a variable (You can use a traditional database as well).&lt;/p&gt;

&lt;p&gt;sendBeacon is intended to be used for sending analytics data to a web server, &amp;amp; avoids some of the problems with legacy techniques for sending analytics, Such as the use of XMLHttpRequest, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon" rel="noopener noreferrer"&gt;Read more here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/Kalpitrathore/time-spent-by-user-on-website" rel="noopener noreferrer"&gt;github&lt;/a&gt; code if you'd like to get sample implementation.&lt;/p&gt;

&lt;p&gt;For more updates, follow me on &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>saas</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Working with extremely large numbers in JavaScript</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Sat, 13 Mar 2021 13:55:30 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/working-with-extremely-large-numbers-in-javascript-21g8</link>
      <guid>https://dev.to/kalpitrathore/working-with-extremely-large-numbers-in-javascript-21g8</guid>
      <description>&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%2F73kory8rcobw1rtlaaz0.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%2F73kory8rcobw1rtlaaz0.jpeg" alt="Alt Text" width="641" height="718"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, we will going to work on extremely large numbers to get precise answers&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;JavaScript has a limitation it only allows precision of about 16 digits for the number format.&lt;/p&gt;

&lt;p&gt;Minimum &amp;amp; maximum value that a number can go to without losing precision is &lt;code&gt;-2^53&amp;lt;= x &amp;lt;=2^53&lt;/code&gt;, &lt;em&gt;where 2^53 = 9007199254740992&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If we go beyond this limit then we'll lose precision.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(1000000000000011112); // =&amp;gt; 1000000000000011100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This impreciseness affect arithmetic operations as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(10000000000000001+1) // =&amp;gt; 10000000000000000
console.log(10000000000000002-1) // =&amp;gt; 10000000000000000
console.log(10000000000000002*3) // =&amp;gt; 30000000000000010
console.log(10000000000000001==10000000000000000) // =&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is difficult to get answers from arithmetic operations of large integers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;To solve this impreciseness, We have created a library called &lt;strong&gt;sateek.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The word &lt;em&gt;sateek&lt;/em&gt; means exact or precise in hindi language.&lt;/p&gt;

&lt;p&gt;To use this library, Encode your large integer in a string format &amp;amp; call the functions provided by sateek.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.add("10000000000000001", "1"); // =&amp;gt; 10000000000000002
sateek.subtract("10000000000000002", "1"); // =&amp;gt; 10000000000000001
sateek.multiply("10000000000000002", "3"); // =&amp;gt; 30000000000000006
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns output in string format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Sateek.js is available on &lt;a href="https://github.com/Kalpitrathore/sateek" rel="noopener noreferrer"&gt;github&lt;/a&gt; &amp;amp; &lt;a href="https://www.npmjs.com/package/sateek" rel="noopener noreferrer"&gt;npm&lt;/a&gt; or you can simply add it's &lt;a href="https://cdn.skypack.dev/sateek" rel="noopener noreferrer"&gt;CDN&lt;/a&gt; to your JavaScript file.&lt;/p&gt;

&lt;h5&gt;
  
  
  Node.js
&lt;/h5&gt;

&lt;p&gt;1) To use this library, You need to install &lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; &amp;amp; &lt;a href="https://www.npmjs.com/get-npm" rel="noopener noreferrer"&gt;npm&lt;/a&gt;.&lt;br&gt;
2) Now run the following command in your project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save sateek
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Import sateek.js library in your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var sateek = require('sateek')();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  JavaScript
&lt;/h5&gt;

&lt;p&gt;1) Create a HTML file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;body&amp;gt;

    &amp;lt;/body&amp;gt;    
    &amp;lt;script type="module"&amp;gt;
        import sateekModule from 'https://cdn.skypack.dev/sateek';
        const sateek = sateekModule();
        console.log(sateek.add("10000000000000002", "3"));
    &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Sateek.js offers 5 functions.&lt;br&gt;
1) add(n1,n2);&lt;br&gt;
2) subtract(n1,n2);&lt;br&gt;
3) divide(n1,n2);&lt;br&gt;
4) compare(n1,n2);&lt;/p&gt;

&lt;p&gt;Where &lt;em&gt;n1&lt;/em&gt; &amp;amp; &lt;em&gt;n2&lt;/em&gt; are two numbers encoded in string format.&lt;/p&gt;

&lt;h5&gt;
  
  
  Add
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.add("10000000000000001", "1"); // =&amp;gt; 10000000000000002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Subtract
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.subtract("10000000000000002", "1"); // =&amp;gt; 10000000000000001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Multiply
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.multiply("10000000000000002", "3"); // =&amp;gt; 30000000000000006
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Divide
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.divide("20000000000000022", "2"); // =&amp;gt; 10000000000000011
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Compare
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sateek.compare("10000000000000001", "10000000000000000"); // =&amp;gt; 1

sateek.compare("10000000000000000", "10000000000000001"); // =&amp;gt; -1

sateek.compare("10000000000000001", "10000000000000001"); // =&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if n1&amp;gt;n2, it returns 1&lt;br&gt;
if n1&amp;lt;n2, it returns -1&lt;br&gt;
if n1==n2, it returns 0&lt;/p&gt;

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

&lt;p&gt;Every library has it's own advantages &amp;amp; limitations. Here are some limitations of sateek.js library.&lt;/p&gt;

&lt;p&gt;1) Sateek.js focuses more on precision as compare to efficiency.&lt;br&gt;
2) It only work with integers.&lt;br&gt;
3) Division operation only work when dividend is greater than divisor.&lt;br&gt;
4) Division operation only returns quotient.&lt;/p&gt;

&lt;p&gt;We have tested this library with large test cases, Still if you found any issue feel free to report it on github/npm or mail me at &lt;a href="mailto:kalpitrathore@gmail.com"&gt;kalpitrathore@gmail.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

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

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



&lt;br&gt;
For daily updates like this, Follow me on &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>productivity</category>
      <category>node</category>
      <category>saas</category>
    </item>
    <item>
      <title>Various Ways of Real-Time Data Communication in Node.js</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Sat, 06 Feb 2021 16:17:33 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/various-ways-of-real-time-data-communication-in-node-js-1h2b</link>
      <guid>https://dev.to/kalpitrathore/various-ways-of-real-time-data-communication-in-node-js-1h2b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, We will going to talk about various ways of Real-Time Data Communication techniques. &lt;/p&gt;

&lt;p&gt;Real-Time Communication is a mode of telecommunication where all the connected clients can exchange information instantly or with negligible transmission delay. There are various techniques by which, We can exchange information between client &amp;amp; server in real-time, Some are:-&lt;/p&gt;

&lt;h2&gt;
  
  
  Techniques
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Polling&lt;/li&gt;
&lt;li&gt;Server Sent Events&lt;/li&gt;
&lt;li&gt;Web Sockets&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%2Fi%2Fejq4nvu0a560j5hyh7wp.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%2Fi%2Fejq4nvu0a560j5hyh7wp.png" alt="Alt Text" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Polling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is a type of "Client Pull" architecture where client constantly request the server for updates at certain regular intervals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client waits for a particular time, then request the server for new updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is kind of half-duplex or unidirectional communication, Where only one direction transmission is allowed at a time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is based on HTTP protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;High latency transmission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browser Support: To receive or send "Polling" updates at the client side, We will use XMLHttpRequest JavaScript API whose browser support can be found on &lt;a href="https://caniuse.com/mdn-api_xmlhttprequest" rel="noopener noreferrer"&gt;caniuse&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's implement this technique in Node.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1) Open a terminal &amp;amp; create a folder &lt;em&gt;polling&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir polling &amp;amp;&amp;amp; cd polling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Now initialize npm in the folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Create &lt;em&gt;app.js&lt;/em&gt; file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 80

app.use('/', express.static('public'));

var data = "Real-Time Update 1";
var number = 1;

app.get('/', (req, res) =&amp;gt; {
  res.send({"update": data})
});

var interval = setInterval(function(){
    data = "Real-Time Update "+number;
    console.log("SENT: "+data);
    number++;
}, randomInteger(2,9)*1000);

function randomInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}  

app.listen(port, () =&amp;gt; {
  console.log(`Listening at http://localhost:${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Install the required dependencies or libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Create &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir public &amp;amp;&amp;amp; cd public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) Create &lt;em&gt;html&lt;/em&gt; folder inside &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir html &amp;amp;&amp;amp; cd html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) Create &lt;em&gt;index.html&lt;/em&gt; file inside the public folder &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Polling&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div id="updates"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;

        var interval = setInterval(function(){
            getUpdates();
        }, 5000);

        function getUpdates()
        {
            var xhr = new XMLHttpRequest();
            xhr.open("GET", "/", true);
            xhr.onload = function (e) {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {                    
                    document.getElementById('updates').innerHTML = document.getElementById('updates').innerHTML + "Received: "+JSON.parse(xhr.responseText).update+"&amp;lt;/br&amp;gt;";
                }
            }
            };
            xhr.onerror = function (e) {
                console.error(xhr.statusText);
            };
            xhr.send(null);
        }
    &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8) Execute &lt;em&gt;app.js&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//if you are inside html folder then go to your root project directory
cd ../..

//Now execute the app.js file
node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) Open a browser &amp;amp; point to &lt;a href="http://localhost/html/index.html" rel="noopener noreferrer"&gt;http://localhost/html/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have successfully implemented the &lt;em&gt;Polling&lt;/em&gt; technique in Node.js. As you can see it's transmission latency is very high.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Server Sent Events
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is a type of "Server Push" architecture, Where server instantly pushes the updates to client whenever it receives new information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initially client sends the handshake request to server, After handshaking or establishing the connection, Client is not allowed to send data to server, Only server can push updates to client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is a kind of half-duplex or unidirectional communication. But after handshaking, only server is allowed to send data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is based on HTTP protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide low latency transmission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To receive or send "Server Sent Events" updates at client side, We will going to use EventSource JavaScript API whose browser support can be found on &lt;a href="https://caniuse.com/mdn-api_eventsource" rel="noopener noreferrer"&gt;caniuse&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's implement this technique in Node.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1) Open a terminal &amp;amp; create a folder &lt;em&gt;server-sent-events&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir server-sent-events &amp;amp;&amp;amp; cd server-sent-events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Now initialize npm in the folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Create &lt;em&gt;app.js&lt;/em&gt; file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 80

app.use('/', express.static('public'));

var data = "Real-Time Update 1";
var number = 1;

app.get('/server-sent-events', function(req, res) {

    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    var interval = setInterval(function(){
        data = "Real-Time Update "+number;
        console.log("SENT: "+data);
        res.write("data: " + data + "\n\n")
        number++;
    }, randomInteger(2,9)*1000);

    // close
    res.on('close', () =&amp;gt; {
        clearInterval(interval);
        res.end();
    });
})

function randomInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}  

app.listen(port, () =&amp;gt; {
  console.log(`Listening at http://localhost:${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Install the required dependencies or libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Create &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir public &amp;amp;&amp;amp; cd public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) Create &lt;em&gt;html&lt;/em&gt; folder inside &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir html &amp;amp;&amp;amp; cd html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) Create &lt;em&gt;index.html&lt;/em&gt; file inside the public folder &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Server Sent Events&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div id="updates"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;    

        var source = new EventSource('/server-sent-events')

        source.addEventListener('message', function(e) {            
            document.getElementById('updates').innerHTML = document.getElementById('updates').innerHTML + "Received: "+e.data+"&amp;lt;/br&amp;gt;";
        }, false)

    &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8) Execute &lt;em&gt;app.js&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//if you are inside html folder then go to your root project directory
cd ../..

//Now execute the app.js file
node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) Open a browser &amp;amp; point to &lt;a href="http://localhost/html/index.html" rel="noopener noreferrer"&gt;http://localhost/html/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have successfully implemented the &lt;em&gt;Server Sent Events&lt;/em&gt; technique in Node.js. We can use this protocol where "Server to Client Transmission" is our only concern.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Web Sockets
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is a type of "Server Push" architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After handshaking, both client &amp;amp; server are allowed to send or receive information at any time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is a kind of full-duplex or bidirectional communication where both client &amp;amp; server transmit &amp;amp; receive information simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is based on HTTP &amp;amp; TCP/IP Protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide low latency transmission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To receive or send "Web Sockets" updates at client side, We will going to use WebSocket JavaScript API whose browser support can be found on &lt;a href="https://caniuse.com/mdn-api_websocket" rel="noopener noreferrer"&gt;caniuse&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's implement this technique in Node.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1) Open a terminal &amp;amp; create a folder &lt;em&gt;websockets&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir websockets &amp;amp;&amp;amp; cd websockets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Now initialize npm in the folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Create &lt;em&gt;app.js&lt;/em&gt; file &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const http = require('http')
const express = require('express')
const WebSocket = require('ws')
const app = express()
const port = 80

app.use('/', express.static('public'));

const server = http.createServer(app);
const wss = new WebSocket.Server({ server })

var data = "Real-Time Update 1";
var number = 1;

wss.on('connection', ws =&amp;gt; {

  ws.on('message', message =&amp;gt; {
    console.log(`Received message =&amp;gt; ${message}`)
  })

  var interval = setInterval(function(){
    data = "Real-Time Update "+number;
    console.log("SENT: "+data);
    ws.send(data)
    number++;
  }, randomInteger(2,9)*1000);  

  ws.on('close', function close() {
    clearInterval(interval);
  });
})

function randomInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}  

server.listen(port, () =&amp;gt; {
  console.log(`Listening at http://localhost:${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Install the required dependencies or libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
npm install --save ws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Create &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir public &amp;amp;&amp;amp; cd public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) Create &lt;em&gt;html&lt;/em&gt; folder inside &lt;em&gt;public&lt;/em&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir html &amp;amp;&amp;amp; cd html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) Create &lt;em&gt;index.html&lt;/em&gt; file inside the public folder &amp;amp; write some code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Server Sent Events&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div id="updates"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;    

        const connection = new WebSocket('ws://localhost:80')

        connection.onmessage = e =&amp;gt; {
            document.getElementById('updates').innerHTML = document.getElementById('updates').innerHTML + "Received: "+e.data+"&amp;lt;/br&amp;gt;";
        }

    &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8) Execute &lt;em&gt;app.js&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//if you are inside html folder then go to your root project directory
cd ../..

//Now execute the app.js file
node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) Open a browser &amp;amp; point to &lt;a href="http://localhost/html/index.html" rel="noopener noreferrer"&gt;http://localhost/html/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have successfully implemented the &lt;em&gt;Web Socket&lt;/em&gt; technique in Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsjyt6xl0rzi1c5gxlrxl.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%2Fi%2Fsjyt6xl0rzi1c5gxlrxl.png" alt="Alt Text" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;There are the most used techniques we have disscussed, Apart from these there are hundreds of techniques available for real-time data transmission.&lt;/p&gt;

&lt;p&gt;You can find whole project on &lt;a href="https://github.com/Kalpitrathore/nodejs-realtime-communication-types.git" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more update, Follow me on &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/Kalpitrathore" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>productivity</category>
      <category>saas</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What the node.js project structure should look like?</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Fri, 08 Jan 2021 18:49:09 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/what-the-node-js-project-structure-should-look-like-2noo</link>
      <guid>https://dev.to/kalpitrathore/what-the-node-js-project-structure-should-look-like-2noo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, we will going to talk about organizing node.js project in a structured way.&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%2Fi%2F62hwsju098k925z6tw4c.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%2Fi%2F62hwsju098k925z6tw4c.png" alt="Alt Text" width="552" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Organized project structure reduces bugs &amp;amp; delicacy, Increases the stability &amp;amp; scalability of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--app.js
|--api-routes
|--config
|--data
|--jobs
|--loaders
|--node_modules
|--public
|--secrets
|--services
|--views
|--package-lock.json
|--package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. app.js
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;app.js&lt;/em&gt; is the entry point or heart of the node.js application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//app.js
const express = require('express');
const app     = express();

require('./loaders/network-information.js');
require('./api-routes/home.js')(app);
require('./jobs/say-hello.js');
var config = require('./config/config.js');

app.set('view engine', 'ejs');
app.use(express.static('public'))

app.listen(config.port, () =&amp;gt; {
  console.log(`App listening at http://localhost:${config.port}`);
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. api-routes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;api-routes&lt;/em&gt; contain URL endpoints, which help users to interact with the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--api-routes
   |--home.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//home.js
var analytics = require('../services/analytics.js');
module.exports = function(app, network_information){    
    app.get('/', function(req, res){
        res.render('home.ejs', {key: "You have visited this page "+analytics.visitCounter()+" times"});
    });    
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. config
&lt;/h3&gt;

&lt;p&gt;This folder contains files that are used to configure the parameters &amp;amp; initial settings for application. They can be overridden &amp;amp; extended by Environment Variables, Command Line Parameters, or External Sources&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--config
   |--config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//config.js
module.exports = {    
    port: process.env.PORT || 80
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. data
&lt;/h3&gt;

&lt;p&gt;Here you can store your small data or can use it as a local database&lt;br&gt;
Note: Don't store any sensitive or confidential data here, Always use secure database for that kind of data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--data
   |--users.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//users.json
[
    {
        "name": "Mario Curtis",
        "city": "San Francisco",
        "contact number": "4949494949780",
        "type": "Admin"        
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Jobs
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;jobs&lt;/em&gt; folder contains scripts that will execute themselves automatically at a particular time&lt;br&gt;
Just like, Here we have created a script which prints "Hello" every hour a day.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--jobs
  |--say-hello.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//say-hello.js
var schedule = require('node-schedule');     

schedule.scheduleJob('00 * * * *', function(){
    console.log('Hello World, This scheduler will say "Hello" every hour to you');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. loaders
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;loaders&lt;/em&gt; contains the type of scripts that will execute at the time server starts.&lt;br&gt;
Just like, Here we are fetching user's &lt;em&gt;IP Address&lt;/em&gt; whenever server starts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--loaders
   |--network-information.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//network-information.js
const http = require('http');

http.get('http://api.ipify.org?format=json', (resp) =&amp;gt; {
  let data = '';

  resp.on('data', (chunk) =&amp;gt; {
    data += chunk;    
  });

  resp.on('end', () =&amp;gt; {    
    console.log("Your IP address is "+JSON.parse(data).ip)
  });

}).on("error", (err) =&amp;gt; {
  console.log("Error: " + err.message);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. public
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;public&lt;/em&gt; folder contains all the files that have to be served "statically" (JS, CSS, Image File).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--public
   |--css
   |  |--home.css
   |--js
   |  |--home.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//home.css
body{
    background-color: #f3f7fa;
}

div{
    text-align: center;
    padding-top: 200px;    
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log('Hello from javascript');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. secrets
&lt;/h3&gt;

&lt;p&gt;You can store all your secrets related to web application such as &lt;strong&gt;API-KEY, AUTHENTICATION-KEY&lt;/strong&gt;, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--secrets
   |--keys.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//keys.json
{
    "api-key": "HUH121NVYTB091BHHBCR121DR"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. services
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;services&lt;/em&gt; contains set of modules which performs a specific task. They can be used over &amp;amp; over again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--services
   |--anaytics.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//analytics.json
var i = 0;
function visitCounter()
{
    i = i + 1;
    return i;
}

module.exports = {
    visitCounter: visitCounter
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10. views
&lt;/h3&gt;

&lt;p&gt;It contains &lt;strong&gt;HTML Template&lt;/strong&gt; files, Which later rendered "dynamically" by &lt;strong&gt;Templating Engine&lt;/strong&gt; &amp;amp; serve HTML response to user.&lt;br&gt;
Here we are using &lt;strong&gt;EJS&lt;/strong&gt; templating engine, You can use any templating engine(pug, ejs) as per your convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--views
   |--home.ejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//home.ejs
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Node.js Project Structure&amp;lt;/title&amp;gt;
        &amp;lt;link rel="stylesheet" href="/css/home.css"/&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;%= key %&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;script src="/js/home.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Organized folder structure reduces the code complexity &amp;amp; increases the scalability of application.&lt;/p&gt;

&lt;p&gt;You can find whole project on &lt;a href="https://github.com/Kalpitrathore/node-project-structure.git" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more update, Follow me on &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/Kalpitrathore" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>productivity</category>
      <category>javascript</category>
      <category>saas</category>
    </item>
    <item>
      <title>Serving HTML files using Node.js on Ubuntu</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Thu, 07 Jan 2021 15:07:57 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/serving-html-files-using-node-js-on-ubuntu-j7e</link>
      <guid>https://dev.to/kalpitrathore/serving-html-files-using-node-js-on-ubuntu-j7e</guid>
      <description>&lt;p&gt;In this article, We'll going to host a &lt;strong&gt;Node.js Application&lt;/strong&gt; on &lt;strong&gt;Ubuntu&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Node.js is an open source, &lt;strong&gt;javascript runtime environment&lt;/strong&gt; used to create of &lt;strong&gt;backend&lt;/strong&gt; of any application.&lt;/p&gt;

&lt;h2&gt;
  
  
  To get started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install Node.js
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install NPM (&lt;strong&gt;NPM&lt;/strong&gt; is a package manager for Node.js packages)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create new project directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir node_application &amp;amp;&amp;amp; cd node_application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Initialize NPM in your project directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will ask some details related to your application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Express.js
It is a standard server framework for node to create single-page, multi-page &amp;amp; hybrid applications
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create "app.js" file inside in your project directory and add some code in it
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var express = require('express');
var app = express();
var path = require('path');
app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname + '/views/index.html'));
});
app.listen(80);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; Create a new folder inside your root project directory.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views &amp;amp;&amp;amp; cd views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a new file "index.html" inside "views" folder and add some code in it.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
   &amp;lt;head&amp;gt;
      &amp;lt;!-- Required meta tags --&amp;gt;
      &amp;lt;meta charset="utf-8"&amp;gt;
      &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
      &amp;lt;!-- Bootstrap CSS --&amp;gt;
      &amp;lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"&amp;gt;
      &amp;lt;title&amp;gt;Hello, world!&amp;lt;/title&amp;gt;
   &amp;lt;/head&amp;gt;
   &amp;lt;body&amp;gt;
      &amp;lt;nav class="navbar navbar-expand-lg navbar-light bg-light"&amp;gt;
         &amp;lt;div class="container-fluid"&amp;gt;
            &amp;lt;a class="navbar-brand" href="#"&amp;gt;Navbar&amp;lt;/a&amp;gt;
            &amp;lt;button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"&amp;gt;
            &amp;lt;span class="navbar-toggler-icon"&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;div class="collapse navbar-collapse" id="navbarSupportedContent"&amp;gt;
               &amp;lt;ul class="navbar-nav me-auto mb-2 mb-lg-0"&amp;gt;
                  &amp;lt;li class="nav-item"&amp;gt;
                     &amp;lt;a class="nav-link active" aria-current="page" href="#"&amp;gt;Home&amp;lt;/a&amp;gt;
                  &amp;lt;/li&amp;gt;
                  &amp;lt;li class="nav-item"&amp;gt;
                     &amp;lt;a class="nav-link" href="#"&amp;gt;Link&amp;lt;/a&amp;gt;
                  &amp;lt;/li&amp;gt;
                  &amp;lt;li class="nav-item dropdown"&amp;gt;
                     &amp;lt;a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"&amp;gt;
                     Dropdown
                     &amp;lt;/a&amp;gt;
                     &amp;lt;ul class="dropdown-menu" aria-labelledby="navbarDropdown"&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a class="dropdown-item" href="#"&amp;gt;Action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a class="dropdown-item" href="#"&amp;gt;Another action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;
                           &amp;lt;hr class="dropdown-divider"&amp;gt;
                        &amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a class="dropdown-item" href="#"&amp;gt;Something else here&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                     &amp;lt;/ul&amp;gt;
                  &amp;lt;/li&amp;gt;
                  &amp;lt;li class="nav-item"&amp;gt;
                     &amp;lt;a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true"&amp;gt;Disabled&amp;lt;/a&amp;gt;
                  &amp;lt;/li&amp;gt;
               &amp;lt;/ul&amp;gt;
               &amp;lt;form class="d-flex"&amp;gt;
                  &amp;lt;input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"&amp;gt;
                  &amp;lt;button class="btn btn-outline-success" type="submit"&amp;gt;Search&amp;lt;/button&amp;gt;
               &amp;lt;/form&amp;gt;
            &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/nav&amp;gt;
      &amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;
      &amp;lt;script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now run this command in your root project directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//if you are inside views folder
cd ..
//else simply run
node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We can see our website in our browser :)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5sv4njl7j94wmkcmm5gl.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5sv4njl7j94wmkcmm5gl.png" alt="k.png" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our project directory will look like this&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.js
node_modules
package.json
package-lock.json
views -&amp;gt; index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Concusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Express&lt;/strong&gt; is a minimal and flexible Node.js web application framework that provides a robust set of features to develop web and mobile applications. It facilitates the rapid development of Node based Web applications.&lt;/p&gt;

&lt;p&gt;For more update, Follow me on  &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
      <category>node</category>
    </item>
    <item>
      <title>AWS EC2: Launching an Amazon EC2 instance</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Tue, 29 Dec 2020 18:56:01 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/aws-ec2-launching-an-amazon-ec2-instance-1cid</link>
      <guid>https://dev.to/kalpitrathore/aws-ec2-launching-an-amazon-ec2-instance-1cid</guid>
      <description>&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%2Fi%2Fr4rqcrsp6gbt1lcikzmc.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%2Fi%2Fr4rqcrsp6gbt1lcikzmc.png" alt="Alt Text" width="360" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, We are going to create a &lt;strong&gt;Linux virtual machine&lt;/strong&gt; hosted on the cloud (also known as Instance) using &lt;strong&gt;Amazon EC2&lt;/strong&gt;. Amazon Elastic Compute Cloud (Amazon EC2) is an &lt;strong&gt;IaaS (Infrastructure as a Service)&lt;/strong&gt; that provides secure, resizable compute capacity in the cloud.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;To launch an EC2 Instance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Sign in to the &lt;a href="https://console.aws.amazon.com" rel="noopener noreferrer"&gt;Amazon Management Console&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the navigation bar, choose a suitable geographic region that meets your requirements.&lt;br&gt;
&lt;em&gt;Tip: Choose a nearer geographic region from your location to get faster responses&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;EC2&lt;/strong&gt; inside the &lt;strong&gt;Compute&lt;/strong&gt; section of &lt;strong&gt;All services&lt;/strong&gt;, It will redirects you to the &lt;strong&gt;Amazon EC2 Console&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the EC2 dashboard choose &lt;strong&gt;Launch Instance&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose an Amazon Machine Image (AMI)&lt;/strong&gt;&lt;br&gt;
Select an appropriate Amazon Machine Image(AMI). An AMI is a template that contains the software configuration (operating system, application server, and applications) required to launch your instance&lt;br&gt;
&lt;em&gt;Tip: Choose Ubuntu if you are not familiar with other machine images&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjo3i0ue4rzdsd4fme9ie.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%2Fi%2Fjo3i0ue4rzdsd4fme9ie.png" alt="Alt Text" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose an Instance Type&lt;/strong&gt;&lt;br&gt;
Choose a suitable &lt;strong&gt;Instance type&lt;/strong&gt; as per your needs. An Instance type describes the hardware specifications of the virtual machine (i.e. CPU, memory, storage, and networking capacity) and then click next.&lt;br&gt;
&lt;em&gt;Tip: Choose t2.micro, Because it is the only instance type which is eligible for free tier&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmv6j09gl3sjtzshk5eem.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%2Fi%2Fmv6j09gl3sjtzshk5eem.png" alt="Alt Text" width="799" height="331"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure Instance Details&lt;/strong&gt;&lt;br&gt;
In this step, We can configure our instance i.e Network type, IP allocation, Monitoring, IAM role, etc. If you don't have any prior knowledge of cloud computing then I would recommend you to not change any setting and simply click next.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzqwkp1oqpdr1udrfz9ao.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%2Fi%2Fzqwkp1oqpdr1udrfz9ao.png" alt="Alt Text" width="799" height="332"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add Storage&lt;/strong&gt;&lt;br&gt;
An &lt;strong&gt;Amazon EBS Volume&lt;/strong&gt; is similar as physical hard drive. In order to store data, We need to attach EBS volume to an instance. You can attach any size of disk space as per your needs. Free tier eligible customers can get up to 30 GB of EBS. We are choosing  &lt;strong&gt;25 GB&lt;/strong&gt; disk space with &lt;strong&gt;General Purpose SSD (GP2)&lt;/strong&gt; instance type.&amp;nbsp;&lt;br&gt;
Enable &lt;strong&gt;"delete on termination"&lt;/strong&gt; checkbox. It will delete the disk space associated with the server, whenever the server will terminate.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhsw8lyfh6hb7ch1r518h.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%2Fi%2Fhsw8lyfh6hb7ch1r518h.png" alt="Alt Text" width="799" height="336"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add Tags&lt;/strong&gt;&lt;br&gt;
A &lt;strong&gt;tag&lt;/strong&gt; is a &lt;strong&gt;key-value&lt;/strong&gt; pair that you assign to an instance to uniquely identify them from a group. It doesn't alter instance's functionality. Click on add tag button, Enter "Name" in key field and "myserver" in value field. then click next.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn6hom0l2deete36a0enk.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%2Fi%2Fn6hom0l2deete36a0enk.png" alt="Alt Text" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Security Group&lt;/strong&gt;&lt;br&gt;
A &lt;strong&gt;security group&lt;/strong&gt; controls inbound and outbound traffic from the server. There are set of protocol by which we can access the instance server i.e. HTTP, HTTPS, SSH.&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on Create a new security group in assign a security group section.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Enter a security group name and description.&lt;/li&gt;
&lt;li&gt;Now you need to define some protocol by which you are going to access the server. SSH protocol is added automatically, so you don't need to add it manually. Choose anywhere in source drop-down box of SSH protocol. This makes your server accessible from anywhere. Alternatively, You can bound the server with custom IP address as well. &lt;/li&gt;
&lt;li&gt;Now click review and launch.
&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%2Fi%2F4w9wfj0ybyi1nrp6nxlu.png" alt="Alt Text" width="800" height="333"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Review Instance Launch&lt;/strong&gt;&lt;br&gt;
Review your instance launch details. You can go back to edit changes for each section. If all details are correct then you can click on launch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will ask you to &lt;strong&gt;select an existing key pair or create new key pair&lt;/strong&gt;. A &lt;strong&gt;key pair&lt;/strong&gt;, consisting of a private key and a public key which is used to access instance server securely. Creating a new security group for individual server is the best practice.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Enter key pair name and click on Download Key Pair button, Once you are done downloading, Save this key in a secure folder and then click on Launch Instance button.
&lt;em&gt;Note:- If you lost your key pairs, then you will not able to download it again&lt;/em&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%2Fi%2Fhtcnumh6g3stp7w15ucc.png" alt="Alt Text" width="800" height="335"&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%2Fi%2F2ov80oqnhuxabz0v9h7o.png" alt="Alt Text" width="800" height="335"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It takes 2–3 minutes to create an instance, Now click on the instance button in the left panel. It will redirect you to the page where you can see list of instances created by you.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9se4kvy4r87nokof8ef9.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%2Fi%2F9se4kvy4r87nokof8ef9.png" alt="Alt Text" width="799" height="334"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhxmi05thaxxk4v7lnpck.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%2Fi%2Fhxmi05thaxxk4v7lnpck.png" alt="Alt Text" width="800" height="336"&gt;&lt;/a&gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait until the instance state of "myserver" is changed from &lt;em&gt;pending&lt;/em&gt; to &lt;em&gt;running&lt;/em&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5au726sdw7sprgt63n1.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%2Fi%2Fc5au726sdw7sprgt63n1.png" alt="Alt Text" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have successfully created an instance server. Now, We need to access it using SSH. Click on instance go to details tab, there we can see Public IP, Just copy it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftxj0xd5d2jrtmpzy16i3.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%2Fi%2Ftxj0xd5d2jrtmpzy16i3.png" alt="Alt Text" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;Terminal&lt;/strong&gt; or &lt;strong&gt;Command Prompt&lt;/strong&gt;, Go to the folder where you store the key pair file and type the command&lt;br&gt;
&lt;code&gt;ssh -i key-pair.pem ubuntu@public_ip&lt;/code&gt;&lt;br&gt;
replace &lt;em&gt;"key-pair.pem"&lt;/em&gt; with your key-pair file name and &lt;em&gt;public_ip&lt;/em&gt; with your instance's public ip.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmubhp8qxii1kmnntytiw.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%2Fi%2Fmubhp8qxii1kmnntytiw.png" alt="Alt Text" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will ask you to add server's fingerprint, then simply type &lt;em&gt;yes&lt;/em&gt; and press enter&amp;nbsp;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flf3m6impj5nkjlsl70z6.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%2Fi%2Flf3m6impj5nkjlsl70z6.png" alt="Alt Text" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo su -
sudo apt-get update
&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%2Fi%2Ft3ci1w7fuqslc1dfmpv0.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%2Fi%2Ft3ci1w7fuqslc1dfmpv0.png" alt="Alt Text" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we have successfully created and accessed an instance server. With the help of ec2 instance we can build web server, database server, vpn server, game server, data analysis server, geolocation or map server and lot more.&lt;/p&gt;

&lt;p&gt;We'll going to build or experiement all of this with our EC2 Server.&lt;/p&gt;

&lt;p&gt;For more update, Follow me on &lt;a href="https://twitter.com/kalpitrathore" rel="noopener noreferrer"&gt;twitter&lt;/a&gt; or &lt;a href="https://www.instagram.com/kalpit_rathore1/" rel="noopener noreferrer"&gt;instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>10 Funny App Loading Messages for App Developers</title>
      <dc:creator>Kalpit Rathore</dc:creator>
      <pubDate>Tue, 22 Dec 2020 14:39:05 +0000</pubDate>
      <link>https://dev.to/kalpitrathore/some-funny-app-loading-messages-for-app-developers-46h</link>
      <guid>https://dev.to/kalpitrathore/some-funny-app-loading-messages-for-app-developers-46h</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Discovering new ways of making you wait.&lt;/li&gt;
&lt;li&gt;Your time is very important to us. Please wait while we ignore you.&lt;/li&gt;
&lt;li&gt;Still faster than Windows update.&lt;/li&gt;
&lt;li&gt;We are not liable for any broken screens as a result of waiting.&lt;/li&gt;
&lt;li&gt;Bored of slow loading spinner?, buy more RAM!&lt;/li&gt;
&lt;li&gt;Kindly hold on until I finish a cup of coffee.&lt;/li&gt;
&lt;li&gt;We will be back in 1/0 minutes.&lt;/li&gt;
&lt;li&gt;Why don't you order a sandwich?&lt;/li&gt;
&lt;li&gt;Don't panic, Just count to infinite.&lt;/li&gt;
&lt;li&gt;Please wait, Your PC is not a superman!&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>node</category>
      <category>react</category>
      <category>vue</category>
    </item>
  </channel>
</rss>
