<?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: Jagannath</title>
    <description>The latest articles on DEV Community by Jagannath (@jagannathm).</description>
    <link>https://dev.to/jagannathm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1096376%2F3a13de0c-3800-47a0-aa95-bbb1614d6999.png</url>
      <title>DEV Community: Jagannath</title>
      <link>https://dev.to/jagannathm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jagannathm"/>
    <language>en</language>
    <item>
      <title>Concurrency and Parallelism in Node.js</title>
      <dc:creator>Jagannath</dc:creator>
      <pubDate>Sun, 04 May 2025 17:26:21 +0000</pubDate>
      <link>https://dev.to/jagannathm/concurrency-and-parallelism-in-nodejs-1lbc</link>
      <guid>https://dev.to/jagannathm/concurrency-and-parallelism-in-nodejs-1lbc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When people think of Node.js, they think “non-blocking I/O”, “event loop”, or “JavaScript on the server.” But one of the most underrated capabilities of Node.js is how elegantly it handles concurrency and parallelism - despite Javascript being single-threaded.&lt;/p&gt;

&lt;p&gt;If you’ve ever believed that Node.js isn’t built for CPU-intensive tasks or can’t run things in parallel, think again. Underneath the simplicity of asynchronous fs.readFile lies a surprisingly powerful ecosystem for managing concurrent and parallel tasks.&lt;/p&gt;

&lt;p&gt;Let’s dive into this hidden gem and learn how to unlock its full potential.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrency vs. Parallelism
&lt;/h2&gt;

&lt;p&gt;Before we get into Node.js internals, let’s understand what these terms mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; is the ability to manage multiple tasks at once, regardless of whether they run in parallel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt; is doing multiple things at the same time, often leveraging multiple cores or threads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Node.js is single-threaded since it is a runtime environment for JavaScript which is single-threaded. But, it is concurrent and even parallel under the hood. That’s the key insight that most developers fail to realize.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js Event Loop
&lt;/h2&gt;

&lt;p&gt;The event loop is the heart of Node.js concurrency. It allows Node to handle thousands of simultaneous I/O operations - like reading files, querying databases, handling HTTP requests, etc. without blocking.&lt;/p&gt;

&lt;p&gt;Let’s consider an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs');

console.log("Start");

fs.readFile('file.txt', 'utf8', () =&amp;gt; {
  console.log("File read");
});

console.log("End");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
File read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without using threads, Node.js can process the file read operation asynchronously, thanks to its event loop and non-blocking APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  But what about Parallelism?
&lt;/h2&gt;

&lt;p&gt;This is where things get really interesting. It often gets overlooked.&lt;/p&gt;

&lt;p&gt;Node.js can do real parallelism, even for CPU-heavy operations, via the following methods:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Worker Threads: Actual Multithreading in JavaScript
&lt;/h3&gt;

&lt;p&gt;A surprisingly underused module in Node.js is worker_threads. It allows you to run JavaScript code in actual separate threads, perfect for CPU-bound work.&lt;/p&gt;

&lt;p&gt;Let’s see an example of a CPU-intensive operation being run on a worker thread.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.js
const { Worker } = require('worker_threads');

const run = () =&amp;gt; {
 return new Promise((resolve, reject) =&amp;gt; {
   const worker = new Worker('./worker.js', { workerData: 40 });
   worker.on('message', resolve);
   worker.on('error', reject);
   worker.on('exit', (code) =&amp;gt; {
    if (code !== 0)
        reject(new Error(`Worker stopped with exit code ${code}`));
    });
 });
};

run().then(console.log);
&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;// worker.js
const { workerData, parentPort } = require('worker_threads');

function fibonacci(n) {
  return n &amp;lt;= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
}

parentPort.postMessage(fibonacci(workerData));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Child Processes: Run external programs or scripts
&lt;/h3&gt;

&lt;p&gt;Need to run a Python script, Bash command, or an isolated Node process? child_process module makes this easy.&lt;/p&gt;

&lt;p&gt;Let’s see how a child-process can be spawned to carry out an operation. We will run a unix command to lists files in the current directory in long format as an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { exec } = require('child_process');

exec('ls -la', (err, stdout) =&amp;gt; {
  if (err) return console.error(err);
  console.log(stdout);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Cluster Module: Scaling across CPU Cores
&lt;/h3&gt;

&lt;p&gt;For web servers, the cluster module can be used to fork multiple instances of Node.js. It helps to distribute workload among multiple CPU cores, making the app truly parallel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const cluster = require('node:cluster');
const http = require('node:http');
const os = require("node:os");
const process = require("node:process");

const numCPUs = os.availableParallelism();

if (cluster.isPrimary) {
  console.log(`Primary process with ID:${process.pid} is running`);

  for (let i = 0; i &amp;lt; numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) =&amp;gt; {
    console.log(`worker process with ID:${worker.process.pid} exited`);
  });
} else {
  http.createServer((req, res) =&amp;gt; {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(3000);

  console.log(`Worker process with ID:${process.pid} started`);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The libuv Thread Pool
&lt;/h2&gt;

&lt;p&gt;Even when you don’t use workers or child processes, Node.js runs I/O operations in a thread pool (via libuv) under the hood - allowing tasks like fs.readFile , crypto.pbkdf2 , dns.lookup , etc. to run in parallel under the hood.&lt;/p&gt;

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

&lt;p&gt;Node.js is not just for I/O. It’s a surprisingly capable runtime for concurrent and even parallel workloads. What’s often seen as a limitation “JavaScript is single-threaded”, is in fact a design trade-off backed by powerful native systems like libuv, worker threads, and OS-level processes.&lt;/p&gt;

&lt;p&gt;Whether you’re building APIs, doing heavy computation, or scraping the web in batches, Node.js gives you the tools - you just have to reach for them.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Internationalization in React: A Beginner's Guide to i18n</title>
      <dc:creator>Jagannath</dc:creator>
      <pubDate>Sun, 27 Apr 2025 12:34:32 +0000</pubDate>
      <link>https://dev.to/jagannathm/internationalization-in-react-a-beginners-guide-to-i18n-3kcb</link>
      <guid>https://dev.to/jagannathm/internationalization-in-react-a-beginners-guide-to-i18n-3kcb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Internationalization (i18n) and localization (l10n) are essential for building web applications that cater to users across different languages and regions across the world. Internationalization is the process of enabling an application to be easily adaptable in various languages and locales, while localization involves translating and formatting content for a specific language or region. As the internet is available on a global scale, providing a localized experience enhances user satisfaction and expands your app's reach.&lt;br&gt;
React, by default, doesn't include built-in internationalization support, but there are powerful libraries available that simplify this process. One of the most widely used libraries for this purpose is i18next, along with its React bindings react-i18next. In this guide, we'll walk through how to set up i18next in a React app, manage translations, enable dynamic language switching, and follow best practices for internationalization.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up Localization in a React App
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Installing dependencies
&lt;/h3&gt;

&lt;p&gt;First, install the necessary 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 i18next react-i18next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This installs the core i18next library and its integration with React.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Project structure for translations
&lt;/h3&gt;

&lt;p&gt;Organize the translations in JSON files within a folder structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
  config/
    locales/
      en/
        translation.json
      es/
        translation.json
      hi/
        translation.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each translation.json file contains key-value pairs for translated text. &lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;strong&gt;en/translation.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "greeting_message": "Hi, how are you?"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;es/translation.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "greeting_message": "¡Hola, ¿cómo estás?"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;hi/translation.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "greeting_message": "नमस्ते | आप कैसे हैं?"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Initializing i18next
&lt;/h3&gt;

&lt;p&gt;Create a configuration file to initialize i18next:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;src/config/i18n.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import enTranslations from './locales/en/translation.json';
import esTranslations from './locales/es/translation.json';
import hiTranslations from './locales/hi/translation.json';

i18n.use(initReactI18next).init({
  resources: {
    en: { translation: enTranslations },
    es: { translation: esTranslations },
    hi: { translation: hiTranslations },
  },
  lng: 'en',
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false,
  },
});

export default i18n;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Loading i18n in Your App
&lt;/h3&gt;

&lt;p&gt;Import the i18n configuration in your app root file. The following is an example that uses vite to bootstrap a react app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;src/main.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import './index.css';
import './config/i18n';

createRoot(document.getElementById('root')).render(
  &amp;lt;StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Translating Text in Components
&lt;/h2&gt;

&lt;p&gt;Use the useTranslation hook to translate text in any component. Let's create a Greeting.jsx component to greet the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTranslation } from 'react-i18next';

export default function Greeting() {
  const { t } = useTranslation();
  return &amp;lt;h1&amp;gt;{t('greeting_message')}&amp;lt;/h1&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also interpolate dynamic values using placeholders:&lt;br&gt;
&lt;strong&gt;en/translation.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "welcome_user": "Welcome, {{name}}!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Component:&lt;/strong&gt;&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;p&amp;gt;{t('welcome_user', { name: 'Baburao' })}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dynamic Language Switching
&lt;/h2&gt;

&lt;p&gt;Enable users to switch languages at runtime using i18n.changeLanguage . Let's create a LanguageSwitcher.jsx component for this purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTranslation } from 'react-i18next';

export default function LanguageSwitcher() {
  const { i18n } = useTranslation();

  const handleLanguageChange = (e) =&amp;gt; {
    i18n.changeLanguage(e.target.value);
  };

  return (
    &amp;lt;select onChange={handleLanguageChange} value={i18n.language}&amp;gt;
      &amp;lt;option value='en'&amp;gt;English&amp;lt;/option&amp;gt;
      &amp;lt;option value='es'&amp;gt;¡Español!&amp;lt;/option&amp;gt;
      &amp;lt;option value='hi'&amp;gt;हिंदी&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results
&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%2Fz37aj0tpd1l0unmivkmy.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%2Fz37aj0tpd1l0unmivkmy.png" alt="English language support using a dynamic dropdown" width="737" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4iwtivtp5ssxshjs05f4.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%2F4iwtivtp5ssxshjs05f4.png" alt="Hindi language support using a dynamic dropdown" width="737" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plan early:&lt;/strong&gt; Incorporate i18n from the start to avoid retrofitting later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meaningful keys:&lt;/strong&gt; Use descriptive keys like "nav.home" rather than full sentences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid concatenation:&lt;/strong&gt; Use complete sentences in translation files and placeholders for dynamic content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pluralization and formatting:&lt;/strong&gt; Utilize i18next's support for pluralization and date/number formatting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test thoroughly:&lt;/strong&gt; Check your app in multiple languages for layout issues and missing translations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RTL language support:&lt;/strong&gt; Ensure your app supports right-to-left languages by adjusting layouts and direction attributes.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Internationalizing a React app is straightforward with tools like i18next. With this approach, you can create a user-friendly multilingual application. Following best practices ensures your app remains scalable and accessible to a global audience.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>i18n</category>
      <category>react</category>
      <category>internationalization</category>
    </item>
    <item>
      <title>Scalable File Upload System with React.js, Express.js and AWS S3 (Using AWS SDK v3)</title>
      <dc:creator>Jagannath</dc:creator>
      <pubDate>Fri, 18 Apr 2025 20:10:52 +0000</pubDate>
      <link>https://dev.to/jagannathm/scalable-file-upload-system-with-reactjs-expressjs-and-aws-s3-using-aws-sdk-v3-2gpc</link>
      <guid>https://dev.to/jagannathm/scalable-file-upload-system-with-reactjs-expressjs-and-aws-s3-using-aws-sdk-v3-2gpc</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;File uploading is a common feature in web applications. AWS provides a robust solution with S3 (Simple Storage Service) as an object storage to store files as objects. &lt;br&gt;
If your server handles every file directly, it quickly becomes a bottleneck as the client sends the entire file to the server which then sends it again to S3, using up CPU, memory, and bandwidth. That's why scalable systems offload this responsibility to cloud storage using pre-signed URLs. In this guide, we'll build a scalable file upload system using React.js, Express.js, AWS S3, and pre-signed URLs, powered by the modern AWS SDK v3.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll build a scalable file upload system using &lt;strong&gt;React.js&lt;/strong&gt;, &lt;strong&gt;Express.js&lt;/strong&gt;, &lt;strong&gt;AWS S3&lt;/strong&gt;, and &lt;strong&gt;pre-signed URLs&lt;/strong&gt;, powered by the modern &lt;strong&gt;AWS SDK v3&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What’s a Pre-Signed URL?
&lt;/h3&gt;

&lt;p&gt;A pre-signed URL allows you to grant temporary &lt;strong&gt;upload/download&lt;/strong&gt; access to a specific S3 object, without exposing your AWS credentials to the client or opening up public access.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No server bottleneck:&lt;/strong&gt; clients upload directly to S3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable:&lt;/strong&gt; your server handles only metadata to create a pre-signed URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure:&lt;/strong&gt; limited-time access, file type and path constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Server-side Code
&lt;/h3&gt;

&lt;p&gt;Let's see how we can create a simple file upload API using Express.js and AWS SDK v3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import dotenv from "dotenv";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { v4 as uuidv4 } from "uuid";

dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000;

const s3 = new S3Client({
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});

app.get("/api/generate-presigned-url", async (req, res) =&amp;gt; {
  const fileName = `${uuidv4()}.jpg`; // You can use other extensions or get extension from client side using query params
  const bucketName = process.env.S3_BUCKET_NAME;

  const command = new PutObjectCommand({
    Bucket: bucketName,
    Key: fileName,
    ContentType: "image/jpeg", // You could allow dynamic types by getting content type from client side using query params
  });

  try {
    const url = await getSignedUrl(s3, command, { expiresIn: 60 });
    res.json({ uploadURL: url, fileName });
  } catch (err) {
    console.error("Error generating pre-signed URL:", err);
    res.status(500).json({ error: "Could not generate pre-signed URL" });
  }
});

app.listen(PORT, () =&amp;gt; {
  console.log(`Server running on http://localhost:${PORT}`);
});

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client-side Code
&lt;/h3&gt;

&lt;p&gt;Let's create a simple React component to upload a file from client side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

export default function S3Uploader() {
  const [file, setFile] = useState&amp;lt;File | null&amp;gt;(null);
  const [uploading, setUploading] = useState(false);

  const handleUpload = async () =&amp;gt; {
    if (!file) {
      alert('No file selected');
      return;
    }

    try {
      setUploading(true);

      // Step 1: Get pre-signed URL from backend
      const res = await fetch(`${process.env.SERVER_BASE_URL}/api/generate-presigned-url?fileName=${encodeURIComponent(file.name)}`);
      const { uploadURL, fileName } = await res.json();

      // Step 2: Upload the file to S3 using the pre-signed URL
      const upload = await fetch(uploadURL, {
        method: 'PUT',
        headers: { 'Content-Type': file.type },
        body: file,
      });

      if (!upload.ok) {
        alert('Upload failed!');
        return;
      }

      alert(`File uploaded! Name: ${fileName}`);
    } catch (err) {
      console.error(err);
      alert('Something went wrong!');
    } finally {
      setUploading(false);
      setFile(null);
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input
        type="file"
        accept="image/jpeg"
        onChange={(e) =&amp;gt; setFile(e.target.files?.[0] || null)}
      /&amp;gt;
      &amp;lt;button
        onClick={handleUpload}
        disabled={!file || uploading}
      &amp;gt;
        {uploading ? 'Uploading...' : 'Upload'}
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modify pre-signed URL endpoint to accept command type based on query params to use GetObject command for downloading files.&lt;/li&gt;
&lt;li&gt;Validate file types and size on the backend before generating a pre-signed URL.&lt;/li&gt;
&lt;li&gt;Store file metadata in your DB after upload for future use.&lt;/li&gt;
&lt;li&gt;Add authentication to protect the pre-signed URL endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Pre-signed URLs are a clean, efficient, and secure way to implement file uploads, keeping scalability in mind. With the AWS SDK v3, the integration is simple, modular and future-proof.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>express</category>
      <category>react</category>
    </item>
    <item>
      <title>My First Open Source Contribution</title>
      <dc:creator>Jagannath</dc:creator>
      <pubDate>Sun, 22 Oct 2023 06:49:37 +0000</pubDate>
      <link>https://dev.to/jagannathm/my-first-open-source-contribution-3lh2</link>
      <guid>https://dev.to/jagannathm/my-first-open-source-contribution-3lh2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hacktoberfest 2023&lt;/strong&gt; marked my first foray into the world of open source contributions. In this article, I'll share the highlights of my journey, from selecting the right project to the valuable lessons learned along the way.&lt;/p&gt;

&lt;p&gt;My open source journey began with the curiosity to give back to the community. After diligent research and exploration, I found a suitable project related to web development that aligned with my interests and skills.&lt;/p&gt;

&lt;p&gt;I added a new feature, adhering to the project's guidelines and coding standards. Collaboration with experienced maintainers provided valuable feedback and guidance throughout the process.&lt;/p&gt;

&lt;p&gt;I faced some challenges, impostor syndrome being the biggest one apart from technical hurdles and time management. Through these obstacles, I learned the power of collaboration, the abundance of learning opportunities, and the value of building a strong developer portfolio.&lt;/p&gt;

&lt;p&gt;My inaugural open source contribution in Hacktoberfest 2023 was a remarkable experience that reinforced the importance of giving back to the open source community and the incredible personal and professional growth it offers. If you haven't ventured into open source yet, I highly recommend giving it a try. It's a journey worth embarking on.&lt;/p&gt;

</description>
      <category>hacktoberfest23</category>
      <category>opensource</category>
      <category>coding</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
