This article was inspired by a conversation with my wife. We were talking about programming and she mentioned that she never really understood how code actually turns into the apps we use every day. I realized she probably wasn't alone in that, and decided to write something that breaks it down for anyone who has ever wondered the same thing. This article aims to fill that gap, in a deliberately simplified way.
A joke in web development is that everything is just a CRUD app (create, read, update, delete). It's largely true. For anyone outside the field, I'd define an app simply as a way for users to interact with data.
Take Instagram. At its surface, it's a platform for uploading, liking, viewing, and discovering photos and reels. There's obviously a lot more going on underneath, like recommendation engines and data processing pipelines built to handle massive scale, but at its core, users are interacting with data Instagram has stored.
Now consider a video game. Games are apps too, but the experience feels nothing like scrolling a feed. You're slaying monsters, building a village, living inside a world. Even so, everything you interact with, the items, objects, and systems, is just data underneath. The experience is richer, but the loop is the same.
I'll be focusing on the web side throughout this article, since that's where my experience lives. But regardless of the domain, that core loop of users interacting with data is the thread that connects it all.
We understand that apps are just different ways of interacting with data, but what does that actually look like under the hood? To go deeper, we need to understand a core principle of how the internet works: the client and server model. Those words mean exactly what you'd expect. A client receives data, and a server provides it. When you open a browser, you're acting as a client. When you visit Instagram or YouTube, their servers are sending you data to interact with. Think of it like a restaurant. When you sit down and order a meal you are acting as a client, you tell the server then serves you your meal.
Now we understand how clients and servers interact, but how does that actually get us the videos we watch and posts we like? In web applications, everything you see in a browser is built from a combination of three tools: HTML, CSS, and JavaScript.
HTML (HyperText Markup Language) is like a human skeleton. It defines the structure and layout of a page, where the text, images, and buttons live. CSS (Cascading Style Sheets) is like a person's features, their hair color, eye color, the things that make you look like you. It styles the HTML elements and gives them their appearance. JavaScript is the brain. When you click a button and something happens, JavaScript is what makes that possible.
These tools only live on the client side of the conversation. What about the server side? This is where things get a bit more complex. When you think of a server, just think of another computer, often far more powerful than your home laptop or desktop. Its sole purpose is to efficiently deliver data to whoever is asking for it. In web applications, these servers run software called web servers, which handle incoming traffic and respond to requests from clients.
There are a ton of server side languages, each with different strengths. Languages like C++ and Rust are highly performant and give programmers fine grained control over server resources. Higher level languages like Python, PHP, and Go operate at a greater level of abstraction and are generally easier to work with. These are the languages most commonly used in web development to build the servers that handle that traffic.
There is one more layer on the server side: the database. As the name suggests, the database is where your data lives. There are many different types, but the most widely used is the relational database. These databases organize data into structured tables with rows and columns. Think of it like a highly optimized Excel spreadsheet. Just as there are many server side programming languages, there are also several relational database management systems, or RDBMS. Popular ones include PostgreSQL, Microsoft SQL Server, and SQLite.
Now that we understand the server side technologies, let's start connecting some dots. When you visit your Instagram home page, you are making a request to their web servers. In plain terms, you are saying "give me my home page data." Instagram receives that request, fetches the relevant data from their database, and sends back a web page with that data loaded in.
This is a good opportunity to go a bit deeper into how those pages are actually served. For most of the internet's history, pages were delivered through a process called server side rendering. All this means is that the server assembles everything, the HTML, CSS, JavaScript, and data, and sends back a fully built page.
A more modern approach is called client side rendering. In this paradigm the server only sends back the raw data, and the page is actually assembled in your browser. The client does the work of taking that data and rendering it into what you see on screen.
Server side rendering is generally simpler to implement and better for SEO (search engine optimization). This just means search engines like Google or Bing can more easily index your pages, making your site easier to find. Client side rendering, on the other hand, excels at creating dynamic and seamless user experiences.
Let's dive a little deeper and look at some simple code to see how developers build these experiences. The snippet below does two things: it connects to a SQLite database and fetches all of the users, then returns those users in a table to the client. There is also a button on the page that demonstrates how JavaScript works.
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import sqlite3
app = FastAPI()
def get_users():
conn = sqlite3.connect("example.db")
cursor = conn.cursor()
cursor.execute("SELECT name, email FROM users")
users = cursor.fetchall()
conn.close()
return users
@app.get("/", response_class=HTMLResponse)
def read_root():
users = get_users()
rows = "".join(f"<tr><td>{name}</td><td>{email}</td></tr>" for name, email in users)
return f"""
<html>
<head>
<title>My Page</title>
<style>
h1 {{ color: steelblue; }}
table {{ border-collapse: collapse; width: 50%; }}
td {{ padding: 8px; border: 1px solid #ccc; }}
</style>
</head>
<body>
<h1>Users</h1>
<table>
<tr><th>Name</th><th>Email</th></tr>
{rows}
</table>
<p>Count: <span id="count">0</span></p>
<button onclick="handleClick()">Click Me</button>
<script>
let count = 0;
function handleClick() {{
count++;
document.getElementById("count").innerText = count;
}}
</script>
</body>
</html>
"""
A very important note: this is a heavily simplified snippet of code. There is no security, no error handling, and no real structure. Professional applications are built with all of these things in mind, along with performance, scalability, and maintainability. A production codebase at a company like Instagram or YouTube is made up of thousands of files, written by hundreds of engineers, built and refined over many years. What we looked at here is the equivalent of a single brick, but hopefully it gives you a sense of just how much goes into laying the foundation.
At the end of the day, every app you use, whether it's Instagram, a video game, or a simple to-do list, is just data being created, read, updated, and deleted. The joke at the beginning of this article is funny because it's true. What makes each application unique is not the data itself, but the experience built around interacting with it.
We covered a lot of ground here. From the client and server model, to the three building blocks of the web, to databases and how pages are rendered and served. None of it is magic, even if it can feel that way from the outside. It is layers of tools and decisions stacked on top of each other, each solving a specific problem.
My hope is that the next time you open an app, you have a little more context for what is happening behind the scenes. Everyone is capable of understanding this stuff, it just takes someone breaking it down in plain terms. Hopefully this was a step in that direction.
Comments (0)
Leave a Comment
No comments yet. Be the first to share your thoughts!