Building A Todo CRUD App With React, TypeScript, Vite And Chakra UI


Hello! ๐Ÿ˜Ž

Recently I've been learning how to use vite in a couple of projects so I thought I'd take what I've learned and show you how to create a simple Todo CRUD application using the following stack: React, TypeScript, Vite, Chakra UI.

I will also be using JsonServer which is a very useful module if you quickly need a REST server. The requests to the server will be done using the axios module.

Well then let's get started. ๐Ÿ˜†

Reasons For Using This Stack

First I want to go over why I'm using the above stack for this tutorial.

  1. React: A popular front-end library. React enables us to craft interactive user interfaces. Its component-based architecture aids in code reusuability and state management. I also deal with more React projects than Vue.js etc.
  2. TypeScript: TypeScript is a superset of JavaScript that adds static types. It helps catch errors early, enhances code quality, and provides better developer experience with IntelliSense.
  3. Vite: Vite is a modern build tool that offers lightning-fast Hot Module Replacement (HMR) for a smoother developer experience. It's optimized for the modern JS ecosystem.
  4. Chakra UI: This is a modular and accessible component library, making it simple to style our React applications without sacrificing functionality or performance.
  5. JsonServer: JsonServer mocks a REST API using a JSON file, letting frontend developers prototype and test without a backend.
  6. Axios: Axios is a JavaScript library that simplifies HTTP requests. It's more intuitive than the built in Fetch API and integrates well with modern async/await syntax.

Now lets start creating the application. ๐Ÿ˜ธ

Setting Up The Project

First we need to install the Vite CLI, open up a terminal window and enter the following command:

npm i -g create-vite

Next to create a vite project you need to run the following command:

create-vite vite-todo --template react-ts

The template tells vite we want a React TypeScript application.

Next install the dependencies via the following command:

cd vite-todo && npm i

We also need to install the dependencies that are needed for this project, this can be done via the following command:

npm install @chakra-ui/react @emotion/react @emotion/styled framer-motion

Next we need to set up our mock REST API server, this can be done by creating a simple json file, create a file called "db.json" and populate it with the following:

	"todos": []

Here we create it with an empty array to indicate there are no todos.

Next start up the mock json server with the following command:

npx json-server --watch db.json --port 5000

The server should now work at the following url: http://localhost:5000/todos

Accessing it you should get an empty array. Now we can start coding the front end. ๐Ÿ™‚

Coding The Frontend

Now we can finally start coding the frontend of the application, open up "src/App.tsx" and replace the contents with the following:

import React, {
} from 'react';
import axios from 'axios';
import {
} from '@chakra-ui/react';

type Todo = {
  id: number;
  title: string;
  completed: boolean;

const App = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [newTodo, setNewTodo] = useState<string>('');

  useEffect(() => {
    const fetchTodos = async (): Promise<void> => {
      const response = await axios.get<Todo[]>('http://localhost:5000/todos');

  }, []);

  const addTodo = async (): Promise<void> => {
    const response = await<Todo>('http://localhost:5000/todos', {
      title: newTodo,
      completed: false


  const updateTodo = async (id: number, title: string): Promise<void> => {
    const updatedTodo = { title, completed: false };
    await axios.put(`http://localhost:5000/todos/${id}`);
    setTodos( => ( === id ? { ...todo, title } : todo)));

  const deleteTodo = async (id: number): Promise<void> => {
    await axios.delete(`http://localhost:5000/todos/${id}`);
    setTodos(todos.filter(todo => !== id));

  const toggleComplete = async (id: number): Promise<void> => {
    const todo = todos.find(todo => === id);

    if (todo) {
      const updatedTodo = { ...todo, completed: !todo.completed };
      await axios.put(`http://localhost:5000/todos/${id}`, updatedTodo);
      setTodos( => ( === id ? updatedTodo : todo)));

  return (
    <Container maxW="" p={5}>
        <Heading mb={5}>Simple Todo App</Heading>

        value={ newTodo }
          (e) => setNewTodo(
        placeholder="Add a new todo"

      <Center mt={2} mb={5}>
          onClick={ addTodo }
        >Add Todo</Button>

      <VStack spacing={ 4 }>
        { => (
          <HStack key={ }>
              isChecked={ todo.completed }
                () => toggleComplete(
              defaultValue={ todo.title }
                (e) => updateTodo(,
            <Button onClick={
              () => deleteTodo(

export default App;

With the above code we import the needed dependencies, define a Todo type and create a basic UI using Chakra UI. We also provide funtions for each CRUD operation.

Next we need to edit the "src/main.tsx" file in order to display our application, open the file up and replace the contents with the following:

import React from 'react';
import { createRoot } from 'react-dom/client';
import { ChakraProvider } from '@chakra-ui/react';
import App from './App';

const container = document.getElementById('root');
const root = createRoot(container);

      <App />

All done! ๐Ÿ˜ƒ In order to run the application run the following command:

npm run dev

Next open up your browser and access the following URL: http://localhost:5173/

You should now see the following page: (I've added a couple of todos)

Image of app

Done! ๐Ÿ˜บ Feel free to play around with the UI etc.


In this tutorial I have shown you how to create a base Todo application using React, Typescript, Vite and Chakra UI, using JsonServer as the REST API and using axios to make requests to the server.

I hope this tutorial has helped you get started and I had a lot of fun learning about Vite.

Feel free to try replacing the mock REST API with a real API and database and maybe try and improve the UI.

As usual you can find the code for the tutorial on my Github:

Happy Coding! ๐Ÿ˜Ž

If you appreciate my work? I cover a variety of topics. For more, please like and follow me. Also, I love coffee.

โ€œBuy Me A Coffeeโ€

If you are looking to learn Algorithm Patterns to ace the coding interview I recommend the following course