Containers vs. Virtual Machines: What the Hell is a Hypervisor?

Hello and welcome. As a Front End developer, virtualization of operating systems is one of those things that can cause me to alternatively shit my pants or throw my laptop out the window at any given time. During my recent AWS Cloud Practitioner studying, I managed to (sort of) get my head around the difference between traditonal Virtual Machines and newfangled containers. Read on, but be forewarned that I still have no idea what the hell I am talking about..
Operating Systems
Fundamentally, virtual machines emulate an entire operating system, all the way down to emulating hard drives and network interfaces. Virtual machines can allow users to actually "virtualize" multiple different "guest" operating systems on a single machine. You can run one virtualized Windows instance alongside a Linux instance on the same physical computer.
Containers differ here. There is no concept of a "guest" operating system in a container. Rather than including their own guest operating system, any number of containers running on a computer share a single underlying operating system.
Because containers don't need to package up an entire virtualized operating system, they are generally much smaller in size than virtual machines. This makes a containerized application smaller, lighter and more portable.
Hypervisor
An important concept in traditional virtual machines is the hypervisor. This is the layer of software that sits between the "host" operating system - the actual operating system running on the computer and interacting with the physical hardware - and the virtualized "guest" operating systems that run individual virtual machines. The hypervisor takes care of delegating and reserving the requested resources (RAM, CPU) of the physical machine and interacting with the underlying scheduler to ensure that the work each virtual machine requests is actually done. Because containers don't virtualize a guest operating system, they don't use a hypervisor. This is a key difference.
Containers do use an application to manage underlying resources, but it's thinner. This is called a container engine, and Docker is an example of one.
App Code
Both containers and virtual machines contain code to make their applications run. The difference between the two is that containers only contain this code (alongside whatever code is needed for other services needed to run software). For example, a containerized Node application can simply require a base Node Docker container image and run its required Node services within it. A virtual machine would need an entirely virtualized operating system to run the Node runtime itself, alongside the aforementioned services. This generally explains the size difference between containers and virtual machines.
Orchestration
In the world of microservices, containers tend to win out. Although both virtual machines and containers can be "orchestrated" to talk to each other, the smaller size and better flexibility of containers tends to make them a better option. Because the entire container packages up everything it needs to run, developers don't need to be concerned about implementing specific details of where the application will eventually run. This makes containers more portable.