Ready to build something cool on the Internet Computer? Let's create a todo app together. Don't worry if you're new to this - I'll walk you through everything step by step, no fancy jargon required.
Why ICP Is Pretty Cool
Think of Internet Computer like a giant, shared computer that's always online. Instead of running your app on servers owned by big companies, it runs on a network that belongs to everyone. Pretty neat, right? Here's why it's awesome:
- Your app never goes down (unless the internet itself breaks!)
- You don't need to pay for expensive servers
- Users don't pay gas fees like on other blockchains
- It's fast - like, really fast
Getting Started
First, let's get your computer ready. Open your terminal and type:
sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)"
This installs dfx - your new best friend for building ICP apps. Now create your project:
dfx new todo_app cd todo_app
Building the Brain (Backend)
Let's create the backend first. find a file called src/todo_app_backend/main.mo
and drop in this code:
import Array "mo:base/Array"; actor { // This is what each todo looks like type Todo = { id: Nat; text: Text; completed: Bool; }; // Keep all todos in one place private var todos: [Todo] = []; private var nextId: Nat = 0; // Add a new todo to the list public func addTodo(text: Text) : async Nat { let todo: Todo = { id = nextId; text = text; completed = false; }; todos := Array.append(todos, [todo]); nextId += 1; return todo.id; }; // Get all your todos public query func getTodos() : async [Todo] { return todos; }; // Mark a todo as done (or not done) public func toggleTodo(id: Nat) : async Bool { todos := Array.map(todos, func (todo: Todo) : Todo { if (todo.id == id) { return { id = todo.id; text = todo.text; completed = not todo.completed; }; }; todo; }); return true; }; // Remove a todo public func deleteTodo(id: Nat) : async Bool { todos := Array.filter(todos, func(todo: Todo) : Bool { todo.id != id }); return true; }; }
Making It Pretty (Frontend)
Now for the part you'll actually see! Create src/todo_app_frontend/src/main.jsx
:
import React, { useState, useEffect } from 'react'; import { todo_app_backend } from 'declarations/todo_app_backend'; function App() { const [todos, setTodos] = useState([]); const [newTodo, setNewTodo] = useState(''); // Get all todos when the app starts const loadTodos = async () => { const result = await todo_app_backend.getTodos(); setTodos(result); }; // Add a new todo const handleAdd = async (e) => { e.preventDefault(); if (!newTodo.trim()) return; await todo_app_backend.addTodo(newTodo); setNewTodo(''); loadTodos(); }; // Mark a todo as done/not done const handleToggle = async (id) => { await todo_app_backend.toggleTodo(id); loadTodos(); }; // Delete a todo const handleDelete = async (id) => { await todo_app_backend.deleteTodo(id); loadTodos(); }; useEffect(() => { loadTodos(); }, []); return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">Todo List</h1> <form onSubmit={handleAdd} className="mb-4"> <input type="text" value={newTodo} onChange={(e) => setNewTodo(e.target.value)} className="border p-2 mr-2" placeholder="Add new todo" /> <button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded"> Add </button> </form> <ul> {todos.map((todo) => ( <li key={todo.id} className="flex items-center mb-2"> <input type="checkbox" checked={todo.completed} onChange={() => handleToggle(todo.id)} className="mr-2" /> <span className={todo.completed ? 'line-through' : ''}> {todo.text} </span> <button onClick={() => handleDelete(todo.id)} className="ml-auto text-red-500" > Delete </button> </li> ))} </ul> </div> ); } export default App;
Starting It Up
Time to see your app in action! In your terminal:
dfx start --clean --background dfx deploy
Your app will pop up at http://localhost:4943. Pretty cool, right?
What's Actually Happening Here?
Let's break down what we just built:
-
The Motoko code (backend) is like a super-secure notebook:
- It remembers all your todos
- Gives each todo a unique ID
- Keeps track of what's done and what isn't
- Can add, check off, or delete todos
-
The React code (frontend) is like a friendly interface:
- Shows you all your todos
- Lets you type in new ones
- Has checkboxes to mark things as done
- Includes delete buttons to remove todos
Cool Things You Can Add
Now that you've got the basics working, why not spice it up? You could:
- Add due dates
- Group todos into categories
- Share todos with friends
- Add file attachments
When Things Go Wrong
Don't panic! Here's what to check:
- Is dfx running? (check with
dfx status
) - Did you save all your files?
- Are there any red error messages?
- When in doubt, try
dfx deploy
again
Need Help?
Everyone gets stuck sometimes. Here's where to find help:
- DFINITY's Discord channel
- Stack Overflow (tag: 'internet-computer')
- Internet Computer forums
Remember: every developer started exactly where you are now. Take your time, have fun, and don't be afraid to experiment - that's how we learn!
Top comments (0)