Frontend and Backend

Introduction

When I started learning to code, nobody explained the shape of the whole system to me. Nobody sat down and said: here is what a software application actually consists of, here is how the pieces connect, here is the mental model you need before any of the specific skills make full sense.

This article is the explanation I wish someone had given me at the beginning. It is for developers who are just starting out and want to understand the whole picture before committing to a specialization. It is also for developers who have specialized — who are comfortable on one side but have a fuzzy understanding of the other — because that fuzziness has real costs that become clearer the further you go in your career.

What Is a Software Application, Really

Before frontend and backend, you need to understand what a software application actually is.

An application is a system that receives input, processes it, and produces output. That is all it is at the most abstract level. A calculator takes numbers and an operation, processes them, and shows a result. A social media platform takes a post, stores it, and shows it to other users. A banking application takes a transfer request, processes it against account balances, and updates records.

The complexity is not in the concept. It is in the scale of what “input”, “process”, and “output” mean in practice — and in the fact that modern applications do this for millions of users simultaneously, across devices they don’t control, over networks they can’t guarantee, with data that must be kept secure and consistent.

The split between frontend and backend is a practical answer to that complexity. It separates the concern of “how does the user interact with the application” from the concern of “how does the application store and process data.” Those two concerns have different requirements, different tools, and different skill sets — but they are two parts of one system, and the connection between them is where most of the interesting problems live.

What Frontend Is

Frontend is everything the user sees and directly interacts with. It is the interface — the visual layer, the interactive layer, the layer that exists on the user’s device.

When you open a web application in a browser, the browser downloads a set of files: HTML, CSS, and JavaScript. Those files are the frontend. The browser reads them and renders what you see on screen. When you click a button, JavaScript code runs in your browser. When a form validates your email address before you submit it, that validation is happening in your browser, in the frontend.

The critical thing to understand about the frontend is where it runs: on the user’s device. Not on a server somewhere. Not on infrastructure owned by the company. On the user’s phone, laptop, or tablet — in their browser. This has enormous implications.

The frontend developer does not control the device. They do not know whether the user has a fast laptop or a four-year-old phone with a cracked screen. They do not know whether the user is on fast broadband or a patchy mobile connection. They do not know whether the user is on Chrome, Firefox, or Safari. They do not know whether the user has set their operating system to a large font size, or uses a screen reader, or has disabled animations. Every frontend decision has to account for a range of devices, connections, browsers, and user preferences that the developer cannot fully predict.

This is why frontend is a genuine discipline and not just “making things look pretty.” The craft of frontend is in making an interface that works well — correctly, accessibly, performantly — for the full range of conditions in which real users will encounter it.

What frontend consists of in practice

The three foundational technologies of frontend are:

HTML — the structure. HTML defines what is on the page: headings, paragraphs, images, buttons, forms, lists. It is the skeleton. Without CSS and JavaScript, an HTML page is unstyled text and functional form elements — readable but visually minimal. Crucially, HTML is also what screen readers and search engines read. Good HTML structure is the foundation of accessibility and discoverability.

CSS — the presentation. CSS controls how HTML elements look: color, typography, layout, spacing, animation. A well-written CSS codebase can completely transform the visual appearance of an application without touching the HTML structure underneath. CSS is also the layer that makes an application responsive — able to adapt its layout to different screen sizes.

JavaScript — the behavior. JavaScript makes the interface interactive. It responds to user events (clicking, typing, scrolling), updates what the user sees without reloading the page, validates input, animates transitions, and — critically — communicates with the backend to send and receive data.

Modern frontend builds on these three technologies with frameworks and libraries: React, Angular, Vue, Svelte. These are tools that help manage the complexity of large JavaScript applications. They are not a different technology — they compile down to HTML, CSS, and JavaScript that the browser understands. But they provide structure, component models, and state management that make building complex interfaces significantly more manageable.

What a frontend developer actually does

A frontend developer builds the interfaces that users interact with. They take a design — usually from a designer, sometimes from their own judgment — and implement it as a working, interactive application in the browser.

In practice this means: building components (self-contained pieces of UI — a button, a form, a card, a navigation menu), managing the state of those components (what data they show, whether they are in a loading state, what happens when the user interacts with them), communicating with the backend to fetch and send data, handling errors gracefully when things go wrong, and ensuring the interface is accessible, performant, and consistent across the range of devices and browsers it will be used on.

What Backend Is

Backend is everything that runs on a server — infrastructure owned and controlled by the application’s developers — rather than on the user’s device.

When a user submits a form, the frontend sends that data to the backend. The backend receives it, validates it, processes it, stores it in a database, and sends a response back. The user never sees any of this happen. They see a success message, or an error, or new content — but the computation happened remotely, on hardware they cannot access.

The backend is where the application’s data lives. It is where the business logic lives — the rules that govern what the application can do, who can do it, and what happens when they try. It is where security is enforced. It is where performance at scale is managed.

Unlike the frontend, the backend developer controls the environment almost completely. They choose the server hardware or cloud infrastructure. They choose the operating system, the runtime, the database. They know exactly what CPU and memory is available. They can optimize for the specific workload the application requires. This control is one of the defining characteristics of backend development — and with it comes responsibility for reliability, security, and data integrity that the frontend simply does not carry in the same way.

What backend consists of in practice

The server — a computer (or, more commonly, many computers) that runs the backend code and listens for requests from clients (browsers, mobile apps, other servers). In modern applications, “the server” is usually cloud infrastructure — AWS, Google Cloud, Azure — that the developers configure and rent rather than physical hardware they own.

The application code — the programs that run on the server. This is where the logic lives: validate this input, look up this record, calculate this result, send this email. Backend code is written in languages like Python, Node.js (JavaScript on the server), Java, Go, Ruby, PHP, and many others. The choice of language depends on the team, the requirements, and the ecosystem.

The database — where data is stored persistently. A database is not just a file on disk — it is a system specifically designed for storing, retrieving, and querying large amounts of structured data efficiently, with guarantees about consistency and durability. There are two broad categories:

Relational databases (PostgreSQL, MySQL, SQLite) store data in tables with rows and columns, related to each other through defined relationships. They use SQL (Structured Query Language) to query data. They are the right choice when data has a clear structure and relationships matter — a user has many orders, an order has many items, an item belongs to a category.

Non-relational databases (MongoDB, Redis, DynamoDB) store data in formats other than tables — documents, key-value pairs, graphs. They are more flexible in structure and often better suited for certain workloads: session storage, caching, data with highly variable shapes.

The API — the interface through which the backend exposes its capabilities to the frontend. The frontend doesn’t have direct access to the database. It communicates with the backend through an API (Application Programming Interface) — a defined set of endpoints that accept requests and return responses. More on this in the next section.

What a backend developer actually does

A backend developer designs and builds the server-side systems that power an application. This means: designing database schemas (how data is structured and related), writing API endpoints (how the frontend requests and receives data), implementing business logic (the rules the application enforces), handling authentication and authorization (who can log in and what they can access), optimizing for performance at scale (making sure the system works for thousands of simultaneous users, not just one), and ensuring data integrity and security (that the data stays correct and protected).

How Frontend and Backend Connect

This is the part that makes the whole system click. Frontend and backend are separate but they are not independent. They are in constant conversation, and understanding that conversation is one of the most important things any developer can learn.

HTTP: the language of the web

The frontend and backend communicate over HTTP (HyperText Transfer Protocol). HTTP is a request-response protocol: the client (the browser, running the frontend) sends a request to the server (running the backend), and the server sends a response back.

Every time you open a web page, your browser sends an HTTP request. The server responds with the HTML, CSS, and JavaScript files. Your browser renders them. This is the initial page load.

After the initial load, the frontend continues communicating with the backend through API calls — additional HTTP requests that fetch or send data without reloading the page. These are the requests that power the dynamic parts of an application: searching for products, submitting a form, loading more comments, updating a profile picture.

An HTTP request has several parts:

The method — what kind of request this is. The main ones:

  • GET — retrieve data (loading a ticket list, fetching a user profile)
  • POST — send new data (creating an account, submitting a form)
  • PUT / PATCH — update existing data (editing a profile, changing a status)
  • DELETE — remove data (deleting a post)

The URL — where the request is going. https://api.example.com/tickets/123 — this tells the server what resource is being requested.

Headers — metadata about the request. The most important is Authorization — the token that tells the server who is making the request.

The body — the data being sent (for POST and PUT requests). Usually JSON.

An HTTP response has:

The status code — a number that tells the frontend what happened:

  • 200 — success
  • 201 — created (resource was created)
  • 400 — bad request (the frontend sent something invalid)
  • 401 — unauthorised (not logged in)
  • 403 — forbidden (logged in but not allowed to do this)
  • 404 — not found (the resource doesn’t exist)
  • 500 — server error (something went wrong on the backend)

The body — the data being returned. Usually JSON.

// A frontend sends this request:
GET https://api.example.com/tickets/123
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

// The backend responds with:
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": "123",
  "subject": "Login not working",
  "status": "open",
  "priority": "high",
  "createdAt": "2025-04-01T10:30:00Z"
}

This exchange — request and response — is the fundamental unit of frontend-backend communication. Everything more complex is built on this foundation.

APIs: the contract between frontend and backend

An API is the defined set of requests the backend will accept and responses it will return. It is a contract: the frontend knows what to send and what to expect back. The backend knows what requests it will receive and what it must return.

The most common API style on the web is REST (Representational State Transfer). A REST API organizes its endpoints around resources — the nouns of the application:

GET    /tickets         → returns a list of tickets
POST   /tickets         → creates a new ticket
GET    /tickets/123     → returns ticket 123
PATCH  /tickets/123     → updates ticket 123
DELETE /tickets/123     → deletes ticket 123

GET    /tickets/123/comments       → returns comments on ticket 123
POST   /tickets/123/comments       → adds a comment to ticket 123

The URL tells you what resource you’re working with. The HTTP method tells you what you’re doing to it. The request body provides the data. The response body returns the result.

Another API style gaining wide adoption is GraphQL. Instead of multiple endpoints for different resources, GraphQL has a single endpoint and lets the client specify exactly what data it needs:

# A GraphQL query — the frontend asks for exactly what it needs
query GetTicket {
  ticket(id: "123") {
    id
    subject
    status
    priority
    comments {
      id
      text
      author {
        name
      }
    }
  }
}

REST and GraphQL solve the same problem — exposing backend data to the frontend — with different tradeoffs. REST is simpler to understand and widely supported. GraphQL is more flexible for complex data needs and reduces over-fetching (getting more data than you need) and under-fetching (needing to make multiple requests to get all the data you need).

Authentication: how the backend knows who you are

When a user logs in, the frontend sends their credentials to the backend. The backend verifies them against the database. If correct, it generates a token — a long, cryptographically signed string — and sends it back to the frontend.

The frontend stores this token (in memory, localStorage, or a cookie) and includes it in every subsequent request. The backend reads the token, verifies it is genuine and not expired, and knows who is making the request.

// Login
POST /auth/login
{ "email": "user@example.com", "password": "..." }

// Response
{ "token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxMjMifQ..." }

// Every subsequent request
GET /tickets
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

The most common token format is JWT (JSON Web Token). A JWT contains encoded information — the user’s ID, their role, when the token expires — and a cryptographic signature that proves the backend issued it. The backend can verify a JWT without a database lookup, which makes authentication fast.

This is the handshake that every authenticated application performs. Understanding it — not just at the “it works” level but at the “why it works this way” level — changes how you think about security on both sides of the application.

The database: where everything persists

Data that needs to survive beyond a single session lives in a database. When a user creates an account, the backend stores the account in a database. When they log out and back in on a different device, the backend retrieves it. The database is the memory of the application.

A simple relational database for a support ticket application might have tables like this:

users
------
id          (unique identifier)
email       (string, unique)
password    (hashed string — never stored in plain text)
name        (string)
role        (admin | agent | customer)
created_at  (timestamp)

tickets
-------
id          (unique identifier)
subject     (string)
status      (open | in_progress | resolved | closed)
priority    (low | medium | high | critical)
user_id     (references users.id — who created the ticket)
assigned_to (references users.id — which agent owns it)
created_at  (timestamp)
updated_at  (timestamp)

comments
--------
id          (unique identifier)
ticket_id   (references tickets.id)
user_id     (references users.id)
text        (string)
created_at  (timestamp)

When the backend receives a request for a ticket, it queries the database:

SELECT
  tickets.*,
  users.name AS author_name,
  agents.name AS agent_name
FROM tickets
JOIN users ON tickets.user_id = users.id
LEFT JOIN users AS agents ON tickets.assigned_to = agents.id
WHERE tickets.id = '123'

The backend takes the result, formats it as JSON, and returns it to the frontend. The frontend never touches the database directly. It only sees the API response.

This separation is not just architecture — it is security. Giving the frontend direct database access would mean giving every user who opens the application direct access to the database. The backend is the gatekeeper.

How the Whole System Fits Together

Let me trace a single user action through the entire system, because seeing it end to end is what makes the model concrete.

A user opens a support ticket application and creates a new ticket. Here is what happens:

1. The user types a subject and description and clicks “Submit.”

The frontend validates the input — checks that the subject is not empty, that the description meets the minimum length requirement. This is client-side validation: fast, immediate feedback to the user. It does not replace server validation — it supplements it.

2. The frontend sends an HTTP request.

POST https://api.example.com/tickets
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
Content-Type: application/json

{
  "subject": "Cannot export data",
  "description": "When I click Export, nothing happens.",
  "priority": "high"
}

3. The backend receives the request.

It reads the Authorization header. It verifies the JWT — confirms it is genuine, has not expired, and identifies the user making the request. If the token is invalid, it responds with 401 immediately without touching the database.

4. The backend validates the input again.

Server-side validation is not optional even though the frontend already validated. The frontend is running on the user’s device — a malicious user can bypass it entirely by sending requests directly to the API. The backend never trusts input from the frontend without validating it.

5. The backend creates the ticket in the database.

INSERT INTO tickets (id, subject, description, priority, status, user_id, created_at)
VALUES ('generated-uuid', 'Cannot export data', 'When I click...', 'high', 'open', '123', NOW())

6. The backend sends the email notification.

A support agent needs to know a new ticket was created. The backend puts a job into a queue — a separate system for background tasks — and returns immediately without waiting for the email to send. The queue processes the email asynchronously.

7. The backend responds to the frontend.

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "generated-uuid",
  "subject": "Cannot export data",
  "status": "open",
  "priority": "high",
  "createdAt": "2025-05-10T14:22:00Z"
}

8. The frontend handles the response.

Status 201 — success. The frontend adds the new ticket to the list in the UI, shows a success message, and navigates to the ticket detail view. The user sees their ticket immediately.

9. If something goes wrong at any point.

The backend returns an appropriate status code. 400 if the input was invalid. 500 if the database insert failed. The frontend reads the status code and the error message in the response body, and shows the user something meaningful — not a blank screen, not a cryptic error code.

Eight steps. Frontend, network, backend, database, background jobs, back to frontend. Every user action in a dynamic web application traces a path like this. Once you see the path clearly, every decision on either side becomes easier to reason about.

Why Understanding Both Sides Makes You Better

Here is the honest argument for why every developer — regardless of specialization — should understand both sides well enough to reason across the boundary.

Frontend developers who understand the backend

Build more efficient applications. When you understand that every API call has a cost — network latency, server processing time, database query time — you make different decisions about when to call APIs, how to structure requests, and how to cache responses. You stop making unnecessary requests. You start thinking about the data you actually need rather than fetching everything and filtering on the client.

Catch problems earlier. A frontend developer who understands authentication can look at a security requirement and say “this validation needs to happen on the backend, not the frontend” before the code is written, not after a security review finds it. A developer who understands database queries can look at an API response and recognize that a different data shape would be more efficient to query — and have that conversation with the backend team before the API is built.

Communicate more precisely. The conversations between frontend and backend teams are about contracts — what data will the API return, in what shape, under what conditions. A frontend developer who understands what goes into producing that data can contribute meaningfully to API design rather than passively consuming whatever the backend team decides.

Debug more effectively. When something is wrong in the browser, the problem might be in the frontend, in the API response, in the backend logic, or in the database query. A developer who can only reason about the frontend layer is stuck at the boundary. A developer who understands both layers can trace the problem to its source.

Backend developers who understand the frontend

Build better APIs. An API designed without understanding how it will be consumed by a frontend is often shaped by what is convenient to produce rather than what is convenient to use. Backend developers who understand how a React component fetches and renders data build APIs with responses shaped for that use case — with the data the component needs, in the structure the component can use most efficiently, without excess fields the frontend will ignore.

Make better performance decisions. The backend developer who understands that a user on a slow mobile connection is waiting for the response to this API call will make different choices about response size, query complexity, and caching strategy than one who only thinks about server-side efficiency.

Understand the security surface. The most dangerous assumption in security is “the frontend will handle that.” It won’t — at least, not reliably, and not for malicious actors. Backend developers who understand how frontend JavaScript works understand why every input must be validated on the server, why authentication cannot be handled solely by client-side routing, and why rate limiting matters even on endpoints that seem safe.

How to Learn This — In the Right Order

The most common mistake is choosing a specialization before understanding the whole, or diving into frameworks before understanding the foundational technologies. Both mistakes create gaps that take years to fill.

Start with HTML — really learn it

HTML is not a stepping stone. It is the foundational document format of the web, and understanding it properly changes everything downstream. Learn semantic HTML — not just div and span but main, nav, article, section, header, footer, button, form, label, input. Understand why those elements exist and what they communicate to browsers, screen readers, and search engines. Build several complete page layouts using only HTML before touching CSS.

The investment in HTML pays returns for the rest of your career. Poor HTML is the source of a disproportionate amount of accessibility failures, SEO problems, and CSS layout headaches in production applications.

Learn CSS — the full model, not just properties

After HTML, CSS. But not CSS as a list of properties to memorize. CSS as a model: how the cascade works, how inheritance works, how specificity works, what the box model is, how layout systems (flexbox, grid) actually function. Build responsive layouts from scratch. Build a dark mode system with custom properties. Build a component that adapts to different contexts without JavaScript.

Understanding CSS at the model level is the difference between a developer who fights the browser and one who works with it.

Learn JavaScript — the language before the frameworks

JavaScript is next, and the same principle applies: learn the language before the frameworks. Variables, functions, arrays, objects, loops, conditionals. Then the important deeper concepts: how the event loop works, what asynchronous code is, how promises and async/await function, what closures are, how the DOM works and how JavaScript interacts with it.

Build interactive web pages with vanilla JavaScript. A form with validation. A to-do list that saves to localStorage. A weather widget that fetches from a public API. These exercises teach you what the frameworks are abstracting before you encounter the abstractions.

Learn the fundamentals of how the web works

While learning JavaScript, learn HTTP in parallel. Understand what a request is and what a response is. Learn the main HTTP methods and status codes. Make some API calls from your JavaScript code — fetch data from a public API and display it. This is the moment the frontend-backend connection becomes concrete.

Learn what JSON is (JavaScript Object Notation — the format that frontend and backend use to exchange data). Learn how to parse it and how to create it.

Build a complete small project

Before going further, build a complete small application that has both a frontend and a backend — even a simple one. A personal blog. A contact form that actually sends an email. A to-do list that saves to a real database rather than localStorage.

For the backend, Node.js with Express is the most accessible entry point for a frontend developer because it uses JavaScript — the same language you already know. You will need to learn some new concepts: routing, middleware, connecting to a database. But the language is familiar, which reduces the cognitive load of learning a new environment.

This project will be imperfect. It will have security gaps and architectural choices you will later recognise as wrong. That is fine. The goal is not to build it well — it is to understand the whole system from one end to the other by building it.

Then choose a specialization and go deep

After the full-system project, you will have a much clearer sense of which side interests you more. That preference is real and worth following — not because you can ignore the other side, but because depth in one area and breadth across both is a more useful combination than shallow knowledge everywhere.

If frontend calls to you: go deep into React or Angular, learn state management, learn performance optimization, learn accessibility, learn CSS architecture. Build complex, production-quality interfaces.

If backend calls to you: go deep into databases and SQL, learn about authentication and security, learn about API design, learn about background jobs and caching and scaling. Build robust, secure, performant server-side systems.

In either case: keep learning about the other side. Read about it. Talk to developers who specialize in it. Every project that crosses the boundary is an opportunity to understand something more deeply.

Learn to use the tools that help you move faster

Once the fundamentals are solid, learn the tools that make the work faster and more reliable:

Version control with Git. This is not optional. Git is how code is tracked, shared, and collaborated on. Learn it early and learn it properly — not just git add and git commit but branching, merging, resolving conflicts, and reading the history.

The command line. Most development tools are used via a terminal. You do not need to be a command line expert, but you need to be comfortable enough that it does not slow you down.

A package manager (npm, pip, composer). Modern development relies on libraries built by others. Package managers install and manage those libraries.

Browser developer tools. The browser’s built-in inspector, network tab, console, and performance tools are some of the most powerful debugging instruments a frontend developer has. Learn them deeply.

An API testing tool (Postman, Bruno, or curl). Being able to send HTTP requests directly to a backend — without going through a frontend — is invaluable for understanding and debugging API behaviour.

Conclusion

Frontend and backend are not two separate professions with nothing to say to each other. They are two sides of one system, and the quality of what lives between them — the API design, the security model, the data shape, the error handling — determines a significant portion of the quality of the application as a whole.

Starting out, you do not need to be expert in both. You need to understand the whole well enough to know where your work fits and how it connects. That understanding is available to anyone willing to build a complete end-to-end system, however simple, and trace how a request travels from a click in the browser through the network to the server, into the database, and back again.

Once you have that understanding, everything else — the frameworks, the libraries, the tools, the architectural patterns — has a place to fit. It stops being a collection of things to memorize and becomes a set of solutions to problems you now understand.

Start simple. Build the whole thing. Then go deep on the part that calls to you.

The developers who only ever go deep — who know one side well and treat the other as someone else’s concern — are capable and valuable. But the ones who understand the system produce work that is qualitatively better. Not because they know more, but because they see more of what they are building.

That vision is available from the beginning, if someone explains the shape of the whole before the parts.

Resources

For understanding the web:

  • MDN Web Docs — the most authoritative reference for HTML, CSS, and JavaScript, with excellent learning guides
  • The Odin Project — a free, comprehensive curriculum covering the full stack from the beginning
  • CS50’s Web Programming — Harvard’s free web development course, rigorous and complete

For understanding HTTP and APIs:

For frontend:

For backend (starting with Node.js for JavaScript developers):

For understanding the whole:

  • How Does the Internet Work — clear explanation of the infrastructure underneath everything
  • Web.dev — Google’s developer resource, covers performance, accessibility, and modern web capabilities