Full-Stack Development in a Todo App: 35 Core Technologies Every Programmer Should Know
Full-Stack Development in a Todo App: …
A todo app as the lens to explore 35 essential full-stack development technologies every programmer should know.
This article uses the complete development lifecycle of a todo app to systematically cover 35 core full-stack technologies. From the frontend trio (HTML, CSS, JavaScript) to backend frameworks, databases, Docker containerization, CI/CD pipelines, cloud services, and scaling architecture, it helps programmers build a clear technology knowledge map and understand when to apply each tool.
Introduction: The Technology Universe Behind a Todo App
"I have a great startup idea — a to-do list app." Sounds simple, right? But when you actually start building it, you'll discover that from frontend to backend, from databases to cloud deployment, a seemingly simple application involves up to 35 core technologies.
This is the reality of full-stack development. This article uses the complete development lifecycle of a todo app as a thread to systematically walk through the key technology stacks programmers need to understand, helping you build a clear full-stack knowledge map.
The Frontend Trio: Everything the User Sees
HTML, CSS, and the DOM — The Skeleton and Skin of a Page
Everything starts with what users can see. HTML (HyperText Markup Language) is the foundation for structuring content in browsers, organizing page elements through tags — tables, paragraphs, div containers, and more. However, pure HTML pages look visually rough.
When an HTML page loads in a browser, the browser parses it and creates the DOM (Document Object Model) — an in-memory tree structure representing every element, attribute, and text fragment. This structure is the foundation for subsequent dynamic manipulation. The DOM isn't just a static tree; it's a programming interface provided by the browser. When JavaScript calls document.getElementById() or querySelector(), it's actually performing node lookups on this tree. One of the core innovations of modern frontend frameworks — the Virtual DOM — was created specifically to address performance issues caused by frequent real DOM manipulation. Frameworks like React maintain a lightweight copy of the DOM in memory, use a diff algorithm to calculate the minimal set of changes, then batch-update the real DOM, significantly reducing browser reflow and repaint operations.
To make pages visually appealing, you need CSS (Cascading Style Sheets). It controls fonts, layouts, colors, and all visual presentation. "Cascading" means styles are processed according to priority rules that handle hierarchy and inheritance between elements.
JavaScript — Bringing Pages to Life
JavaScript is a high-level interpreted programming language that dynamically manipulates the DOM on the frontend. Want a button to change color? Want to respond to user clicks? All this interactive logic is implemented by JavaScript. It's event-driven, with much of the code centered around "writing functions to respond to user actions."
At this point, you have a todo list that runs in a browser. But a new problem emerges — who would pay for a tool that only works when the browser is open?
Backend Fundamentals: Making the App Actually Work
Servers, Operating Systems, and Backend Languages
We need a backend that can continuously execute code and remember user identities. A server is essentially a computer, but one optimized for high loads and 24/7 operation, typically accessed via command line.
Approximately 95% of servers run the open-source Linux operating system, with common distributions including Ubuntu, Debian, and Red Hat. Linux dominates the server market for several key reasons: First, being open-source and free means enterprises don't need to pay expensive OS licensing fees. Second, Linux's modular design allows administrators to install only necessary components, reducing the attack surface and resource consumption. Third, virtually all major cloud providers (AWS, Google Cloud, Azure) use Linux as their default base image. It's worth noting that even on Microsoft's Azure cloud platform, over 60% of virtual machines run Linux.
The choice of backend programming languages is abundant: C#, Ruby, Python, Go, Rust, and more. Their core purpose is to provide business logic for the application — processing credit card payments, running intensive computations, saving data to databases. Each language has its pros and cons, but in the early stages of a project, don't spend weeks agonizing over the choice — getting something running matters more.
HTTP Protocol and Backend Frameworks
How do the frontend and backend communicate? The answer is HTTP (HyperText Transfer Protocol). Clients send requests using methods like GET, POST, and PUT, and the server receives them and returns responses containing status codes and data. The key point: clients can contact the server at any time, but the server can only reply when it receives a request.
A core design principle of HTTP is statelessness — the server doesn't remember previous requests. This means each request is independent, and the server doesn't know who is making the request. To solve this problem, web development introduced mechanisms like Cookies, Sessions, and JWT (JSON Web Token). Cookies are stored in the client's browser and automatically attached to each request; Sessions save state on the server side; JWT encodes user information in an encrypted format carried by the client, with the server verifying identity by validating the signature. JWT is particularly suited for distributed systems because it doesn't require sharing session state between servers.
Running an application directly exposed to the internet isn't advisable. Nginx or Apache web server software acts as a reverse proxy, directing requests in the right direction, with significant benefits for privacy, security, and performance.
Backend frameworks (such as Express for Node.js, Django/FastAPI for Python, Ruby on Rails) are the core tools for handling HTTP requests. They help you fetch data from databases, create response documents, and return them to users.
Frontend Frameworks and Cross-Platform Development
SPA Single-Page Applications and Server-Side Rendering
As your app grows in popularity, plain HTML pages will feel slow to users — every action requires reloading the entire page. Frontend frameworks (React, Vue, Svelte) let you build Single-Page Applications (SPAs), where JavaScript in the browser drives page updates. User actions don't require page reloads, resulting in a much smoother experience.
However, SPAs have SEO drawbacks. The root cause lies in how search engine crawlers work: when traditional crawlers request a page, an SPA returns only a nearly empty HTML shell and a large chunk of JavaScript code. Although Google's crawler can execute JavaScript, the rendering cost is high, wait times are long, and there's no guarantee all content will be correctly indexed. Additionally, SPAs face longer Time to First Contentful Paint, because users must wait for the entire JavaScript bundle to download and execute before seeing any content.
Server-side rendering frameworks (Next.js for React, Nuxt for Vue) were created specifically to solve these problems. They preserve the development experience of frontend frameworks while gaining the SEO and initial load speed advantages of server-side rendering — the mainstream choice for balancing performance and search engine friendliness.
Cross-Platform Mobile Solutions
In native development, iOS uses Swift/Xcode and Android uses Kotlin/Android Studio, requiring learning different languages and ecosystems. Cross-platform solutions like Flutter (Dart language) or React Native (JavaScript) let you compile one codebase to both platforms, significantly reducing development and maintenance costs.
The Data Layer: Far More Than Just Spreadsheets
Choosing Between Relational Databases and NoSQL
Relational databases (such as PostgreSQL, MySQL) store data in tables, with tables linked through foreign keys to eliminate duplicate data. For example, a users table stores user information, a tasks table stores todo items, and foreign keys connect the two. They rely on strict schema definitions and are suited for business scenarios with clear data relationships.
The reason relational databases remain irreplaceable in critical business areas like finance and e-commerce comes down to their ACID transaction guarantees: Atomicity ensures a group of operations either all succeed or all roll back; Consistency guarantees data always remains in a valid state; Isolation prevents concurrent transactions from interfering with each other; Durability ensures committed data is never lost. For example, in a bank transfer scenario, debiting Account A and crediting Account B must execute as an atomic operation — if either step fails, everything must roll back. This is something NoSQL databases typically cannot natively guarantee.
NoSQL databases (such as MongoDB) don't rely on fixed schemas, typically use document-based storage, and are suited for handling large volumes of unstructured data, such as analytics logs and social media content.
In real projects, combining both types of databases is common practice. The key is choosing the right solution based on your data characteristics.
Redis Caching and WebSocket Real-Time Communication
When your app needs real-time chat functionality, even a one-second delay can severely impact the experience. Redis stores key-value pairs in memory rather than on disk, providing extremely fast access speeds — an essential tool for real-time scenarios and cache acceleration.
For real-time communication, HTTP polling is too inefficient. The WebSocket protocol establishes a persistent connection through a single handshake, allowing uninterrupted bidirectional messaging between server and client — perfect for chat, collaborative editing, and other real-time interaction needs.
DevOps and Deployment: From Code to Production
Git Version Control and Build Tools
Team collaboration requires Git version control — it's like a tree where the main codebase can branch out for independent development, then safely merge back into the trunk when complete. GitHub is essentially "a cloud-based code repository managed with Git," hosting project code and supporting collaboration.
Build tools (such as Webpack, Vite) play an important role before deployment: removing unused imports, compressing images and code, compiling JavaScript into a single optimized file — all significantly speeding up page load times.
Docker Containerization and CI/CD Pipelines
"It works on my machine, so why doesn't it work in production?" This is a classic problem developers frequently encounter. Docker containers solve this by building consistent runtime environment images — whether on local machines, test environments, or production servers, the results are always consistent.
Docker containers are often compared to virtual machines (VMs), but their isolation levels are completely different. VMs simulate complete hardware environments through a Hypervisor, with each VM running an independent OS kernel — startup times measured in minutes and memory usage often in the gigabytes. Docker containers share the host machine's OS kernel, achieving process-level isolation through Linux's namespace and cgroup mechanisms — startup times measured in seconds or even milliseconds, with memory usage typically in the tens of megabytes. This lightweight nature means a single server can run dozens or even hundreds of containers, while the same hardware might only support a dozen or so VMs.
Continuous Integration (CI) automatically builds, optimizes, and tests code before it enters production; Continuous Delivery (CD) ensures released code is always ready to deploy smoothly in any environment. Together, they make the entire process from development to production more efficient and reliable.
Cloud Services and Scaling: Handling Millions of Users
Cloud Storage and CDN Acceleration
Cloud services are essentially hosted versions of the technologies mentioned above. Object storage (such as AWS S3) lets you upload files without worrying about disk capacity; CDN (Content Delivery Network) is a globally distributed network of proxy servers that lets users worldwide access content from nearby locations, significantly improving access speed.
Load Balancing and Message Queues
When you have 25 machines but only one is handling all the traffic, you need a load balancer. It uses health checks to determine each server's status and distributes traffic evenly across healthy machines, ensuring service stability and availability.
Message queues (such as RabbitMQ, based on the AMQP protocol) handle asynchronous tasks that don't need immediate completion. Tasks are queued in first-in-first-out order and executed sequentially by background workers — for example, a push notification doesn't need to be sent immediately; it can be placed in a queue for later processing.
The core problems message queues solve are system decoupling and traffic peak shaving. Take an e-commerce flash sale as an example: if 100,000 users place orders simultaneously, writing directly to the database would crash the system. With a message queue, order requests first enter the queue as a buffer, and backend services consume them at their own processing capacity. Users see a "Order submitted, processing" message rather than a system error. Besides RabbitMQ, other commonly used options include Apache Kafka (suited for high-throughput log stream processing) and Redis Streams (for lightweight scenarios). Message queues also support the publish/subscribe pattern, where a single message can be independently processed by multiple consumers, enabling event-driven architecture.
Infrastructure as Code (IaC)
IaC (Infrastructure as Code) lets developers define infrastructure structure using code or configuration files. For example, by specifying Redis versions and server specifications in a configuration file, all development and production environments can remain consistent and predictable, avoiding discrepancies and errors from manual configuration.
Conclusion: The Core Philosophy of Full-Stack Technology Selection
Starting from a "simple" todo app, we've traversed 35 core technologies — from HTML to Docker, from SQL to WebSocket. This walkthrough reveals an important insight: The key to full-stack development isn't mastering every single technology, but understanding what problem each one solves and when to introduce it.
In an era where AI-assisted programming is increasingly prevalent, this holistic perspective is especially important. AI tools can help you write code, but deciding which technologies to use and how to architect a system still requires the programmer's own judgment. Rather than diving into the details of a specific technology from the start, it's better to first build a complete technology knowledge map, then gradually go deeper based on actual project needs.
Programmers who understand these 35 technologies can truly harness various development tools and build products of real value.
Related articles

Claude Code for Test Development in Practice: An AI Programming Workflow That Doubles Your Efficiency
A practical guide to Claude Code for test development: auto-generating test scripts, Plan Mode workflows, MCP + Playwright integration, and Subagent parallel tasks to build systematic AI-assisted workflows.

Hermes Agent Hands-On Review: An AI Efficiency Revolution for Indie Game Developers
Indie game developer reviews Hermes Agent vs OpenClaude: intelligent context compression, real-time Memory, remote control via Telegram, and practical use cases in game dev, social media, and email.

Vibe Coding Beginner's Guide: Tool Selection Across Three Categories with Practical Examples
A comprehensive guide to Vibe Coding's three tool categories: Agent frameworks, CLI Coding, and IDE tools, with practical examples including Snake game and data analysis workbench.