On Frontend vs Backend
In the web community, there's a common distinction between Frontend and Backend developers.
Typically, Frontend developers use HTML, CSS, and JS/TS to write code that runs in the browser, while Backend developers use languages like Python, Ruby, Java, C#, JS/TS, etc., to write code that runs on the server.
I believe this is a misconception. The distinction between Frontend and Backend developers isn't about the languages or environments they use; those are merely implementation details of the application architecture.
A Frontend developer focuses on the user interface of the application. They are responsible for the user experience, handling user inputs, and displaying the results.
A Backend developer, on the other hand, works on the business logic of the application. They handle data processing, storage, retrieval, and manipulation.
Case 1: macOS App using Swift
Let's illustrate this with an example outside the web platform. Suppose we're building a desktop application for macOS that runs entirely locally on the user's machine, with no server involved.
We'll use Swift to write the application, SwiftUI for the UI, and SwiftData for the persistence layer. The business logic will be written in plain Swift code.
The architecture is straightforward: SwiftUI views call functions from the business logic layer written in Swift, and those functions interact with SwiftData to store and retrieve data.
Does this application have a Frontend and Backend? Some might say no, because there's no server, but I say yes, because there's a clear separation between the UI code and the business logic code.
Here, the Frontend developer handles the UI layer written in SwiftUI, while the Backend developer is responsible for the business logic layer written in Swift and the data layer managed by SwiftData.
While a single developer could handle all layers (commonly called a Full Stack developer), in a team with a Frontend and Backend separation, responsibilities can be defined based on the same criteria outlined above.
- Frontend developers work on the UI layer.
- Backend developers work on the business logic layer.
Case 2: Web App using TypeScript
Now, let's say we need to migrate this application to the web so it's accessible from any device with a browser. We'll use HTML, CSS, and TypeScript to write the application, and IndexedDB for the data layer.
This is still a pure client-side application with no server involved, running entirely in the user's browser.
Does this application also have a Frontend and Backend? Commonly, the answer is no, because HTML, CSS, and JS/TS are considered Frontend languages. However, the same criteria still apply.
Here, the Frontend developer handles the UI layer written in HTML, CSS, and TypeScript, while the Backend developer is responsible for the business logic layer also written in TypeScript, and the data layer managed by IndexedDB.
In this scenario, the Frontend developer uses HTML and CSS to define the UI appearance and TypeScript to handle user inputs, call functions from the business logic layer, and display results.
The Backend developer uses TypeScript to write the business logic functions that the Frontend developer calls, and uses IndexedDB to store and retrieve data.
Case 3: CLI App using Rust
Let's take a different approach. We now want to build a CLI that runs on Linux, we'll connect via SSH to another computer to run commands and interact with our application.
We could use any programming language, like Python, Ruby, Java, C#, JS/TS, etc., but let's use Rust for this example.
Rust will be used to write the business logic of the application, and interact with STDIN and STDOUT to read user inputs and display results on the terminal.
Does this application have a Frontend and Backend? Many might say no, because there's no graphical UI. However, there is a UI: the terminal, where the user types commands and reads outputs, making it a text-based UI.
The Frontend developer uses Rust to read from STDIN and write to STDOUT, while the Backend developer handles the business logic layer written in Rust, and the persistence layer, which could be a file or a database.
As with previous examples, a single developer could handle all layers, but in a team with Frontend and Backend separation, responsibilities are defined based on the same criteria.
Case 4: Centralized Server for Auth and Storage
Suppose we want to build a centralized server to handle authentication and storage for our applications. Users of our macOS, web, and CLI apps will authenticate and store data in a central location, accessible from any device or platform.
We can use any language, but let's choose PHP with Laravel. And instead of duplicating the business logic across platforms, we can have a single source of truth in PHP.
Our macOS, web, and CLI apps will then become clients of this Laravel server, sending requests to authenticate users, interact with the business logic, and store and retrieve data.
How we expose the business logic to clients is up to us. We could use REST, GraphQL, RPC, etc., and the protocol (commonly HTTP) is an implementation detail. We could also use WebSocket, etc.
Let's say we use HTTP and a mix of REST and RPC to expose the business logic to clients.
Frontend developers of the client applications will now use HTTP to send requests to the server and update the UI with the responses.
Is the Laravel application solely a Backend? Generally, yes, because it focuses on business logic, but we could also say it has a Frontend, as it exposes an API for clients to interact with.
The API is the Frontend of the Laravel application. We could have a Frontend developer specialized in building APIs, with a Backend developer exposing functions or methods for the API developer to call.
In a traditional MVC architecture like Laravel or Ruby on Rails, the Model is the Backend, while the View and Controller are Frontend. Why the Controller? Because it's where the Frontend developer can call the Models to interact with the business logic, render the View, and react to user actions via POST requests.
Case 5: Server-side Rendered Web App
Let's return to our web application, but now we want to add server-side rendering. We'll use Remix to write the application with React. In our route loaders and actions, we'll connect to the Laravel API for authentication, data retrieval, business logic, etc.
Here, the architecture becomes more complex, with code running both in the browser and on the server.
Following the common definition of Backend, the code in Remix's loaders and actions should be Backend code because it runs on the server. However, no Backend developer would consider it as such. That code serves the UI by fetching data and reacting to UI-triggered actions.
Thus, we have an application with a client-server model still under Frontend responsibility, while Backend developers focus on business logic and the data layer in the Laravel API.
Appendix: Backend for Frontend
Let's say our API strictly follows REST principles, serving multiple clients, and cannot be tailored to a specific client.
A common issue is that Frontend developers need to make multiple API requests to gather all the data needed to render the UI, leading to performance problems, over-fetching, under-fetching, etc.
To solve this, we could introduce a Backend for Frontend (BFF), or more accurately, a Server for Frontend.
This is a separate server tailored to the needs of a specific client, allowing Frontend developers to make a single request to the BFF for all the data needed to render the UI.
In our SSR-ed web app example, Remix loaders and actions could be considered a BFF, as they aggregate data from various Laravel API endpoints and send it to the client in a single, UI-optimized response.
For our macOS application, we could build another BFF. While the BFF can be in any language, it's better to use the same language as the client to avoid context switching. Therefore, we could use Swift to build this server that consumes the API and serves the macOS client.
In BFF, the "Backend" is analogous to the "Server" in the client-server model, not the "Business Logic" as we defined earlier. This is why I think "Server for Frontend" is a more accurate term, although BFF is a well-known term in the industry.
Conclusion
The separation between Frontend and Backend developers should be based solely on their code responsibilities, not the languages or environments they work in.
A Frontend developer should not be limited to HTML, CSS, and JS/TS. They can work on any code that interacts with the user, whether it's a graphical UI, a text-based UI, or an API.
Similarly, a Backend developer should not be restricted to server-side code. They can work on any code that processes data, whether on the server, client, or both.