Different dimensions of Remix deploy targets
Deployment Targets in Remix
When creating a new Remix app with
Currently, the following deployment targets are officially supported:
- Remix App Server
- Express Server
- Architect (AWS Lambda)
- Cloudflare Pages
- Cloudflare Workers
Picking the right deployment target for your application is important. There are a lot of considerations and requirements that play into this decision. So let's break it down into different dimensions.
The different dimensions
We can identify the following dimensions:
- Hosting provider / cloud platform
- Hosting service
- Hosting environment
- Application environment
Please note that the terms I am using here come from my own intuition. I am not aware of any better widely-used terms for these dimensions.
Hosting provider / cloud platform
Most Remix deployment targets are hosting provider or cloud platform specific. The adapter is meant to make Remix run on a specific platform. Other targets are generic and can be deployed to different platforms.
The generic deployment targets are:
- Remix App Server
- Express Server
For instance, the Remix App Server and Express Server applications can be executed wherever Node.js can run.
Considering the associated or other potential hosting providers for an deployment target is probably the most important aspect of choosing a deployment target.
Most hosting providers and cloud platforms offer several different services that use different computing models and technologies. Some hosting providers may offer several services that can be used to host a Remix application.
For example, both Cloudflare Pages and Cloudflare Workers can be used to host a Remix application. Also, Vercel and Netlify now offer edge environments which can be used with Remix (even though there isn't an official Remix deployment target out yet for these environments).
Services differ in their functionality, pricing, and utilized technologies.
- Workers runtime (workerd)
Each Remix deployment target is meant to run on one of these runtimes:
- Remix App Server: Node.js
- Express Server: Node.js
- Architect (AWS Lambda): Node.js
- Fly.io: Node.js
- Netlify: Node.js
- Vercel: Node.js
- Cloudflare Pages: Workers runtime (workerd)
- Cloudflare Workers: Workers runtime (workerd)
- Deno: Deno
The underlying runtime has implications on what kind of packages and functionality can be executed in your Remix app.
Different services use different hosting environments. These hosting environments best fit into these three categories:
- Long-running server
Long-running server environments are environments in which your web server is run continuously. Serverless environments utilize the serverless computing model to execute your application like a function on every incoming request. Edge environments distribute your application to the edge of the network and also follow a serverless computing model.
The line between these hosting environments is blurry. Some long-running server environments might shutdown after a timeout in which no request came in similar to how serverless functions terminate (e.g. the now sunset Heroku free-tier). Both serverless and long-running server environments can utilize geographic distribution to offer edge-like geographic proximity to users.
I define edge as an environment that is running on a CDN or the users' devices. Edge computing traditionally is defined as computing that happens on the user's device (e.g. car, laptop, drone, or smart home device). I would argue that regionally distributed containers should be considered edge-like or regionally distributed, but not edge environments. But that just emphasizes how blurry the lines between these different environments are.
Each Remix deployment target maps to one hosting environment:
- Remix App Server: Long-running server
- Express Server: Long-running server
- Architect (AWS Lambda): Serverless
- Fly.io: Long-running server
- Netlify: Serverless
- Vercel: Serverless
- Cloudflare Pages: Edge
- Cloudflare Workers: Edge
- Deno: Edge
Please note that the generic deployment targets are in theory flexible and could be used in other hosting environments. For instance, the Deno deployment target when deployed to Deno deploy runs in an edge environment. However, it could potentially be used in a long-running server environment as well.
The hosting environment has serious implications for your application's behavior. Filesystem access, pricing, scalability, distribution, maximum application size, response times, and supported capabilities (e.g. keep-alive, WebSocket) heavily rely on both your hosting provider and service and their hosting environment.
Your application's process runs in some sort of environment. On localhost or an OG home server, your application may run on a physical machine and its operation system. Hosting providers and cloud platforms utilize virtual application environments to run your application (for security and orchestration reasons).
We can identify the following virtual application environments:
- Virtual machines (VM)
- V8 Isolates
Please note that the container landscape is particularly fragmented. There are several different container technologies and standards. Not everything that uses a Docker image is a Docker container (1). For example, AWS Lambda uses Firecracker which creates so called microVMs that run on top of KVM (Kernel-based Virtual Machine). These microVMs are specifically optimized for faster startup times and other serverless use cases.
So how do these application environments differ? I use the following intuition for these environments:
- Virtual machines mostly include an operation system on their own. VMs boot up in minutes and are measured in Gigabytes.
- microVMs virtualize the kernel to some extend but are more lightweight than VMs. KVMs boot up in milliseconds (may reach a few seconds) and are measured in Megabytes.
- (Docker) Containers run on top of a host operating system. Usually, containers are measured in Megabytes and boot up in a few seconds.
Different hosting environments utilize different application environment to orchestrate and run your application. Currently they usually map as follows:
- Long-running server: Generic (VM, MicroVM, Container)
- Serverless: Container or MicroVM
- Edge: V8 Isolate
Each Remix deployment target may map to several or one application environment:
- Remix App Server: Generic
- Express Server: Generic
- Architect (AWS Lambda): MicroVM
- Fly.io: MicroVM (1)
- Netlify: MicroVM
- Vercel: MicroVM
- Cloudflare Pages: V8 Isolate
- Cloudflare Workers: V8 Isolate
- Deno: V8 Isolate
The underlying application environment has additional implications for your application especially regarding cold start times and application size.
It is amazing that Remix provides such flexibility. However, that flexibility also means that you as a developer have the responsibility to pick the right deployment target for your own use case and your application requirements.
There are a lot of factors that play into the decision of picking a deployment target. The outlined dimensions play an important role in understanding the different considerations that affect the decision.
I hope this overview helps you to make a better choice for your own app!
Cheers and happy coding!