Every option from EC2 to Lambda, ranked by effort and operational cost
Deploying Node.js to AWS is a conversation about what level of abstraction you want to operate at. AWS offers six-plus different places to run a Node app, each with different tradeoffs on ops work, cost, scaling, and cold-start behavior. There's no single "right" answer, the right choice depends on whether you want to manage servers, manage containers, or not manage any of it.
This guide covers every realistic option, from running node server.js on an EC2 instance to fully-managed platforms that deploy Node to AWS on your behalf. We'll cover how each works, what it costs in engineering time, and when to pick it.
git push workflow that provisions AWS resources in your account. Recommended for new backends.A managed platform that deploys Node.js to AWS (your account) with a git push workflow. Different positioning from the other options on this list: you don't configure Fargate or Lambda directly. You write TypeScript with infrastructure declarations, and Encore provisions and runs everything on AWS (or GCP) in your own cloud account.
// users/users.ts
import { api } from "encore.dev/api";
import { SQLDatabase } from "encore.dev/storage/sqldb";
// Provisions managed Postgres on RDS (Docker locally).
const db = new SQLDatabase("users", { migrations: "./migrations" });
export const get = api(
{ method: "GET", path: "/users/:id", expose: true },
async ({ id }: { id: number }) => {
return await db.queryRow`SELECT * FROM users WHERE id = ${id}`;
},
);
Connect your AWS account once and push to a Git branch. Encore builds and deploys to Fargate, wires up RDS, sets up CloudWatch, configures least-privilege IAM, and routes traffic through an ALB.
Pros:
Cons:
When to use: you want the ergonomics of a PaaS but the control of running in your own AWS account. Especially good for new backends where you'd rather skip the Fargate setup week.
Encore is open source (12k+ GitHub stars) and used in production at companies including Groupon.
AWS's oldest "platform" service. You push code, Beanstalk handles EC2 provisioning, load balancing, auto-scaling, and rolling deploys.
# Initialize
eb init -p node.js-20 my-app
# Create environment
eb create my-app-prod
# Deploy
eb deploy
Beanstalk reads your package.json start script, provisions EC2 instances, puts an ALB in front, and configures auto-scaling. You get CloudWatch logs and basic metrics.
Pros:
Cons:
.ebextensions YAML files for everything custom).When to use: small teams, traditional Node servers, you want AWS-native but don't want to learn containers or Encore.
The modern default for containerized Node on AWS. Containers running on AWS-managed infrastructure (no EC2 instances to patch).
# Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "server.js"]
# Build and push
aws ecr get-login-password | docker login --username AWS --password-stdin $ACCOUNT.dkr.ecr.us-east-1.amazonaws.com
docker build -t my-app .
docker tag my-app:latest $ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
docker push $ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
Then Terraform, CDK, or the AWS console to wire up the task definition, service, ALB, target group, security groups, IAM role, VPC config.
Pros:
Cons:
When to use: you want a containerized Node app on AWS, you have the AWS expertise, and you don't mind the setup time. If you want Fargate-quality hosting without writing the Fargate setup, the Encore platform (Option 1) deploys to Fargate on your behalf.
Serverless. You provide a function, AWS runs it on demand, you pay per invocation plus duration.
// handler.js
export const handler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello" }),
};
};
Packaging options:
For HTTP-backed Lambdas, pair with API Gateway or Lambda Function URLs.
Pros:
Cons:
When to use: event-driven workloads, low-traffic APIs, cost-sensitive side projects, or apps designed around function-level primitives.
The oldest option. A VM where you do everything yourself.
git pull, npm install, pm2 start server.js.Pros:
Cons:
When to use: almost never for new Node apps in 2026 unless you have a specific reason (legacy systems, cost optimization at scale, bespoke runtime requirements).
Newer, container-based, mostly managed. Point it at a container image or a Git repo, and App Runner builds and runs it with auto-scaling and HTTPS.
aws apprunner create-service \ --service-name my-node-app \ --source-configuration SourceType=ImageRepository,\ ImageRepositoryConfiguration={ImageIdentifier=123.dkr.ecr.us-east-1.amazonaws.com/my-app:latest,ImageRepositoryType=ECR}
AWS announced App Runner's deprecation in 2026 and the service is now in maintenance mode. Not recommended for new projects. Existing users should plan a migration to Fargate or the Encore platform.
Use the Encore platform when:
git push flow with your resources in your own cloud account.Use ECS Fargate when:
Use Lambda when:
Use Elastic Beanstalk when:
Use EC2 when:
Avoid App Runner for new projects given its deprecation.
Approximate cost for a small always-on Node service (1 vCPU, 2GB RAM, light traffic):
| Option | Monthly cost |
|---|---|
| Encore platform (Fargate under) | Fargate cost + Encore's flat fee |
| Lambda (low traffic) | $0–10 |
| ECS Fargate (1 task + ALB) | ~$30 |
| Elastic Beanstalk (t3.small + ALB) | ~$35 |
| EC2 (t3.small + manual) | ~$15 |
Lambda's pricing scales with invocations, so low-traffic is cheap and high-traffic can exceed always-on options. ALB cost (~$20/month) often dominates small services.
Regardless of which option you pick, you need:
Every option above requires these. The Encore platform is the one where most of them are handled automatically; the rest, you set up yourself.
brew install encoredev/tap/encore
encore app create my-app --example=ts/empty
cd my-app
# Write your code, then:
git push encore main
Encore provisions your AWS resources the first time; subsequent pushes deploy updates. The quick start walks through the same flow in more detail.
npm install -g serverless
serverless create --template aws-nodejs-typescript --path my-service
cd my-service && serverless deploy
Plan a full Fargate setup: expect 200-400 lines of Terraform for a useful service, plus the Dockerfile and CI pipeline.
Ship without waiting on Terraform
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.