04/23/26

How to Deploy Node.js to AWS in 2026

Every option from EC2 to Lambda, ranked by effort and operational cost

8 Min Read

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.

TL;DR

  • Encore Cloud: git push workflow that provisions AWS resources in your account. Recommended for new backends.
  • Elastic Beanstalk: easiest official AWS option for traditional servers. Showing its age.
  • ECS Fargate: the modern default for containerized Node apps on AWS.
  • Lambda: serverless, pay-per-request, cold-start tradeoffs.
  • EC2: full control, you manage everything.
  • App Runner: deprecated by AWS in 2026. Avoid for new projects.

Option 1: Encore Cloud

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 Cloud provisions and runs everything on AWS (or GCP) in your own cloud account.

How it works

// 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, deploys to Fargate, wires up RDS, sets up CloudWatch, configures least-privilege IAM, and routes traffic through an ALB.

Tradeoffs

Pros:

  • No Terraform / CDK / CloudFormation / task definitions to write.
  • Resources live in your AWS account, not Encore's.
  • Built-in tracing, structured logs, and metrics.
  • Preview environments per PR.
  • Production defaults (private VPC, encryption, least-privilege IAM) applied automatically.

Cons:

  • Encore's conventions fit Node and Go backends; for non-Node runtimes or bespoke workloads this isn't the right abstraction.
  • AWS and GCP only. Other clouds work via Encore's Terraform provider as an escape hatch.

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 (11k+ GitHub stars) and used in production at companies including Groupon.

Deploy with Encore

Want to jump straight to a running app? Clone this starter and deploy it to your own cloud.

Deploy

Option 2: Elastic Beanstalk

AWS's oldest "platform" service. You push code, Beanstalk handles EC2 provisioning, load balancing, auto-scaling, and rolling deploys.

How it works

# 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.

Tradeoffs

Pros:

  • Genuinely git-push-style deploys on pure AWS.
  • No Docker required.
  • AWS-native billing and IAM.

Cons:

  • AWS has quietly deprioritized it, fewer new features, older runtime versions.
  • Config is sprawling (.ebextensions YAML files for everything custom).
  • Rolling updates can be slow.

When to use: small teams, traditional Node servers, you want AWS-native but don't want to learn containers or Encore.

Option 3: ECS Fargate

The modern default for containerized Node on AWS. Containers running on AWS-managed infrastructure (no EC2 instances to patch).

How it works

  1. Build a Docker image.
  2. Push to ECR (AWS's container registry).
  3. Create a task definition (CPU, memory, env vars, IAM role).
  4. Create an ECS service (desired count, load balancer, VPC).
  5. Deploy updates by pushing a new image and updating the task definition.
# 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.

Tradeoffs

Pros:

  • Integrates with ALB, API Gateway, VPC, IAM cleanly.
  • Scales well, production-ready out of the box.
  • Full control over container runtime and networking.

Cons:

  • A lot of wiring. First deploy is measured in days of setup.
  • The task definition / service / target group / ALB dance is its own learning curve.
  • Cost includes the always-on task plus the ALB.

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, Encore Cloud (Option 1) deploys to Fargate on your behalf.

Option 4: AWS Lambda

Serverless. You provide a function, AWS runs it on demand, you pay per invocation plus duration.

How it works

// handler.js export const handler = async (event) => { return { statusCode: 200, body: JSON.stringify({ message: "Hello" }), }; };

Packaging options:

  • ZIP deploy for small functions.
  • Container image for larger bundles (up to 10GB).
  • Tools: Serverless Framework, SAM, SST, Architect, or raw CloudFormation.

For HTTP-backed Lambdas, pair with API Gateway or Lambda Function URLs.

Tradeoffs

Pros:

  • True pay-per-request pricing.
  • Scales to zero and from zero instantly for many use cases.
  • No servers to manage.

Cons:

  • Cold starts (50ms-500ms for Node, longer for heavier bundles).
  • 15-minute max execution time.
  • Every handler is its own deployable artifact (chatty when you have many).
  • Operational complexity shifts to the glue (API Gateway, IAM, VPC, state between invocations).

When to use: event-driven workloads, low-traffic APIs, cost-sensitive side projects, or apps designed around function-level primitives.

Option 5: EC2

The oldest option. A VM where you do everything yourself.

How it works

  1. Launch an EC2 instance (Ubuntu, Amazon Linux).
  2. SSH in, install Node.
  3. git pull, npm install, pm2 start server.js.
  4. Configure nginx or ALB for TLS.
  5. Set up CloudWatch agent, auto-scaling group, AMI management.

Tradeoffs

Pros:

  • Maximum control.
  • Cheapest compute if fully utilized.
  • Familiar if you've operated Linux servers.

Cons:

  • You own OS patches, runtime upgrades, TLS renewal, monitoring setup, log aggregation.
  • No auto-scaling without setting up ASGs manually.
  • Deploy story is whatever you build.

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).

Option 6: AWS App Runner (deprecated)

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 Encore Cloud.

How to Choose

Use Encore Cloud when:

  • You're building a new Node backend on AWS or GCP.
  • You want a PaaS-style git push flow with your resources in your own cloud account.
  • You'd rather not write Terraform / CDK / task definitions.

Use ECS Fargate when:

  • You want full control over a containerized always-on service.
  • You have AWS expertise and time to set up the task/service/ALB plumbing.
  • Encore's conventions don't fit your workload.

Use Lambda when:

  • Your workload is event-driven or spiky.
  • You care about scale-to-zero more than predictable performance.
  • Cold starts are acceptable.

Use Elastic Beanstalk when:

  • You want an AWS-native managed option without containers.
  • Your app fits a simple web-server shape.
  • You're okay with the aging tooling.

Use EC2 when:

  • You have legacy apps or specialized runtime needs.
  • You're optimizing cost at scale and can invest in ops.

Avoid App Runner for new projects given its deprecation.

Cost Comparison (Rough)

Approximate cost for a small always-on Node service (1 vCPU, 2GB RAM, light traffic):

OptionMonthly cost
Encore Cloud (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.

Production Considerations

Regardless of which option you pick, you need:

  • HTTPS: ALB with ACM cert, or CloudFront in front.
  • Database: RDS for Postgres/MySQL, DynamoDB for key-value, DocumentDB for Mongo-like.
  • Secrets: AWS Secrets Manager or Parameter Store. Don't put secrets in env vars stored in Terraform.
  • Logs: CloudWatch Logs by default. Stream to Datadog, Grafana, or a centralized log store at scale.
  • Metrics and alerting: CloudWatch Alarms, or a proper APM (Datadog, New Relic, Grafana).
  • Tracing: AWS X-Ray or OpenTelemetry.
  • CI/CD: GitHub Actions, CodePipeline, or similar.
  • Backup / DR: RDS automated snapshots, cross-region replication for critical data.

Every option above requires these. Encore Cloud is the one where most of them are handled automatically; the rest, you set up yourself.

Getting Started

Encore Cloud

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.

Lambda via Serverless Framework

npm install -g serverless serverless create --template aws-nodejs-typescript --path my-service cd my-service && serverless deploy

Fargate via Terraform (manual)

Plan a full Fargate setup: expect 200-400 lines of Terraform for a useful service, plus the Dockerfile and CI pipeline.

Deploy with Encore

Want to jump straight to a running app? Clone this starter and deploy it to your own cloud.

Deploy

Ready to escape the maze of complexity?

Encore Cloud is the development platform for building robust type-safe distributed systems with declarative infrastructure.