<?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: Dev Khatri</title>
    <description>The latest articles on Forem by Dev Khatri (@devk3).</description>
    <link>https://forem.com/devk3</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%2F188996%2F28169215-5d6e-4e33-89cb-161d0fd86464.png</url>
      <title>Forem: Dev Khatri</title>
      <link>https://forem.com/devk3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devk3"/>
    <language>en</language>
    <item>
      <title>I Built a Full-Stack Vite + React + Tailwind + Node.js + TypeScript Boilerplate — Feedback Welcome!</title>
      <dc:creator>Dev Khatri</dc:creator>
      <pubDate>Thu, 03 Jul 2025 16:33:20 +0000</pubDate>
      <link>https://forem.com/devk3/i-built-a-full-stack-vite-react-tailwind-nodejs-typescript-boilerplate-feedback-welcome-15im</link>
      <guid>https://forem.com/devk3/i-built-a-full-stack-vite-react-tailwind-nodejs-typescript-boilerplate-feedback-welcome-15im</guid>
      <description>&lt;p&gt;Hi devs! 👋&lt;/p&gt;

&lt;p&gt;I recently built a full-stack boilerplate combining Vite, React, TailwindCSS, Express, and TypeScript — and open-sourced it on GitHub!&lt;/p&gt;

&lt;p&gt;🔗 Repo: &lt;a href="https://github.com/khatridev/vite-react-node-ts" rel="noopener noreferrer"&gt;https://github.com/khatridev/vite-react-node-ts&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Why I Made This Boilerplate
&lt;/h4&gt;

&lt;p&gt;Over the years as a full-stack JavaScript developer, I found myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Repeating setup steps for every project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manually configuring TypeScript, ESLint, Prettier, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Constantly tweaking dev scripts and folder structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So I decided to package a clean, modern, monorepo setup that just works out of the box — and can serve as a starting point for real-world full-stack projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Tech Stack
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vite + React + TailwindCSS + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Express + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling&lt;/td&gt;
&lt;td&gt;ESLint + Prettier + Vitest + TSX (dev)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structure&lt;/td&gt;
&lt;td&gt;Monorepo (client/ + server/)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🙏 Feedback Welcome!&lt;br&gt;
I’d love to hear what you think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What would you improve?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What features would make this more useful?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to drop a comment here or open an issue/PR on GitHub.&lt;/p&gt;

&lt;p&gt;🌟 Star It If You Like It&lt;br&gt;
If you think this boilerplate can help others — please consider starring the &lt;a href="https://github.com/khatridev/vite-react-node-ts" rel="noopener noreferrer"&gt;repo &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>vite</category>
      <category>fullstack</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>create todo app in react</title>
      <dc:creator>Dev Khatri</dc:creator>
      <pubDate>Mon, 04 May 2020 08:15:13 +0000</pubDate>
      <link>https://forem.com/devk3/create-todo-app-in-react-4eda</link>
      <guid>https://forem.com/devk3/create-todo-app-in-react-4eda</guid>
      <description>&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;Learn some concepts of react while creating a todo list app&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's start
&lt;/h1&gt;

&lt;p&gt;A basic todo list would have following things for sure,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add todo &lt;/li&gt;
&lt;li&gt;show todo &lt;/li&gt;
&lt;li&gt;delete todo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;visualization is more important, they say..&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%2Ft5gnawzqlthxfgtyq3c0.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%2Ft5gnawzqlthxfgtyq3c0.png" width="624" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so let’s create something like this…&lt;/p&gt;

&lt;h4&gt;
  
  
  Add TODO
&lt;/h4&gt;

&lt;p&gt;To add an item we would need a simple textbox&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="text"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;let's put some state in place&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.state = { new_text: "" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;now text box takes the value from our state&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="text" value={this.state.new_text} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;now if we type anything in the textbox, we may not see any values getting typed in the textbox,&lt;br&gt;
because textbox is getting the value from the state and that is empty and not getting updated yet.&lt;/p&gt;

&lt;p&gt;How do we update our state now ?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="text" onChange={handleChange} value={todo.text} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;function,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handleChange(e) {
    this.setState({ new_text: e.target.value })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;now we have our todo in sync with component state, &lt;/p&gt;

&lt;p&gt;but our state is handling one item at a time. we may have to update our state definition that stores multiple items,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.state = {
    items: [],
    new_text: ""
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;let’s use form submit to set todo&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form onSubmit={this.handleSubmit}&amp;gt;
  &amp;lt;input type="text" onChange={this.handleChange} value={this.state.new_text} /&amp;gt;
    &amp;lt;button&amp;gt;Add&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;function,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handleSubmit(e){
    e.preventDefault();
    let newItem = {
        new_text : this.state.new_text
    }
    this.setState(state=&amp;gt;({
        items : state.items.concat(newItem),
        new_text:''
      }))
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: when any form submit is performed, page re-renders hence preventing it,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          event.preventDefault();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;our next task is to show the todos in the list below the textbox.&lt;/p&gt;

&lt;h4&gt;
  
  
  Show todo
&lt;/h4&gt;

&lt;p&gt;Add a list to show all the todos, to display the list items we add one more component [Todolist] and add a list in it&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  {this.props.items.map(item=&amp;gt;(
      &amp;lt;li&amp;gt;{item.new_text}
      &amp;lt;/li&amp;gt;
  ))}
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and display just below the textbox,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;Todolist items = {this.state.items} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have our app that lets us type text in text box , and shows the list under it, but what is this error in the console !!&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%2Fr9uvner9brxnl4f3vv1l.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%2Fr9uvner9brxnl4f3vv1l.png" width="800" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this is caused when you are displaying items and has no unique identifier, hence we may have to add some unique identifier for the list item.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Dates are important" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s put the id wherever we are using our list items&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; handleSubmit(e){
        e.preventDefault();
        let newItem = {
            new_text : this.state.new_text,
            id: Date.now()
        }
        this.setState(state=&amp;gt;({
            items : state.items.concat(newItem),
            new_text:''
        }))
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and while showing the list items,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  {this.props.items.map(item=&amp;gt;(
      &amp;lt;li key={item.id}&amp;gt;{item.new_text}
      &amp;lt;/li&amp;gt;
  ))}
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;now we have our app running without any error.&lt;/p&gt;

&lt;p&gt;This is the flow for our app,&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%2F7h67jbb92qgh91qpn7fb.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%2F7h67jbb92qgh91qpn7fb.png" width="669" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait, we discussed delete as well right…&lt;/p&gt;

&lt;p&gt;How do we accommodate delete functionality here, when one component triggers action and another component must be updated. Currently, child component does not have capability to update the state.&lt;/p&gt;

&lt;p&gt;To achieve this, we will use react hooks.&lt;/p&gt;

&lt;p&gt;There are many ways we can add hooks, I like the following, &lt;/p&gt;

&lt;p&gt;we create a separate file that performs all the crud information on the state and uses the state internally&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const TodoRepo = (initialValue = []) =&amp;gt; {
    const [todos, setTodos] = useState([]);
    return {
        todos,
        addTodo: item =&amp;gt; {
            if (item.new_text != "") {
                setTodos(
                    todos.concat(item)
                )
            }
        },
        deleteTodo: item =&amp;gt; {
            if (item.new_text != "") {
                setTodos(
                    todos.filter((td) =&amp;gt; {
                        return td.id != item.id
                    })
                )
            }
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and we use this js file in our first component [ Todo_App]&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    {todos.map(item =&amp;gt; (
      &amp;lt;li key={item.id}&amp;gt;{item.new_text}&amp;lt;button onClick={()=&amp;gt;{deleteTodo(item)}}&amp;gt; delete&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;
    ))}
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have the hooks configured in our app that adds/shows/deletes list items.I have setup the todo list with material-ui and have deployed here,&lt;br&gt;
&lt;a href="https://github.com/khatridev/react-todolist" rel="noopener noreferrer"&gt;https://github.com/khatridev/react-todolist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will keep adding more features in it, would be happy to hear any feedbacks.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Starting to write blog</title>
      <dc:creator>Dev Khatri</dc:creator>
      <pubDate>Sun, 15 Mar 2020 06:16:03 +0000</pubDate>
      <link>https://forem.com/devk3/starting-to-write-blog-5e8a</link>
      <guid>https://forem.com/devk3/starting-to-write-blog-5e8a</guid>
      <description>&lt;p&gt;I want to start writing technical blogs, want to know the starter plans&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
