In this guide, I'm going to walk you through the steps to set up a Vite project with TypeScript to create a basic to-do list application. We're going to keep it simple and build this without using a framework or library so we can focus on the core functionality of Vite.
Project Setup
To start, you need to have Node.js and npm installed on your computer. Once you have those, open your terminal and run the following commands to create a new Vite project:
# Create a new Vite project
npm create vite@latest my-todo-app -- --template vanilla-ts
# Navigate into the project directory
cd my-todo-app
# Install dependencies
npm install
# Open the project in your code editor
code .
These commands will set up a new directory called my-todo-app
with a basic Vite project that uses TypeScript. The npm create vite@latest
command creates the project structure using the vanilla-ts
template, which is perfect for our needs. After navigating into the directory and installing the dependencies, you can open the project in your code editor to start working on it.
Project Structure
After setting up the project, you'll see a structure that looks like this:
my-todo-app/
├── node_modules/
├── public/
│ └── vite.svg
├── src/
│ ├── main.ts
│ └── style.css
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
└── package-lock.json
This structure includes the necessary files for a Vite project with TypeScript. The src
folder contains your main TypeScript file (main.ts
), and the public
folder holds static assets like the Vite logo. The index.html
file is the entry point for your web application, and package.json
lists your project's dependencies and scripts.
Modifying src/main.ts
Next, we need to modify the src/main.ts
file to include our to-do list functionality. Replace the existing content with the following code:
interface Todo {
id: number;
text: string;
completed: boolean;
}
let todos: Todo[] = [];
let nextTodoId = 1;
const todoInput = document.createElement('input');
todoInput.type = 'text';
todoInput.placeholder = 'Enter a new todo';
const addButton = document.createElement('button');
addButton.textContent = 'Add Todo';
const todoList = document.createElement('ul');
document.body.appendChild(todoInput);
document.body.appendChild(addButton);
document.body.appendChild(todoList);
function renderTodos() {
todoList.innerHTML = '';
todos.forEach(todo => {
const listItem = document.createElement('li');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = todo.completed;
checkbox.addEventListener('change', () => toggleTodo(todo.id));
const label = document.createElement('label');
label.textContent = todo.text;
label.style.textDecoration = todo.completed ? 'line-through' : 'none';
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.addEventListener('click', () => deleteTodo(todo.id));
listItem.appendChild(checkbox);
listItem.appendChild(label);
listItem.appendChild(deleteButton);
todoList.appendChild(listItem);
});
}
function addTodo() {
const text = todoInput.value.trim();
if (!text) return;
const newTodo: Todo = {
id: nextTodoId++,
text: text,
completed: false,
};
todos.push(newTodo);
todoInput.value = '';
renderTodos();
}
function toggleTodo(id: number) {
todos = todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
);
renderTodos();
}
function deleteTodo(id: number) {
todos = todos.filter(todo => todo.id !== id);
renderTodos();
}
addButton.addEventListener('click', addTodo);
renderTodos();
This code sets up a simple to-do list with the ability to add new items, mark them as completed, and delete them. We use TypeScript to define the structure of our to-do items and ensure type safety throughout our code.
Modifying index.html
Now, we need to update the index.html
file to include our TypeScript code. Replace the contents of index.html
with the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS To-Do</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
This HTML file serves as the entry point for our application. It includes a script tag that points to our main.ts
file, allowing our TypeScript code to run in the browser.
Running the Development Server
To see your to-do list in action, go back to your terminal and run the following command:
npm run dev
This command starts the Vite development server, which will bundle your code and make it available at http://localhost:5173
. Open this URL in your browser, and you'll see your basic to-do list application up and running.
Building the App
Once you have made the final changes to the code and are ready to build the app, you can run the following command:
npm run build
This will create a production build of your application in the dist
folder where all the files will be bundled and ready to be served to your users.
Final Thoughts
As you can see, it's very easy to set up Vite with a simple TypeScript project and get a lot of functionality out of the box. Vite takes care of the bundling, so you don't need to worry about setting up a complex build pipeline yourself. Of course, we can take this a lot further by adding a UI framework like React, Vue and other libraries like TailwindCSS for styling and more.
Top comments (9)
What do the cool kids use these days besides vite?
Honestly Vite is amazing! haha
why no early return here?
That's a good catch! I also prefer guard statements over nested ifs but this one slipped my mind. I'll update the post now.
Yeah your update was correct but the suggestion is not: you caught that it should be
but also, you can shorthand the text property assignment
whoopsie, that was a typo. Thanks for correcting!
You're very welcome, I love that you used Vanilla DOM for this! Big ups!
This guide walks you through setting up a simple to-do list application using Vite and TypeScript. You'll first create a new Vite project with the vanilla-ts template and install the necessary dependencies. The project structure includes essential files like main.ts, index.html, and tsconfig.json. You'll modify main.ts to implement the to-do list functionality, such as adding, marking as completed, and deleting items, with type safety ensured by TypeScript. The index.html file is updated to link to the TypeScript code, and running npm run dev will start the Vite development server. Finally, npm run build will bundle your app for production.
Nice article with a great step by step!
If you are looking for something already set up with Vite and Typescript, including hooking it up to the backend, check out the open-source serverless first fullstack framework ⚡️ Baseline ⚡️ github.com/Baseline-JS/core