Skip to content

Introduction to Web Apps

Web applications, or web apps, have evolved significantly over the years, offering a range of approaches to building interactive and dynamic user experiences. Whether it’s a traditional server-side application, a modern client-side single-page application (SPA), or a hybrid model combining elements of both, every web app is fundamentally built on the same core technologies: HTML, CSS, and JavaScript (and maybe WebAssembly).

Core Components of a Web Application

Regardless of the architecture or framework you choose, at its heart, every web application consists of the following three essential parts:

  1. HTML (HyperText Markup Language): The structure of the web application, defining the content and layout.
  2. CSS (Cascading Style Sheets): The presentation layer, controlling the appearance and styling of the content.
  3. JavaScript (JS): The behavior layer, enabling interactivity, dynamic content, and client-side logic. WebAssembly (Wasm) extends JavaScript by allowing high-performance code execution within the browser.

These components work together to create the complete user experience, no matter how the application is built or deployed.

   +-------------------+
   |       HTML        |  --> Structure (Content & Layout)
   +-------------------+
            |
   +-------------------+
   |       CSS         |  --> Presentation (Styling & Appearance)
   +-------------------+
            |
   +-------------------+
   |    JavaScript     |  --> Behavior (Interactivity & Logic)
   |   (WebAssembly)   |  --> (High-Performance Code Execution)
   +-------------------+

In this structure:

  • HTML forms the skeleton of the web app, defining the elements on the page such as headings, paragraphs, images, links, forms, etc.
  • CSS beautifies and styles these elements, defining things like colors, fonts, layouts, and responsive design rules.
  • JavaScript (and WebAssembly) adds life to the page, making it interactive, responsive to user actions, and capable of performing complex computations directly in the browser.

Exploring Different Types of Web Apps

While HTML, CSS, and JavaScript (or WebAssembly) are the building blocks of every web app, the way they are used and delivered to the client can vary widely. In this introduction, we’ll explore different types of web apps:

  • Pure Server-Side Applications: Where most of the processing happens on the server, and the server sends fully-rendered HTML pages to the client.
  • Pure Client-Side Single-Page Applications (SPAs): Where the server provides a single HTML page, and JavaScript handles rendering, data fetching, and interaction entirely in the browser.
  • Hybrid Applications: Combining server-side rendering for initial content with client-side enhancements, offering a balance of performance, SEO, and interactivity.
  • Emerging Technologies: Like HTMX, which leverages extended HTML attributes to create dynamic web apps without relying heavily on JavaScript, and WebAssembly, which enables near-native performance for web applications.

Understanding these different approaches will help you choose the right architecture for your next web project, leveraging the strengths of each to build fast, responsive, and engaging web applications.

Web applications, or web apps, have evolved significantly, offering a range of approaches to building interactive and dynamic user experiences. From traditional server-side applications to cutting-edge client-side frameworks and hybrid models, each approach offers unique benefits depending on the needs of the application. In this introduction, we’ll explore different types of web apps—pure server-side applications, pure client-side single-page applications (SPAs), hybrid applications, and the emerging use of technologies like HTMX—along with the most commonly used technologies in each category.

Pure Server-Side Applications

Pure server-side applications are a classic approach to web development where the server handles all the business logic, data processing, and HTML rendering. The server responds to each client request by generating and delivering fully-rendered HTML pages. This model was the standard in the early days of the web and remains widely used for many applications today.

graph TD
  A[Client Browser] -->|HTTP Request| B[Web Server]
  B -->|Process Request| C[Application Logic]
  C -->|Query| D[Database]
  D -->|Return Data| C
  C -->|Render HTML| B
  B -->|HTTP Response with HTML| A

Server-side application

Key Characteristics:

  • Server-Rendered Pages: HTML is fully rendered on the server and sent to the client’s browser.
  • Simplified Client: The client (browser) primarily displays the server-rendered content with minimal client-side logic.
  • SEO-Friendly: Since the HTML is rendered on the server, it’s easily accessible by search engines, making it inherently SEO-friendly.

Common Technologies:

  • LAMP Stack: Linux, Apache, MySQL, PHP/Perl/Python.
  • Ruby on Rails: A popular framework built with Ruby, emphasizing simplicity and productivity.
  • ASP.NET: A robust server-side framework developed by Microsoft.
  • Java Spring: A comprehensive framework used for building scalable server-side applications in Java.

Use Cases:

  • Content Management Systems (CMS): Like WordPress, where pages are dynamically generated on the server.
  • E-commerce Platforms: Such as Magento, handling complex server-side processing for products and transactions.
  • Corporate Websites: Sites that rely heavily on server-rendered content for SEO and data processing.
Example

Here’s an example of a simple Node.js and Express server-side web application that serves an HTML file with associated CSS. This example is as minimal as it gets, providing a basic structure to get you started.

Step 1: Set Up Your Project

  1. Create a project directory:

    mkdir simple-express-app
    cd simple-express-app
    

  2. Initialize the project:

    npm init -y
    

  3. Install Express:

    npm install express
    

Step 2: Create the Server Code

Create a file named server.js in your project directory:

// server.js
const express = require('express');
const path = require('path');

const app = express();
const PORT = 3000;

// Serve static files (e.g., CSS) from the "public" directory
app.use(express.static(path.join(__dirname, 'public')));

// Serve the HTML file for the root route
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

Step 3: Create the HTML and CSS Files

  1. Create a directory named public inside your project directory. This directory will hold your HTML and CSS files.

    mkdir public
    cd public
    

  2. Create an index.html file inside the public directory:

    <!-- public/index.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Simple Express App</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <h1>Welcome to My Simple Express App</h1>
        <p>This is a very basic example of serving HTML and CSS using Node.js and Express.</p>
    </body>
    </html>
    
  3. Create a styles.css file inside the public directory:

    /* public/styles.css */
    body {
        font-family: Arial, sans-serif;
        background-color: #f0f0f0;
        margin: 0;
        padding: 20px;
    }
    
    h1 {
        color: #333;
    }
    
    p {
        font-size: 1.2em;
        color: #666;
    }
    

Step 4: Run the Server

  1. Start the server:

    cd \simple-express-app
    node server.js
    

  2. Open your browser and navigate to http://localhost:3000.

You should see the HTML page styled with the CSS you provided. The page should display a heading and a paragraph, with the styles defined in the styles.css file.

Pure Client-Side (SPA) Applications

Single-page applications (SPAs) represent a modern approach to web development where the client (browser) takes on a significant portion of the application’s logic. In an SPA, the server typically delivers a single HTML page, and all subsequent interactions are handled through JavaScript, which dynamically updates the content without reloading the entire page. SPAs communicate with the server using RESTful APIs or GraphQL.

graph TD
    A[Client Browser] -->|Initial Request| B[Web Server]
    B -->|Serve Single HTML Page + JS| A
    A -->|Fetch Data| C[REST API Server]
    C -->|Return JSON Data| A
    A -->|Render & Update UI| A[Client Browser]

Key Characteristics:

  • Dynamic Client-Side Rendering: JavaScript frameworks or libraries handle the rendering and updating of the user interface.
  • Asynchronous Data Loading: Data is fetched from the server as needed, resulting in a smoother and more responsive user experience.
  • Rich User Interfaces: SPAs offer highly interactive and responsive interfaces, similar to desktop applications.

Common Technologies:

  • React: A popular JavaScript library for building SPAs with a component-based architecture.
  • Angular: A full-featured framework developed by Google, offering tools like two-way data binding and dependency injection.
  • Vue.js: A progressive JavaScript framework known for its flexibility and ease of integration.
  • Svelte: A newer framework that compiles components into highly optimized JavaScript at build time, resulting in fast, lightweight SPAs.

Use Cases:

  • Social Media Platforms: Like Facebook or Twitter, where real-time updates are crucial.
  • Webmail Clients: Such as Gmail, where the interface is continually updated without full page reloads.
  • Dashboards: Used in analytics or monitoring systems, where data is frequently updated without disrupting the user experience.
Example of a Simple SPA

In modern applications, you’d want to keep the user on the same page to enhance the experience and maintain the state. Try the following example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Area Calculation</title>
    <style>
      .input span {
        display: inline-block;
        width: 100px;
        margin: 10px;
      }
      button {
        margin: 10px;
      }
    </style>
  </head>
  <body>
    <h1>Area Calculation</h1>
    <div>[<a href="#" id="menuSquare">Square</a>] [<a href="#" id="menuTriangle">Triangle</a>]</div>

    <section id="square">
      <h2>Square</h2>
      <div class="input">
        <div><span>Length</span><input id="length" type="number" /></div>
        <div><span>Width</span><input id="width" type="number" /></div>
        <div><span>Area</span><input id="areas" type="number" readonly /></div>
        <div><button id="calculateSquare">Calculate</button></div>
      </div>
    </section>
    <section id="triangle">
      <h2>Triangle</h2>
      <div class="input">
        <div><span>Height</span><input id="height" type="number" /></div>
        <div><span>Base</span><input id="base" type="number" /></div>
        <div><span>Area</span><input id="areat" type="number" readonly /></div>
        <div><button id="calculateTriangle">Calculate</button></div>
      </div>
    </section>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
      // When the page loads, show the square section
      $("#triangle").hide();
      $("input").val(0);

      $("#menuSquare").click(() => {
        $("#triangle").hide();
        $("#square").show();
        $("input").val(0);
      });
      $("#menuTriangle").click(() => {
        $("#triangle").show();
        $("#square").hide();
        $("input").val(0);
      });

      $("#calculateSquare").click(() => {
        let l = parseFloat($("#length").val());
        let w = parseFloat($("#width").val());
        let a = l * w;
        $("#areas").val(a);
      });
      $("#calculateTriangle").click(() => {
        let h = parseFloat($("#height").val());
        let b = parseFloat($("#base").val());
        let a = h * b * 0.5;
        $("#areat").val(a);
      });
    </script>
  </body>
</html>

However, it quickly becomes too complex to manage the state, external links (route), security, DOM manipulation, etc., on your own. That’s why there are many SPA frameworks available.

Example of AJAX

This example uses both jQuery and underscore.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Kommuner i DK</title>
  </head>
  <body>
    <h1>Kommuner i Danmark</h1>

    <button>Hent info om alle kommuner</button>

    <ul id="lst" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
      $("button").click(() => {
        const ul = $("#lst");
        ul.empty();
        let data = $.get("https://dawa.aws.dk/kommuner/", (data) => {
          // skab et array af objekter med navn og kode (skærer resten fra)
          let navne = _.map(data, (o) => ({
            navn: o.navn,
            kode: o.kode,
          }));
          navne.forEach((v) => {
            let li = $("<li/>").html(`${v.kode}: ${v.navn}`);
            ul.append(li);
          });
        });
      });
    </script>
  </body>
</html>

Hybrid Applications

Hybrid web applications combine elements of both server-side and client-side approaches, leveraging the strengths of each. These applications typically involve server-side rendering (SSR) for the initial page load, with client-side JavaScript taking over to manage dynamic content and user interactions. This approach offers the SEO benefits of server-side rendering and the interactivity of SPAs.

graph TD
    A[Client Browser] -->|Initial Request| B[Web Server]
    B -->|Server-Side Rendering| C[Application Logic]
    C -->|Query| D[Database]
    D -->|Return Data| C
    C -->|Render HTML with Initial Data| B
    B -->|Serve Rendered HTML Page| A
    A -->|Client-Side JavaScript Fetches Additional Data| E[REST API Server]
    E -->|Return JSON Data| A
    A -->|Update UI Dynamically| A

Key Characteristics:

  • Initial Server Rendering: Ensures fast load times and SEO benefits by delivering fully-rendered HTML initially.
  • Client-Side Interactivity: JavaScript enhances the user experience by handling dynamic updates and interactions without full page reloads.
  • Progressive Enhancement: The application is designed to work well even if JavaScript is disabled, making it more robust and accessible.

Common Technologies:

  • Next.js: A React framework that supports server-side rendering, static site generation, and client-side rendering.
  • Nuxt.js: A Vue.js framework offering similar features to Next.js, with built-in SSR capabilities.
  • Django with Django REST Framework: Often used for server-side rendering, with client-side enhancements provided by React or Vue.js.
  • ASP.NET Core with Blazor: Microsoft’s Blazor allows for C# development on both the client and server sides, enabling flexible rendering strategies.

Use Cases:

  • E-commerce Sites: Where initial content is server-rendered for SEO, but client-side JavaScript manages dynamic features like cart updates.
  • Content-Rich Blogs: Server-rendered content ensures SEO, while interactive elements like comments are handled on the client side.
  • Corporate Portals: Combining server-rendered content for fast load times with rich client-side interactivity for personalized user experiences.
Example

Here is an example of a simple htmx application that demonstrates how to use htmx to create a dynamic web application without writing JavaScript. Goto https://github.com/devcronberg/htmx-node-app and clone the repository (or download the zip file by clicking the Green button).

Then install and start the server using:

npm install
node server.js

HTMX and Other Emerging Technologies

HTMX

HTMX is an emerging technology that brings a fresh approach to building dynamic web applications by allowing HTML to be more interactive without relying heavily on JavaScript. HTMX enables developers to use extended HTML attributes to make asynchronous requests, update parts of the page, and handle user interactions—all without writing JavaScript. This approach offers a middle ground between traditional server-rendered applications and full-fledged SPAs.

Key Characteristics:

  • HTML-Centric: HTMX allows developers to manage dynamic behaviors directly in HTML using attributes, reducing the need for JavaScript.
  • Server-Driven Interactivity: Interactions like form submissions and page updates are handled by the server, but only the relevant parts of the page are updated.
  • Progressive Enhancement: HTMX integrates well with existing HTML, making it easy to incrementally enhance web pages with dynamic features.

Use Cases:

  • Form Handling: Creating dynamic forms that update or validate without a full page reload.
  • Partial Page Updates: Efficiently updating specific sections of a page in response to user actions without reloading the entire page.
  • Enhancing Legacy Applications: Adding modern interactivity to existing server-rendered applications without a full rewrite.

Other Emerging Technologies

WebAssembly (Wasm)

WebAssembly continues to revolutionize web development by allowing high-performance code written in languages like C, C++, and Rust to run in the browser, bringing near-native performance to web applications.

WebGPU

WebGPU, the successor to WebGL, provides more direct access to modern GPU features, enabling advanced graphics rendering and compute-intensive tasks directly in the browser.

Web Components

Web Components enable developers to create reusable, encapsulated custom elements that can be used across different projects, promoting code reuse and maintainability in large-scale applications.

The Future of Web Development

As web technologies continue to evolve, developers have more tools than ever to build powerful, responsive, and interactive web applications. Whether choosing a traditional server-side approach, a modern SPA, a hybrid model, or exploring emerging technologies like HTMX, WebAssembly, and WebGPU, the possibilities are vast and growing. The future of web development is poised to deliver even more integrated, fast, and versatile online experiences, transforming the way we interact with the digital world.