<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Arnab Saha</title>
    <description>The latest articles on Forem by Arnab Saha (@arnabsahawrk).</description>
    <link>https://forem.com/arnabsahawrk</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%2F1503623%2F7d415416-b7e4-44e8-aea8-b192b7ca7f8c.png</url>
      <title>Forem: Arnab Saha</title>
      <link>https://forem.com/arnabsahawrk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/arnabsahawrk"/>
    <language>en</language>
    <item>
      <title>A Curated LeetCode List for Full-Stack Developers</title>
      <dc:creator>Arnab Saha</dc:creator>
      <pubDate>Sat, 18 Apr 2026 11:14:05 +0000</pubDate>
      <link>https://forem.com/arnabsahawrk/a-curated-leetcode-list-for-full-stack-developers-395a</link>
      <guid>https://forem.com/arnabsahawrk/a-curated-leetcode-list-for-full-stack-developers-395a</guid>
      <description>&lt;p&gt;I built this list for myself while going through a full-stack web development journey and preparing for job placement in parallel. If you are in a similar position — actively building things, learning a framework, and trying to keep problem-solving consistent without burning out — this might be useful for you too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link:&lt;/strong&gt; &lt;a href="https://leetcode.com/problem-list/wgazxxzm/" rel="noopener noreferrer"&gt;https://leetcode.com/problem-list/wgazxxzm/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in the list
&lt;/h2&gt;

&lt;p&gt;191 problems across four categories in this order:&lt;/p&gt;

&lt;p&gt;TypeScript (23) → DSA Part 1: Arrays &amp;amp; Hashing, Two Pointers, Sliding Window, Stack, Binary Search → SQL (21) → DSA Part 2: Linked List, Trees, Heap/Priority Queue, Backtracking, Tries, Graphs, Advanced Graphs, DP, Greedy, Intervals, Math &amp;amp; Geometry, Bit Manipulation (143) → Bash (4)&lt;/p&gt;

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

&lt;p&gt;My daily stack is Node.js and React. Solving in TypeScript means I am reinforcing types, generics, and interfaces while solving the problem. The language practice compounds with the algorithmic practice instead of running separately. You are not context-switching into a language you do not use — you are practicing the one you already write every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The only rule I follow
&lt;/h2&gt;

&lt;p&gt;Spend at least 30 minutes and up to 1 hour each day before starting development. The ceiling is the point. I am building real projects at the same time. Uncapped LeetCode time kills everything else.&lt;/p&gt;

&lt;p&gt;Deep work on 191 curated problems beats shallow coverage of 500.&lt;/p&gt;




&lt;p&gt;If you are on a similar path — full-stack dev, job hunting, trying to keep everything moving without dropping the ball — feel free to use the list. Would love to hear how others are balancing this.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>typescript</category>
      <category>dsa</category>
      <category>sql</category>
    </item>
    <item>
      <title>I Built a Multi-Provider AI Chat App with Django and React — Here's What Actually Happened</title>
      <dc:creator>Arnab Saha</dc:creator>
      <pubDate>Mon, 02 Mar 2026 17:14:34 +0000</pubDate>
      <link>https://forem.com/arnabsahawrk/i-built-a-multi-provider-ai-chat-app-with-django-and-react-heres-what-actually-happened-49</link>
      <guid>https://forem.com/arnabsahawrk/i-built-a-multi-provider-ai-chat-app-with-django-and-react-heres-what-actually-happened-49</guid>
      <description>&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;The core idea was simple: a ChatGPT-like interface backed by free-tier AI APIs, with Google login, persistent chat history, and real-time streaming. The twist was multi-provider routing — if Groq's free quota runs out mid-day, the app silently falls back to Gemini, then Mistral. The user never sees an error. They just keep chatting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack I chose:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Django 6 + Django REST Framework on the backend&lt;/li&gt;
&lt;li&gt;React 19 + TypeScript + Tailwind CSS v4 on the frontend&lt;/li&gt;
&lt;li&gt;Groq (Llama 3.3 70B), Google Gemini 2.0 Flash, Mistral Small for AI&lt;/li&gt;
&lt;li&gt;Google OAuth 2.0 for auth&lt;/li&gt;
&lt;li&gt;Render (backend) + Vercel (frontend) + Neon (Neon) — all free tier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Starting with Auth
&lt;/h2&gt;

&lt;p&gt;I wanted Google OAuth because it's frictionless for users. No password forms, no email verification — just "Sign in with Google" and you're in.&lt;/p&gt;

&lt;p&gt;The standard django-allauth approach assumes a server-side redirect flow — Google redirects back to your Django backend, and Django sets a session cookie. That doesn't work cleanly when your frontend is a separate React SPA on a different domain.&lt;/p&gt;

&lt;p&gt;So I went with the &lt;strong&gt;implicit flow&lt;/strong&gt;: the frontend handles the Google popup, gets the credential token directly from Google, then sends it to Django. Django validates it against Google's API, finds or creates the user, and returns a JWT pair (access + refresh). From that point forward, it's just JWT auth.&lt;/p&gt;

&lt;p&gt;This meant writing a custom &lt;code&gt;GoogleLoginView&lt;/code&gt; that takes a Google credential, calls Google's tokeninfo endpoint, extracts the email and profile data, and issues tokens. It worked — but it took longer than expected because the django-allauth docs assume the redirect flow, and the custom path is not well documented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; When your frontend and backend live on different origins, think about auth flows from first principles. Don't assume a library's default flow fits your architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the Database Before Writing Any AI Code
&lt;/h2&gt;

&lt;p&gt;I made a deliberate choice to fully design and implement the data layer before touching any AI integration. The models were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ChatSession&lt;/code&gt; — belongs to a user, has a title, tracks created/updated time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Message&lt;/code&gt; — belongs to a session, stores role (user/assistant), content, which AI provider responded, and which model was used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ProviderUsage&lt;/code&gt; — tracks daily usage per provider so the routing logic knows when to fall back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last model was the important one. The fallback logic needed to survive server restarts. If I tracked quota exhaustion in memory only, a Render dyno restart would reset it and I'd hammer a dead quota again immediately. Storing it in the database means the state persists across restarts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Multi-Provider Router
&lt;/h2&gt;

&lt;p&gt;This is the part I'm most satisfied with.&lt;/p&gt;

&lt;p&gt;The router works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try Groq first (fastest, Llama 3.3 70B)&lt;/li&gt;
&lt;li&gt;If Groq returns a quota error, mark it exhausted in the DB for today and try Gemini&lt;/li&gt;
&lt;li&gt;If Gemini fails, fall back to Mistral&lt;/li&gt;
&lt;li&gt;If all three are exhausted, return a clear error to the user&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every message response records which provider and model actually served it. So in the DB you can see "this message was answered by Gemini because Groq was exhausted."&lt;/p&gt;

&lt;p&gt;The tricky part was making the fallback transparent to the streaming layer. Once I start streaming tokens to the client, I can't switch providers mid-response. So the fallback only happens before streaming begins — the router tries to open a connection with the provider, and if that fails, it retries with the next one before sending a single byte to the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSE Streaming Was Harder Than I Expected
&lt;/h2&gt;

&lt;p&gt;Server-Sent Events looked simple on paper: Django yields chunks, the browser reads them. In practice, several rough edges appeared.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CORS and SSE don't play well by default.&lt;/strong&gt; My frontend is on Vercel, my backend on Render — two different origins. SSE connections are long-lived and behave differently from regular XHR requests when it comes to CORS headers. I had to verify that Django's CORS middleware applied correctly to streaming responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Django's ORM doesn't like being called inside a generator.&lt;/strong&gt; When you yield from a Django streaming response, you're inside a generator function. Database writes (like saving the completed message after streaming finishes) need careful handling. I collected the full streamed content and wrote it to the DB in the generator's &lt;code&gt;finally&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The client needed an abort mechanism.&lt;/strong&gt; If the user clicks "stop generating," the frontend needs to cleanly close the SSE connection. On the React side, this meant using an &lt;code&gt;AbortController&lt;/code&gt;. On the Django side, catching &lt;code&gt;GeneratorExit&lt;/code&gt; when the client disconnects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind v4 and the Design Token System
&lt;/h2&gt;

&lt;p&gt;Tailwind v4 is a significant departure from v3. There's no &lt;code&gt;tailwind.config.js&lt;/code&gt; anymore — all custom tokens are defined in your CSS file using &lt;code&gt;@theme&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-surface-base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1a1a1a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-ink-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f0ede8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2e2e2e&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;I mirrored these in a &lt;code&gt;theme.ts&lt;/code&gt; file for the rare cases where I needed values in JavaScript. The rule I set for myself: no hardcoded hex values in any component. Everything goes through a token class like &lt;code&gt;bg-surface-base&lt;/code&gt; or &lt;code&gt;text-ink-primary&lt;/code&gt;. This paid off when I wanted to adjust the base background — one line in the CSS file, done everywhere.&lt;/p&gt;

&lt;p&gt;The downside: Tailwind v4 is still new and the ecosystem hasn't fully caught up. I hit cases where shadcn/ui components assumed v3 configuration and needed manual adaptation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying on Free Tiers
&lt;/h2&gt;

&lt;p&gt;Both Render and Vercel have generous free tiers, but they come with real constraints you have to design around.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Render's free backend spins down after 15 minutes of inactivity.&lt;/strong&gt; The first request after a cold start can take 30-50 seconds. For a chat app where the first thing a user does is send a message, that's a painful first impression.&lt;/p&gt;

&lt;p&gt;The fix turned out to be simple. I created a lightweight &lt;code&gt;/health&lt;/code&gt; endpoint on the Django backend that just returns a 200 OK, then set up a free UptimeRobot monitor to ping it every 5 minutes. Render never gets the chance to spin the instance down. No cold starts, no 50-second waits, no frustrated users — and it costs nothing on either side.&lt;/p&gt;

&lt;p&gt;Sometimes the "real" fix is just a cron job with a URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL on Neon free tier has connection limits.&lt;/strong&gt; Django's default connection behavior opens a new connection per request. Under any real load, this exhausts the connection pool. The fix is &lt;code&gt;CONN_MAX_AGE&lt;/code&gt; in Django's database settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment variables across two deployments get tedious.&lt;/strong&gt; Django needs &lt;code&gt;GOOGLE_CLIENT_ID&lt;/code&gt;. React also needs &lt;code&gt;VITE_GOOGLE_CLIENT_ID&lt;/code&gt; (Vite's required prefix for client-side vars). The same value, two names, two dashboards. Small thing, but error-prone. I kept a &lt;code&gt;.env.example&lt;/code&gt; for both services and updated them in sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context Window Problem
&lt;/h2&gt;

&lt;p&gt;Early on, I was only sending the user's latest message to the AI. The AI had no memory — every message was a fresh conversation. Obviously wrong for a chat app.&lt;/p&gt;

&lt;p&gt;The fix is sending the last N messages as conversation history on every request. But N has to be bounded — very long sessions would exceed the model's context window limit and the API would return an error.&lt;/p&gt;

&lt;p&gt;I settled on a configurable &lt;code&gt;CONTEXT_WINDOW_SIZE&lt;/code&gt; (last 20 messages by default), queried from the DB before every AI call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-Generating Session Titles
&lt;/h2&gt;

&lt;p&gt;When a new session starts, it has no title. I wanted it to appear automatically after the first exchange.&lt;/p&gt;

&lt;p&gt;After the first user message and AI response are saved, a separate lightweight AI call generates a short title (under 8 words) based on the conversation content. It runs after streaming completes so it doesn't block anything. The frontend polls for the session update and renders the title in the sidebar when it arrives.&lt;/p&gt;

&lt;p&gt;Small feature, but it makes the app feel complete rather than like a half-finished prototype.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start with the streaming architecture.&lt;/strong&gt; I built the basic request/response flow first, then had to rework significant parts to support SSE. Designing for streaming from day one would have avoided most of that rework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write the API contract first.&lt;/strong&gt; I built backend and frontend somewhat in parallel, which meant changing endpoint shapes while the frontend was already consuming them. A simple spec written upfront would have saved some self-coordination overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Free tiers shape your architecture whether you plan for it or not.&lt;/strong&gt; Cold starts, connection limits, quota limits — these aren't edge cases on free hosting. They're the default. Design for them early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-provider AI routing is genuinely useful, not just clever.&lt;/strong&gt; Since deploying, Groq's free tier has hit its daily limit multiple times. Without the fallback, the app would be broken for the rest of the day. With it, users don't notice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSE is underused and underappreciated.&lt;/strong&gt; For one-directional streaming from server to client, SSE is simpler than WebSockets in almost every way. It works over plain HTTP, handles reconnection natively, and needs no special infrastructure. Reach for it before WebSockets when you only need server-to-client streaming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design tokens are worth the upfront investment.&lt;/strong&gt; The Tailwind v4 token setup took a couple of hours. But having a consistent, named color system meant I never debated "is this the right shade?" The answer was always "use the token and move on."&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The app is live at &lt;a href="https://arnabsahawrk-ai-chat-assistant.vercel.app" rel="noopener noreferrer"&gt;arnabsahawrk-ai-chat-assistant.vercel.app&lt;/a&gt;. Sign in with Google and send a message. If Groq's quota is spent for the day, you will be talking to Gemini without knowing it.&lt;/p&gt;

&lt;p&gt;Source code is on &lt;a href="https://github.com/arnabsahawrk/ai-chat-assistant" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and the API documentation is at &lt;a href="https://ai-chat-assistant-4agm.onrender.com/" rel="noopener noreferrer"&gt;ai-chat-assistant-4agm.onrender.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you spot something that could be done better or have an idea worth trying, drop it in the comments — always open to it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>django</category>
      <category>react</category>
    </item>
    <item>
      <title>Access Token &amp; Refresh Token: A Breakdown</title>
      <dc:creator>Arnab Saha</dc:creator>
      <pubDate>Thu, 18 Jul 2024 06:31:01 +0000</pubDate>
      <link>https://forem.com/arnabsahawrk/access-token-refresh-token-a-breakdown-5f81</link>
      <guid>https://forem.com/arnabsahawrk/access-token-refresh-token-a-breakdown-5f81</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Access Tokens and Refresh Tokens: The Keys to Secure Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this post, I'm trying to explain the concepts of access tokens and refresh tokens, two crucial components of secure authentication in web applications and APIs. By understanding their roles and how they work together, we can build robust and user-friendly authentication systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is an Access Token?
&lt;/h3&gt;

&lt;p&gt;An access token acts like a digital key that grants temporary permission to access a specific resource within an application or API. When a user successfully logs in, an access token is issued. This token contains essential information, such as user identity and permissions, allowing them to interact with the application's functionalities.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key characteristics of access tokens:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short-lived:&lt;/strong&gt; Access tokens typically have a short lifespan, often expiring within minutes or hours. This security measure helps minimize the potential damage if the token is compromised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited scope:&lt;/strong&gt; Access tokens can be granted with specific scopes, restricting the actions a user can perform. This prevents unauthorized access to sensitive data or functionalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-contained (sometimes):&lt;/strong&gt; Access tokens might contain enough information to validate the user's identity without needing to contact the authentication server for every request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is a Refresh Token?
&lt;/h3&gt;

&lt;p&gt;While access tokens are essential for immediate access, their short lifespan poses a challenge: what happens when the token expires? This is where refresh tokens come in. A refresh token is a long-lived credential (often lasting days or weeks) issued alongside the access token during login.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key characteristics of refresh tokens:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Long-lived:&lt;/strong&gt; Designed to last longer than access tokens, allowing users to maintain their logged-in state for extended periods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited functionality:&lt;/strong&gt; Refresh tokens themselves cannot access resources. They are used solely to obtain new access tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure storage:&lt;/strong&gt; Refresh tokens are more sensitive than access tokens and should be stored securely on the server-side (e.g., database) to prevent unauthorized use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Flow of Authentication
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Login:&lt;/strong&gt; The user enters their credentials (username and password) to log in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; The server verifies the credentials and, upon successful authentication, issues an access token and a refresh token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access:&lt;/strong&gt; The user interacts with the application, sending the access token with each request to access resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expiration:&lt;/strong&gt; As the access token nears its expiration, the application sends the refresh token to the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refresh:&lt;/strong&gt; The server verifies the refresh token and, if valid, issues a new access token, allowing the user to continue accessing resources without needing to re-login.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Benefits of Using Access and Refresh Tokens
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security:&lt;/strong&gt; Short-lived access tokens minimize the risk of unauthorized access even if compromised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved User Experience:&lt;/strong&gt; Refresh tokens prevent frequent login prompts, ensuring a smooth and uninterrupted user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Server Load:&lt;/strong&gt; By using cached access tokens, the server is not overloaded with constant authentication requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Access tokens and refresh tokens play a vital role in secure and user-friendly authentication. Understanding their distinct characteristics and their coordinated function is essential for building robust web applications. By implementing this two-token approach, we can ensure a seamless user experience while safeguarding sensitive data within our application or API.&lt;/p&gt;

</description>
      <category>security</category>
      <category>jwt</category>
      <category>token</category>
      <category>authentication</category>
    </item>
    <item>
      <title>TanStack Table Explained: Everything You Need to Know</title>
      <dc:creator>Arnab Saha</dc:creator>
      <pubDate>Fri, 28 Jun 2024 12:37:49 +0000</pubDate>
      <link>https://forem.com/arnabsahawrk/tanstack-table-explained-everything-you-need-to-know-16g9</link>
      <guid>https://forem.com/arnabsahawrk/tanstack-table-explained-everything-you-need-to-know-16g9</guid>
      <description>&lt;p&gt;&lt;em&gt;Unlocking TanStack table potential to get started with it. Learn by creating something cool with it.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the world of modern web development, displaying data effectively and efficiently is a common challenge. Whether it's a simple list of users or a complex financial report, tables are essential. While there are many libraries available to handle tables in React, few offer the flexibility, performance, and ease of use that TanStack Table does.&lt;/p&gt;

&lt;p&gt;TanStack Table, previously known as React Table, has quickly become the go-to solution for developers needing powerful and customizable table components. TanStack is not only compatible with React but it also supports Angular, Lit, Qwik, Solid, Svelte, Vue, and also Vanilla JavaScript/TypeScript.&lt;/p&gt;

&lt;p&gt;In this post, I'll dive into what makes TanStack Table stand out, explore its core features, and provide a hands-on example to get you started.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is TanStack Table?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;TanStack Table is a lightweight, highly customizable, and headless UI for building powerful tables &amp;amp; data grids. By "headless," I mean it comes with all the core functionality and logic for table operations without any user interface. This gives us total control over our table's appearance while also taking advantage of the built-in functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Choose the TanStack Table?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Choosing a table library for your project can be confusing as so many options are available online. Here’s why TanStack Table might be the best fit for your next project:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Performance&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;When our dataset is large, managing it efficiently becomes crucial as we also have to take performance into account. TanStack uses features like Virtualization and Tree shaking which are methods for optimizing performance. It also optimizes rendering to ensure that even if there are tens of thousands of rows the performance is smooth.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tree shaking&lt;/strong&gt; is a process of optimizing during final javascript bundling, it removes all the dead code or unused code from the bundle.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Virtualization or Windowing&lt;/strong&gt; is a technique to improve performance by only rendering the items that are currently in view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Adaptability&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;TanStack table supports headless architecture which allows us to be free from any built-in UI. Its high customizability lets us integrate it with any CSS framework or theme. This flexibility comes in very handy when design changes are required for almost every project.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Advanced Feature&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;TanStack Table supports a wide range of feature lists such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sorting with customizable sort functions.&lt;/li&gt;
&lt;li&gt;Built-in filters or custom filter logic.&lt;/li&gt;
&lt;li&gt;Hide or unhide any column.&lt;/li&gt;
&lt;li&gt;Built-in pagination logic.&lt;/li&gt;
&lt;li&gt;Group rows by any criteria.&lt;/li&gt;
&lt;li&gt;Dynamic resizing of columns.&lt;/li&gt;
&lt;li&gt;Select rows with checkboxes or other UI elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4. Active Community and Support&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;TanStack Table is actively maintained and is supported by a great community. The documentation is precise and easy to understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key Challenges When Using TanStack Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Although TanStack Table offers many advantages, it also has some drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing column width according to data length.&lt;/li&gt;
&lt;li&gt;Making the table responsive for all screen sizes.&lt;/li&gt;
&lt;li&gt;Debugging a custom build table using the TanStack table.&lt;/li&gt;
&lt;li&gt;Comprehensive documents can make it difficult to find quick answers.&lt;/li&gt;
&lt;li&gt;The learning curve is steep.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting Started with TanStack Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's start with a simple example. I'll create a basic table using TanStack Table.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 1: Install TanStack Table&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;First, let's install TanStack Table and its peer dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @tanstack/react-table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Step 2: Set Up the Table&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I'll start by setting up our table component. For this example, I’ll use a simple dataset of users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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;createColumnHelper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;flexRender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getCoreRowModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useReactTable&lt;/span&gt;&lt;span class="p"&gt;,&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;@tanstack/react-table&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;wallet_balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john.doe@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;United States&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Premium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;wallet_balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;150.25&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="na"&gt;id&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice Smith&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice.smith@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Canada&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Basic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;wallet_balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;50.75&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;const&lt;/span&gt; &lt;span class="nx"&gt;columnHelper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createColumnHelper&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;country&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Country&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="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Subscription&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="nx"&gt;columnHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wallet_balance&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;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Wallet balance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&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="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;_setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;users&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;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useReactTable&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;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;getCoreRowModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getCoreRowModel&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;table&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;thead&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHeaderGroups&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;headerGroup&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;headerGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;headerGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;header&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPlaceholder&lt;/span&gt;
                  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
                  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;flexRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;columnDef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;thead&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tbody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRowModel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getVisibleCells&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;cell&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;flexRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;columnDef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tbody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;table&lt;/span&gt;&lt;span class="p"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we have the users data to populate the table. I'm using the createColumnHelper function to create columnHelper which is then used to define an array of columns. These columns decide how data will appear in the table. It creates columns according to the header I have provided. In this case, it is "Name," "Age," "Email," etc. We can customize cell rendering behavior by providing the cell property. If it is not provided then it indicates that the default cell rendering behavior will be used.&lt;/p&gt;

&lt;p&gt;The useReactTable hook is used to set up a table component with data and column configurations. This configuration decides how data will be rendered in the table. I'm using table.getHeaderGroups() and table.getRowModel().rows for generating the header and body of the table.&lt;/p&gt;

&lt;p&gt;After some styling, the table would look like the below image:&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%2F0thtfw2zktnd4mrttul7.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%2F0thtfw2zktnd4mrttul7.png" alt="https://github.com/arnabsahawrk" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 3: Customize Accordingly&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;You can now start customizing the table according to your needs. You can add search, sorting, pagination, or any other features. TanStack provides the hooks and ease to add all this functionality. You can refer to their official documentation &lt;a href="https://tanstack.com/table/latest/docs/introduction" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;TanStack Table could be a great option for your next project. Its headless UI makes design integration effortless, and its rich feature set makes it simple to create pagination, sorting, filtering, and other features. For further clarity, explore additional examples in the documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>tanstack</category>
      <category>tanstacktable</category>
      <category>reacttable</category>
      <category>react</category>
    </item>
    <item>
      <title>Why Should We Use React For the Front-End?</title>
      <dc:creator>Arnab Saha</dc:creator>
      <pubDate>Sat, 18 May 2024 08:15:12 +0000</pubDate>
      <link>https://forem.com/arnabsahawrk/why-should-we-use-react-for-the-front-end-40e9</link>
      <guid>https://forem.com/arnabsahawrk/why-should-we-use-react-for-the-front-end-40e9</guid>
      <description>&lt;p&gt;React JS is a JavaScript library built and maintained by Facebook. React is an efficient, declarative, and flexible open-source JavaScript library for creating simple, fast, and scalable frontends of web applications.&lt;/p&gt;

&lt;p&gt;The language used to build React applications is JSX. JSX is basic JavaScript that facilitates HTML quoting and uses the syntax of this HTML tag to make subcomponents.&lt;/p&gt;

&lt;p&gt;ReactJS is a stronger framework because of its ability to break down the complex interface and allow users to work on individual components.&lt;/p&gt;

&lt;p&gt;ReactJS's core objective is to deliver the best rendering performance possible. Its strength stems from the emphasis on individual parts. ReactJS helps developers break down the complicated UI into smaller components, rather than operating on the entire web framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Benefits of React JS for Front-End Development
&lt;/h2&gt;

&lt;p&gt;React JS offers tons of benefits. Let’s see the key benefits of React JS to understand why it stands out from other front-end JavaScript development frameworks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;p&gt;React allows developers to utilize individual parts of their application on both the client-side and the server-side, which ultimately boosts the speed of the development process.&lt;/p&gt;

&lt;p&gt;In simple terms, different developers can write individual parts and all changes made won’t affect the logic of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexibility
&lt;/h3&gt;

&lt;p&gt;Compared to other front-end frameworks, the React code is easier to maintain and is flexible due to its modular structure. This flexibility, in turn, saves a huge amount of time and cost for businesses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;React JS was designed to provide high performance in mind. The core of the framework offers a virtual DOM program and server-side rendering, which makes complex apps run extremely fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usability
&lt;/h3&gt;

&lt;p&gt;Deploying React is fairly easy to accomplish if you have some basic knowledge of JavaScript.&lt;/p&gt;

&lt;p&gt;In fact, an expert JavaScript developer can easily learn all the ins and outs of the React framework in a matter of a day or two.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reusable Components
&lt;/h3&gt;

&lt;p&gt;One of the main benefits of using React JS is its potential to reuse components. It saves time for developers as they don’t have to write various codes for the same features. Furthermore, if any changes are made in any particular part, it will not affect other parts of the application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So, now that you know the key benefits of the React framework, let’s move forward and also check out the top reasons to Choose React JS for your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why React JS Can Be the Best Choice for Your Project
&lt;/h2&gt;

&lt;p&gt;If you are still not sure whether to choose React JS for your project or not, these reasons will help you make the decision.&lt;/p&gt;

&lt;p&gt;Below, I mention the top reasons why React JS can be the best framework for your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  It helps to build rich user interfaces
&lt;/h3&gt;

&lt;p&gt;Today, the quality of the user interface in an application plays an important role. If the user interface is poorly designed, then it lowers the chances of an application to succeed.&lt;/p&gt;

&lt;p&gt;But, if an application has a high-quality UI, then there are better chances that your users will love to use the app.&lt;/p&gt;

&lt;p&gt;Therefore, building rich user interfaces is sort of necessary for an application to survive and thrive.&lt;/p&gt;

&lt;p&gt;The good news is that React allows building such high-quality, rich user interfaces through its declarative components, which brings us to our next point.&lt;/p&gt;

&lt;h3&gt;
  
  
  It allows writing custom components
&lt;/h3&gt;

&lt;p&gt;React comes with JSX, an optional syntax extension, which makes it possible to write your own components.&lt;/p&gt;

&lt;p&gt;These components accept HTML quoting and also make all subcomponent rendering a delightful experience for developers.&lt;/p&gt;

&lt;p&gt;Though there have been many debates on the matter of JSX, it has already for writing custom components, building high-volume applications, and converting HTML mockups into ReactElement trees.&lt;/p&gt;

&lt;p&gt;Not only this but after creating components developers can reuse them in the whole app as components are highly customizable, and due to this it speeds up the development process.&lt;/p&gt;

&lt;h3&gt;
  
  
  It uplifts developers’ productivity
&lt;/h3&gt;

&lt;p&gt;Frequent updates often turn into headaches when an app has complex logic and when a single modification in one component can dramatically affect other components.&lt;/p&gt;

&lt;p&gt;But, to combat this problem, Facebook has amplified React with the component reusability feature.&lt;/p&gt;

&lt;p&gt;Component reusability in React basically allows developers to redeploy the same digital objects.&lt;/p&gt;

&lt;p&gt;The process is simple too! – developers, for example, can begin adding simple components such as buttons, text fields, and checkboxes and then move them to wrapper components, which are ultimately moved forward to the root component.&lt;/p&gt;

&lt;p&gt;This approach provides better code maintenance and growth as each component in React has its own internal logic, which is easy to manipulate and as a result, boosts the productivity of application development.&lt;/p&gt;

&lt;h3&gt;
  
  
  It offers fast rendering
&lt;/h3&gt;

&lt;p&gt;When you’re building a complex, high-load app, it becomes mandatory to define the structure of the app in the beginning since it can impact the performance of your app.&lt;/p&gt;

&lt;p&gt;In simple words, the DOM model is tree-structured. So, a minor modification at a higher level layer can awfully impact the user interface of an application. To solve this, Facebook has introduced a virtual DOM feature.&lt;/p&gt;

&lt;p&gt;Virtual DOM, as the name suggests, is the virtual representation of DOM that allows testing all changes to the virtual DOM first to calculate risks with each modification.&lt;/p&gt;

&lt;p&gt;This approach, as a result, helps to maintain high app performance and guarantees a better user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  It comes with useful developer toolset
&lt;/h3&gt;

&lt;p&gt;Learning emerging technologies and using them in real-life projects can be both fun and beneficial, but only if they are used correctly.&lt;/p&gt;

&lt;p&gt;Facebook understands this, and it’s for this reason they have added much-needed React dev tools and Chrome dev tools to their React JS framework.&lt;/p&gt;

&lt;p&gt;These React tools help developers discover child and parent components, observe component hierarchies, and inspect components’ present state and props.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strong community support
&lt;/h3&gt;

&lt;p&gt;One of the biggest reasons why you should choose React for front-end development is that it has very strong community support. A large community of React developers is making it better as it’s an open-source library and coders from around the world are helping people learn the technology in different ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  ToolKit support
&lt;/h3&gt;

&lt;p&gt;In the market there bunch of toolkits are available that can be used to start the upper level of development directly as the toolkit contains provides bundle of configuration and code of boilerplate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Actually, one of the reasons why I believe React is better than other frameworks is that it has a larger community support and, great development tooling and it has tons of different libraries for every use case. Also, I should mention that React has maintained a much more stable API compared to Angular and Vue at this juncture.&lt;/p&gt;

&lt;p&gt;From my perspective, these things make React the best choice for enterprise web application development.&lt;/p&gt;

&lt;p&gt;But, React has some trade-offs too. Apart from the advantages of React that were mentioned above, React has some problems too:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Too much boilerplate code to write&lt;/li&gt;
&lt;li&gt;Really complicated state management strategies&lt;/li&gt;
&lt;li&gt;Too easy to abuse its features and develop applications in a wrong way&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sometimes, it's worth to use React and sometimes it's not. I believe choosing a web app framework depends on the type of project. The framework that fits your project's needs is the perfect choice.&lt;/p&gt;

</description>
      <category>react</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
