
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
cdk-nextjs
Advanced tools
The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the Semantic Versioning model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
Deploy Next.js apps on AWS with the AWS CDK.
NextjsGlobalFunctions does not currently support ISR - waiting for Official Next.js Deployment Adapters API.NextjsGlobalFunctions, NextjsGlobalContainers, NextjsRegionalContainers, NextjsRegionalFunctions.overrides.NextjsRegionalContainers)."standalone". Learn more here about Standalone Output.npm install cdk-nextjscdk deployimport { App, Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import { NextjsGlobalFunctions } from "cdk-nextjs";
import { join } from "node:path";
class NextjsStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new NextjsGlobalFunctions(this, "Nextjs", {
healthCheckPath: "/api/health",
buildContext: join(import.meta.dirname, ".."),
});
}
}
const app = new App();
new NextjsStack(app, "nextjs");
See examples/ for more usage examples.
NextjsGlobalFunctionsArchitecture includes AWS Lambda Functions to respond to dynamic requests and CloudFront Distribution to globally serve requests and distribute static assets. Use this construct when you have unpredictable traffic, can afford occasional latency (i.e. cold starts - typically 1% of production traffic), and/or want the most granular pricing model. (code)

NextjsGlobalContainersArchitecture includes ECS Fargate containers to respond to dynamic requests and CloudFront Distribution to globally serve requests and distribute static assets. Use this option when you have predictable traffic, need the lowest latency, and/or can afford a less granular pricing model. (code)

NextjsRegionalContainersArchitecture includes ECS Fargate containers to respond to dynamic requests and Application Load Balancer to regionally serve requests. Use this options when you cannot use Amazon CloudFront (i.e. AWS GovCloud). (code)

NextjsRegionalFunctionsArchitecture includes AWS Lambda Functions to respond to dynamic requests and API Gateway REST API to regionally serve requests and distribute static assets. Use this options when you cannot use Amazon CloudFront (i.e. AWS GovCloud). (code)

The simplest path to deploy Next.js is on Vercel - the Platform-as-a-Service company behind Next.js. However, deploying to Vercel can be expensive and some developers want all of their workloads running directly on AWS. Developers can deploy Next.js on AWS through AWS Amplify Hosting, but Amplify does not support all Next.js features and manages AWS resources for you so they cannot be customized. If Amplify meets your requirements we recommend you use it, but if you want to use all Next.js features or want more visibility into the AWS resources then this construct is for you.
NextjsGlobalFunctions or NextjsGlobalContainers (which use CloudFront), the number of top level files/directories cannot exceed 25, the max number of behaviors a CloudFront Distribution supports. We recommend you put all of your public assets into one top level directory (i.e. public/static) so you don't reach this limit. See CloudFront Quotas for more information.NextjsGlobalFunctions, when revalidating data in Next.js (i.e. revalidatePath), the CloudFront Cache will still hold stale data. You'll need to use AWS SDK JS V3 CreateInvalidationCommand to manually invalidate the path in CloudFront. See more here.NextjsGlobalFunctions, setting an Authorization header won't work by default because of Lambda Function URL with IAM Auth is already using the Authorization header. You can use the AWS_LWA_AUTHORIZATION_SOURCE environment variable of AWS Lambda Web Adapter to set an alternative Authorization header in the client which will then be set to the Authorization header when it reaches your app.NextjsRegionalFunctions doesn't support streaming because API Gateway doesn't support streaming yet.NextjsRegionalFunctions without a custom domain, API Gateway REST APIs require a stage name (default: /prod) to be specified. This causes links to pages and static assets to break because they're not prefixed with the stage name. You can work around this issue by specifying basePath in next.config.js as your stage name. Additionally, you'll need to add middleware logic to rewrite requests to include the stage name because API Gateway does not include the stage name in the path passed to Lambda. See examples/app-playground/middleware.ts.This construct by default implements all AWS security best practices that a CDK construct library reasonably can considering cost and complexity. Below are additional security practices we recommend you implement within your CDK app. Please see them below:
NextjsGlobalFunctions and NextjsGlobalContainers, CloudFront Access Logs. See examples/ for sample implementation.NextjsGlobalContainers and NextjsRegionalContainers, use ALB HTTPS ListenerNextjsGlobalContainers and NextjsRegionalContainers, enable ReadonlyRootFilesystem. This will remove ability to use Static On-Demand feature of Next.js so it's not enabled by default, but is recommended for security.The following basic assumptions were used for a typical medium Next.js app. See docs/usage.xlsx for detailed assumptions and usage per construct type that you can plug into AWS Pricing Calculator.
| Metric | Value |
|---|---|
| Monthly Active Users | 1K |
| Pages Visited Per Month Per User | 100 |
| Avg Request Size | 50KB |
| Static Requests Per Page (js, css, etc) | 15 |
| Static Requests Cache Hit % | 50% |
| Static Assets Size | 10GB |
| Dynamic Requests Per Page (document, optimized images, etc.) | 5 |
| Dynamic Cache Read % | 50% |
| Dynamic Cache Write % | 5% |
| Dynamic Cache Data Size | 10GB |
| Average Dynamic Cache Request Size | 100KB |
More Details:
NAT Gateways enable compute within private subnets to access the internet without directly exposing that compute to the internet. NAT Gateways prevent you from having to manage your own NAT Instances however they cost $0.045/hr/AZ resulting in charge of $64.80/month for 2 AZs (.045 x 24 x 30 x 2). While NAT Gateways are recommended by AWS to ensure maximum reliability and scalability, some customers may desire less expensive alternatives:
| Service | Monthly Usage | Estimated Monthly Cost (USD) |
|---|---|---|
| Lambda | 500K requests, 2 GB memory, 150ms avg duration | $0.00 (Always Free Tier) |
| CloudFront | 2M requests, 100 GB transfer to internet | $0.00 (Always Free Tier) |
| S3 | 10 GB storage, 750K GET requests | $0.53 |
| EFS | 10 GB storage, 25/2.5 GB Read/Write Throughput | $3.90 |
| VPC | NAT Gateway, 2 AZs | $64.80 |
| Total | $69.32 |
| Service | Monthly Usage | Estimated Monthly Cost (USD) |
|---|---|---|
| ECS Fargate | 1 task (1 vCPU, 2 GB) | $28.44 |
| ALB | 1 LB, 1.04GB/hr, 5.79 conn/sec | $22.50 |
| CloudFront | 2M requests, 100 GB transfer to internet | $0.00 (Always Free Tier) |
| S3 | 10 GB storage, 750K GET requests | $0.53 |
| EFS | 10 GB storage, 25/2.5 GB Read/Write Throughput | $3.90 |
| VPC | NAT Gateway, 2 AZs | $64.80 |
| Total | $120.53 |
| Service | Monthly Usage | Estimated Monthly Cost (USD) |
|---|---|---|
| ECS Fargate | 1 task (2 vCPU, 4 GB), always on | $28.44 |
| ALB | 1 LB, 4.17 GB/hr, 23.15 conn/sec | $40.78 |
| EFS | 10 GB storage, 25/2.5 GB Read/Write Throughput | $4.05 |
| VPC | NAT Gateway, 2 AZs | $64.80 |
| Total | $138.07 |
| Service | Monthly Usage | Estimated Monthly Cost (USD) |
|---|---|---|
| Lambda | 500K requests, 2 GB memory, 150ms avg duration | $0.00 (Always Free Tier) |
| API Gateway | 2M requests | $7.00 |
| EFS | 10 GB storage, 25/2.5 GB Read/Write Throughput | $4.05 |
| VPC | NAT Gateway, 2 AZs | $64.80 |
| Total | $75.85 |
Artillery Playwright app playground example load tests results with 1K concurrent users. Reproduce with pnpm test-fargate:lg within examples/load-tests.
browser.page.TTFB.https://abc123.cloudfront.net/isr:
min: ......................................................................... 6.3
max: ......................................................................... 5017.4
mean: ........................................................................ 11.5
median: ...................................................................... 10.3
p95: ......................................................................... 15.6
p99: ......................................................................... 22.9
browser.page.TTFB.https://abc123.cloudfront.net/isr/1:
min: ......................................................................... 3.2
max: ......................................................................... 560.6
mean: ........................................................................ 9.4
median: ...................................................................... 5.4
p95: ......................................................................... 11.1
p99: ......................................................................... 162.4
browser.page.TTFB.https://abc123.cloudfront.net/isr/2:
min: ......................................................................... 3.1
max: ......................................................................... 1511.9
mean: ........................................................................ 9.2
median: ...................................................................... 5.2
p95: ......................................................................... 10.7
p99: ......................................................................... 149.9
browser.page.TTFB.https://abc123.cloudfront.net/isr/3:
min: ......................................................................... 3.4
max: ......................................................................... 131.1
mean: ........................................................................ 7.1
median: ...................................................................... 5.3
p95: ......................................................................... 10.1
p99: ......................................................................... 64.7
browser.page.TTFB.https://abc123.cloudfront.net/ssg:
min: ......................................................................... 6.4
max: ......................................................................... 5015.1
mean: ........................................................................ 11.5
median: ...................................................................... 10.3
p95: ......................................................................... 15.6
p99: ......................................................................... 23.3
browser.page.TTFB.https://abc123.cloudfront.net/ssg/3:
min: ......................................................................... 2.9
max: ......................................................................... 98
mean: ........................................................................ 5.1
median: ...................................................................... 4.6
p95: ......................................................................... 8.2
p99: ......................................................................... 12.8
browser.page.TTFB.https://abc123.cloudfront.net/ssr:
min: ......................................................................... 6.4
max: ......................................................................... 5018.6
mean: ........................................................................ 11.3
median: ...................................................................... 10.3
p95: ......................................................................... 15.6
p99: ......................................................................... 23.3
browser.page.TTFB.https://abc123.cloudfront.net/ssr/2:
min: ......................................................................... 83.4
max: ......................................................................... 150.7
mean: ........................................................................ 119
median: ...................................................................... 111.1
p95: ......................................................................... 147
p99: ......................................................................... 147
browser.page.TTFB.https://abc123.cloudfront.net/streaming:
min: ......................................................................... 6.4
max: ......................................................................... 5015.2
mean: ........................................................................ 11.8
median: ...................................................................... 10.3
p95: ......................................................................... 15.6
p99: ......................................................................... 23.3

TODO
TODO
TODO
Steps to build locally:
git clone https://github.com/cdklabs/cdk-nextjs.gitcd cdk-nextjspnpm i && pnpm compile && pnpm buildThis project uses Projen, so make sure to not edit Projen created files and only edit .projenrc.ts.
Q: How does this compare to cdk-nextjs-standalone?
A: cdk-nextjs-standalone relies on OpenNext. OpenNext injects custom code to interact with private Next.js APIs. While OpenNext is able to make some optimizations that are great for serverless environments, this comes at an increase maintenance cost and increased chances for breaking changes. A goal of cdk-nextjs is to customize Next.js as little as possible to reduce the maintenance burden and decrease chances of breaking changes.
Q: Why not offer API Gateway version of construct?
A: API Gateway does not support streaming.
Q: How does cdk-nextjs support caching in Next.js?
A: Next.js has 3 types of server caching that are persisted to disk: data cache, full route cache, and image optimization cache. By default this cached data is persisted on individual compute instances and is not shared - reducing cache hits. cdk-nextjs uses the custom Next.js cache handler for data and full route cache and symlinking for image optimization cache to modify Next.js to read/write from a mounted file system
Q: Why EFS instead of S3?
A: cdk-nextjs uses Amazon Elastic File System (EFS) to mount a file system to functions or containers as a shared cache. The custom Next.js cache handler could be modified to read/write data to Amazon S3, but there is no way to modify the location of the image optimization cache without modifying Next.js internals. Other factors to compare:
| Factor | EFS | S3 |
|---|---|---|
| Performance | 1-10ms per file operation | 100-200ms per request |
| Cold Start Impact | 50-100ms to mount | No impact |
| Storage Cost | $0.30 / GB-month | $0.023 / GB-month |
| Read Throughput/Request Cost | $0.03 / GB-month | $0.04 / M requests |
| Write Throughput/Request Cost | $0.06 / GB-month | $5.00 / M requests |
Q: How customizable is the cdk-nextjs package for different use cases?
A: The cdk-nextjs package offers deep customization through prop-based overrides. These can be accessed in the construct props, allowing you to override settings like VPC configurations, CloudFront distribution, and ECS/Fargate setup. For example, you can modify nextjsBuildProps to customize the build process or use nextjsDistributionProps to adjust how CloudFront handles caching and routing. This level of control makes it easy to adapt the infrastructure to your application’s specific performance, networking, or deployment needs.
Q: How can I use a custom domain with cdk-nextjs?
A: See low-cost example.
Q: What is difference between NextjsGlobalFunctionsProps.overrides.nextjsDistribution and NextjsGlobalFunctionsProps.overrides.nextjsGlobalFunctions.nextjsDistributionProps
A: NextjsGlobalFunctionsProps.overrides.nextjsDistribution allows you to customize any construct's props within NextjsDistribution and is likely what you want whereas NextjsGlobalFunctionsProps.overrides.nextjsGlobalFunctions.nextjsDistributionProps allows you to customize the props passed into the construct: NextjsDistribution. This principle also applies to other similarly named overrides.
Q: Why use container image for NextjsGlobalFunctions?
A: Read The case for containers on Lambda (with benchmarks).
Q: How can I cdk bootstrap --cloudformation-execution-policies ... my AWS Account with limited permissions for cdk-nextjs to deploy?
A: See docs/cdk-nextjs-cfn-exec-policy.json. Note, this IAM Policy is scoped to all cdk-nextjs constructs so you can remove services if you know the construct you're using doesn't use that service.
This construct was built on the shoulders of giants. Thank you to the contributors of cdk-nextjs-standalone and open-next.
Thank you for helping other developers deploy Next.js apps on AWS
FAQs
Deploy Next.js apps on AWS with CDK
We found that cdk-nextjs demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.