Go & Vanilla JS: Fullstack Without Frameworks

Maximiliano Firtman
Independent Consultant
10 hours, 11 minutes CC
Go & Vanilla JS: Fullstack Without Frameworks

Course Description

Code a high-performance fullstack app from scratch! Skip the framework and create a modern Vanilla JavaScript app with web components, dynamic client-side routing, View Transitions, and data filtering and sorting. Build a rock-solid backend JSON API with Go, complete with authentication, logging, and a Postgres database layer. Learn to build robust applications, with higher performance and fewer dependencies, in Vanilla JS and Go!

This course and others like it are available as part of our Frontend Masters video subscription.

Preview
Close

Course Details

Published: May 27, 2025

Learning Paths

Learn Straight from the Experts Who Shape the Modern Web

Your Path to Senior Developer and Beyond
  • 200+ In-depth courses
  • 18 Learning Paths
  • Industry Leading Experts
  • Live Interactive Workshops

Table of Contents

Introduction

Section Duration: 19 minutes
  • Introduction
    Maximiliano introduces the course by discussing core topics and prerequisites, including a basic knowledge of JavaScript, HTML, CSS, Go, and SQL. He also provides the workshop materials, including the project code and dataset.
  • Course Project & Approach
    Maximiliano introduces the course project, which will include features such as filtering, searching, marking movies as favorites, and user account functionality. The project will also include user registration, authentication, and the ability to mark movies as favorites and add them to a watchlist.

Building a Backend with Go

Section Duration: 1 hour, 41 minutes
  • Go Project Setup
    Maximiliano demonstrates how to create a new Go module using the "go mod init" command and explains the basic structure of a Go project. Additionally, Maximiliano discusses the process of adding external dependencies to the project using the go.mod file and the "go get" command.
  • Simple Server Setup
    Maximiliano demonstrates how to set up the server using the HTTP package and the ListenAndServe function. He also shows how to handle different routes using the FileServer function, which serves files from a specified directory.
  • Project Architecture
    Maximiliano explains the architecture of the app, including the user interface, frontend, transport, backend, and database. He also introduces the Air tool for automatically restarting the server when files are changed, and mentions the use of PG for PostgreSQL.
  • Adding a Logger
    Maximiliano discusses two options for creating a logger: using a cloud-based provider or creating a custom logging system that writes to a file. He demonstrates how to create a logger package in Go and explains the design pattern of returning two values (object and error) in functions that may trigger an error. Maximiliano then shows how to initialize the logger in the main.go file and use it to log messages and errors.
  • Creating Go Models
    Maximiliano walks through building the project models, which are the structures for each entity in the project, such as movies, genres, actors, and users. He also explains how pointers indicate optional fields in the models.
  • Creating JSON Route Handler
    Maximiliano demonstrates how to create a handler for a RESTful API in Go. He creates a method within the movie handler structure to handle the API request for retrieving the top movies. He also demonstrates how to set the content type header to JSON and encode the movie data into JSON format.
  • JSON Route Handler Q&A
    Maximiliano explains that when using an "if" statement with multiple conditions, only the last condition is considered. He suggests using the HTTP package to handle errors and send appropriate HTTP error codes. He also discusses the need to register the handler with the server and explains how to create a new instance of a structure in Go.
  • Install AIR
    Maximiliano walks through installing a tool called "Air" that provides live reload for Go apps. He demonstrates how to install the tool using the command line and explains that it automatically rebuilds and runs the server whenever changes are made to the Go files.
  • Creating Another Route Handler
    Maximiliano walks through creating a `writeJSONResponse` function to handle the common code for setting the content type, encoding data into JSON, and handling errors. He demonstrates how to define this function and use it in the `getTopMovies` and `getRandomMovies` handlers.

Postgres Database Layer

Section Duration: 1 hour, 19 minutes
  • Create Database Model Interface
    Maximiliano discusses the database table structure, including entities and relationships, and emphasizes the need for normalization in a SQL-based database. He provides a step-by-step guide on setting up a PostgreSQL server using aiven.io and also explains how to populate the database using an import script or by importing a SQL dump file.
  • Abstract Interface
    Maximiliano explains that creating an interface allows for future-proofing the backend project, as it allows for easy database changes. He demonstrates the creation of an interface called "movie storage" with functions such as getTopMovies, getRandomMovies, getMovieByID, and searchMoviesByName.
  • Setup Postgres Connection
    Maximiliano demonstrates how to store the connection string, retrieve the connection string, and open the database. He also demonstrates how to handle the naming mismatch between Go properties and the database field names by adding metadata to the models.
  • Movie Repository
    Maximiliano demonstrates how to import the Postgres database driver and explains that it is necessary to connect to the database. He demonstrates creating the movie repository, including how it creates a new instance of the repository, implements the interface methods, and handles SQL queries.
  • Movie Handler
    Maximiliano discusses how handlers handle HTTP requests and responses, while repositories handle communication with the database. He also demonstrates how to pass the repository and logger to the handler using an initializer function.
  • Debugging
    Maximiliano demonstrates how to debug and fix errors in a Go backend application. He identifies an internal error in the handler and traces it back to a problem in the movie repository. He also implements a handler for random movies using similar logic.
  • Adding More Database Queries
    Maximiliano adds more database queries, such as getting a movie by ID, searching movies by name with optional filters, getting all genres, and fetching movie relations like actors and keywords. He also tests the logger functionality by logging an error message.
  • Adding More Handlers
    Maximiliano finishes the handlers, which include functions such as getting movies by ID, getting all genres, and searching for movies. Once the handlers are completed, the URLs need to be registered so that the server can respond to the corresponding requests.

Client-Side Application with Vanilla JS

Section Duration: 2 hours, 12 minutes
  • HTML Structure
    Maximiliano walks through how to set up the HTML structure for the course web app, including linking CSS and a web manifest file. He also builds the header section of the app, including a logo, navigation bar, and search input.
  • Creating App.js
    Maximiliano demonstrates creating a global app object with a search function that prevents the browser from reloading the form. He also explains how to connect the JavaScript file to the HTML file using ECMAScript modules and the defer attribute for improved performance.
  • Client-Side API Service
    Maximiliano explains how to create an API service in JavaScript using the fetch API. He demonstrates how to make API calls to a backend server and retrieve data using async/await and the fetch.json method. He also discusses the use of try/catch blocks to handle errors and suggests encapsulating the API service to prevent exposing it in the console or to unauthorized users.
  • Web Components
    Maximiliano demonstrates how to create a Web Component by defining a template using the HTML template element and explains that the template is not rendered by default and needs to be used with JavaScript.
  • Homepage Component
    Maximiliano demonstrates creating the homepage component. He extends the class from "HTMLElement", uses the "connectedCallback" method to execute code, retrieves the template from the DOM, and appends it to the component.
  • Dynamically Render Component
    Maximiliano explains how to dynamically render content in the web component. He demonstrates how to create a render function and call it within the connectedCallback method. He also uses the API module to fetch and display the top movies and random movies.
  • Movie Item Component
    Maximiliano demonstrates how to create the movieItem component, pass the movie as a property, and render the movie details using HTML and template strings. He also mentions the need to implement pagination or infinite scrolling for large datasets and discusses the importance of server-side rendering for SEO purposes.
  • Course Project Review
    Maximiliano provides an overview of the course project so far, highlighting components like app.js for client-side interaction, API.js for backend requests, main.go for server setup, handlers for HTTP requests, and models and repositories for database interactions.
  • Loading State Component
    Maximiliano discusses creating an animated loading component using CSS animations instead of traditional loading spinners or progress bars to indicate loading times in web applications. He also demonstrates how to create an "animated loading" component with CSS animations for a wave effect.
  • Movie Details Component
    Maximiliano explains the process of creating a web component for a movie details page, including registering the component, loading CSS files, using Shadow DOM for styling, fetching movie data from an API, error handling for non-existent movie IDs, and populating HTML content dynamically.
  • Embedding Elements in Movie Details
  • YouTube Embed Component
    Maximiliano demonstrates how to create a web component for embedding YouTube videos dynamically by listening for attribute changes using JavaScript. He also explains the process of defining the web component, handling attribute changes with attributeChangedCallback, and dynamically updating the embedded video based on the provided URL.

Dynamic Rendering

Section Duration: 1 hour, 15 minutes
  • SPA Routing
    Maximiliano discusses creating a router using design patterns to manage client-side URLs effectively, allowing for dynamic content loading without server-side changes. He also demonstrates how to define routes and components within the router.
  • Adding a Router
    Maximiliano walks through how to add a router in JavaScript as a singleton class and discusses the use of the history API to handle navigation and state changes. Maximiliano also touches on event handling, URL manipulation, and the distinction between global variables in the browser context.
  • Creating a Generic Router
    Maximiliano shows how to build a generic router for quickly adding routes to any project. He covers injecting components, handling missing routes, using regex for dynamic paths, and extracting parameters.
  • Routing Q&A
    Maximiliano answers questions about passing data into web components and how routing works using URL changes and regex. He also shows how to make the router available globally in the app.
  • Dynamic Router & Links
    Maximiliano makes adjustments in the code to ensure proper rendering of pages, including handling 404 errors and dynamic URL routing based on parameters. He demonstrates enhancing link functionality within the router by preventing default actions on link clicks and manually updating URLs without page refreshes.
  • Handling Nested Routes
    Maximiliano discusses the issue of receiving 404 errors when refreshing or bookmarking specific URLs in a web application due to client-side routing not being recognized by the server. He demonstrates how to handle this by creating a catch-all client routes handler in the server-side code to deliver the index HTML for all client-side routes.
  • View Transitions
    Maximiliano introduces the View Transitions API as a simple way to create smooth transitions between pages without complex CSS animations. By setting specific CSS styles for old and new pages and utilizing the `document.startViewTransition` function, a subtle fade effect can be achieved during page transitions.
  • Error Messages Modal
    Maximiliano discusses implementing error messages in a web application by creating a dialog element in HTML to display error messages to users. He demonstrates adding functionality in app.js to show error messages and navigate users back to the home page if needed.

Search, Filter, & Sort

Section Duration: 33 minutes
  • Searching & Displaying Results
    Maximiliano discusses implementing search functionality in a web application, focusing on constructing query strings for searches and updating URLs accordingly. He also demonstrates parsing URL parameters using URLSearchParams and rendering search results based on query parameters.
  • Fixing the MovieItem Component
    Maximiliano demonstrates debugging a bug related to navigation by identifying the issue in the MovieItem component and addressing it by preventing the default behavior. He also touches on advanced techniques using event listeners and the DOM to enhance user experience and handle event propagation effectively.
  • Filtering Movies by Genre
    Maximiliano demonstrates how to dynamically load genres from an API and populate a select element in JavaScript. Additionally, he shows how to implement functions for changing search filters and ordering.

Authentication

Section Duration: 1 hour, 44 minutes
  • Authentication Strategies
    Maximiliano discusses authentication, focusing on user registration, login, and password security. This course will involve creating frontend forms for registration and login, implementing hashing for passwords to enhance security, and discussing the importance of not storing passwords in plain text.
  • Adding Authentication Storage
    Maximiliano explains the process of adding a dependency for hashing passwords using bcrypt. He also outlines the steps involved in creating an account management system, including setting up model repositories, handlers for web services like registration and authentication, and corresponding components on the client side.
  • User Account Repository
    Maximiliano discusses the authentication process in a system and the practice of returning generic error messages for unsuccessful login attempts. He also highlights the significance of safeguarding user data and mentions strategies like limiting login attempts to enhance security in large projects.
  • User Account Handlers
    Maximiliano explains the importance of handlers, including how they interact with HTTP requests, communicate with repositories, and manage data flow. He also demonstrates the process of creating account handlers and integrating them into the application alongside repositories.
  • Testing Authentication with Postman
    Maximiliano demonstrates using Postman to send a POST request to an API endpoint, showing how to include data in JSON format and interpret the server response. He also touches on manual method verification in handlers when working with frameworks in Go for different HTTP methods on the same URL.
  • Registration Form
    Maximiliano explains the process of setting up registration and login functionality on the backend and discusses the need to create corresponding URLs on the client-side for account registration and authentication. He also touches on the significance of associating labels with inputs for accessibility purposes.
  • Registration Page Custom Element
    Maximiliano demonstrates creating a web component for a registration page by extending from HTML element and defining the component. He also addresses issues like setting input types explicitly for CSS styling and discusses how browsers handle unclosed tags.
  • Login Form & Custom Element
    Maximiliano demonstrates creating a login form and discusses changing attributes like autocomplete to enhance user experience and avoid issues like password manager suggestions on login screens. He also shows how to integrate the login form into a route for seamless navigation between registration and login pages.
  • Calling the Authentication APIs
    Maximiliano explains the process of creating new API endpoints for registration and login functionalities. He emphasizes the need to send data using a new function called "send" to work with login and registration. Maximiliano also covers client-side validation for user input data before sending it to the server, highlighting the importance of server-side validation as well.
  • Client-Side Form Validation
    Maximiliano demonstrates implementing login functionality, with proper validation and error messages. Additionally, he tests registration, confirming the flow is working correctly by creating new user accounts.
  • JSON Web Tokens
    Maximiliano discusses the challenges of user authentication and introduces solutions such as server-side sessions and JSON Web Tokens (JWT) as secure methods to handle authentication without compromising sensitive data.
  • Generating a JWT with Go
    Maximiliano explains the process of creating and using JSON Web Tokens (JWT) in Go by utilizing the golang-jwt library. He also demonstrates how to generate a token with user data, encrypt it using a secret key, and validate it.
  • Storing JWTs on the Client
    Maximiliano explains the importance of storing authentication keys client-side using local storage or IndexedDB for actions requiring authentication. He demonstrates creating a service to store data, like JWT tokens, and using a proxy pattern in JavaScript to manage events like saving token changes to local storage.

Features for Authenticated Users

Section Duration: 59 minutes

Wrapping Up

Section Duration: 5 minutes
  • Wrapping Up
    Maximiliano wraps up the course by discussing future feature ideas like account deletion, OTP email confirmation, better password resets, error handling, similar movies, actor pages, and using Go for email.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now