question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: state of Serverless Next.js and next steps

See original GitHub issue

Hi all!

I hope you are having a great weekend. I just wanted to take some time to give some updates on the current state of Serverless Next.js. This is a long post - TL;DR on bottom if you want. Ever since I’ve started using this early this year, and contributing just a few months back, we as a community have accomplished, as of version 1.18 or 1.19 alpha:

  • Stability improvements: for example, we added multiple end-to-end tests that deploy a real Lambda@Edge for both the current-minor and previous-minor Next.js versions, pinned dependencies, enabled security updates (automated dependency updates are a WIP via Renovate), and added a bunch more unit test coverage for the handler code.
  • Build/deploy and configuration improvements: thanks to all the bug reports and suggestions, we’ve merged many improvements to configuring CloudFront inputs and other serverless.yml outputs, decoupling build step from the deploy step, etc.
  • Feature parity: except for the recently released Next.js 10 features, some more involved features (like revalidate on SSG), and a few miscellaneous bugs or quirks, the majority of Next.js 9.x features should be implemented and fairly stable and well-tested.

…and more. Thank you for all your support and contributions, and for helping us test and report bugs with the latest alpha versions!

That being said, we’ve also noticed these two biggest pain points:

  • Lambda@Edge and CloudFront are highly coupled with the core code of routing and rendering the correct pages. As an end user of this package, you may not notice it, but this actually makes it harder to support new platforms, such as Lambda, Cloudflare, GCP, Azure, etc. As a maintainer, it also makes it hard to separate testing the platform integration vs. testing the core code.
  • Infrastructure management has been difficult and sometimes has inconsistent results, as there is no first-class state management like a proper infrastructure-as-code (IaC) tool. The reason for this is that the Serverless Components we use (aws-cloudfront, domain, etc.) weren’t well maintained and interfaced with the AWS SDK directly and do not manage state except for saving the Lambda function name, CloudFront distribution ID, etc (in the .serverless directory).

This brings us to the next set of challenges:

  • Decoupling and modularizing the runtime code itself so it’s not tied Lambda@Edge. This will help us in separating concerns to the respective packages. Fortunately, we have Rollup.js or other bundlers which can largely help with this. I propose the following:
    • Core Next.js code: this is the core routing and rendering logic, all specific to Next.js rendering of SSR, SSG pages and doing non-dynamic, dynamic routing.
    • Optional request/response middleware: any additional runtime code you’d like to run before/after the core serverless code is run. For example, you could use this to do basic authentication, log additional metrics, etc. This doesn’t really belong to the core routing code. We could provide a few essential first-party middleware, the community can contribute additional middleware to the package, another package, or use their own.
    • Bundler: bundles the core Next.js code together with any included middleware, including custom middleware.
    • Platform plugins: these plugins are responsible for building and deploying the code to a specific platform. For example, this can be Lambda@Edge, Lambda, Cloudflare, etc. Its responsibility is to take the bundled core code + middleware and further bundle that with lightweight platform compatibility layers that interface with the core. It can also perform any further optimizations as needed. For example, for Lambda@Edge, this will involve the CloudFront event. As part of this, we may also plan to reduce the Lambda@Edge handlers into a single origin request handler to simplify the architecture and even improve performance by reducing cold start + CloudFront + S3 origin + Lambda complexity.

In essence, everything except for the platform plugins should be platform-agnostic.

  • Properly decoupling build and deploy steps, and making it more configurable: much of this is already done, as you can just build only .serverless_nextjs outputs using this component, and actually deploy using your own IaC tools - although there is no first-party implementation of CDK yet. This brings us to the last point:

  • Proper infrastructure-as-code and state management. We’ve seen that our use of AWS SDK means we need to keep updating deployment code to support new features. There is also no proper state management. Fortunately, there are tools like CDK, Terraform, Pulumi etc. that have already already solved these issues, by storing state remotely (e.g in Terraform, you can store it in Terraform, S3, etc).

    • Explore the use of CDK / CDK for Terraform / Pulumi. We are leaning towards CDK and CDK for Terraform, since I am familiar with Terraform and it also seems to have the most providers and gives more flexibility. Also, a deployment has two phases: provisioning static infrastructure, like CloudFront, Lambda@Edge, and S3, and uploading/deploying new code and assets, so this lends itself well.
  • Serverless Components GA upgrade: with all the above in mind, we are still planning to upgrade to Serverless Components GA as part of this. The plan is for some of the above refactoring to make this much easier.

We hope to incorporate at least some of these into the next major release (v2), I am hoping sometime in Q1 2021. Please share any thoughts or feedback you may have. We could also definitely use some help on some of this (after or in parallel to modularization), especially on supporting new platforms other than Lambda@Edge, since it’s mostly @danielcondemarin and me maintaining this package.

I will update this post as I get more feedback. Thank you for reading!

FYI: @danielcondemarin

TL;DR: for v2 release, we are planning to modularize and decouple the component from Lambda@Edge, make it more platform-agnostic and support more platform deployments, and improve pain points related to infrastructure management. In addition, we will plan to upgrade to Serverless Components GA. We would love feedback or comments to help us improve.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:66
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
dphangcommented, Nov 14, 2020

@chancity sure, that would be great, feel free to ping @danielcondemarin if you’d like to be added to the Slack to discuss. We’d definitely love some help

@JordanLao we do want to support Lambda next, though first as mentioned we want to:

  1. Simplify the handler and decouple the core routing code from any particular platform. Thereafter the build outputs look largely the same.
  2. We’d need to write deployment logic and additional layer to make it compatible with Lambda. I think we plan to support new platforms using CDK/CDK for Terraform since that is more robust than trying to manage infrastructure ourselves using the AWS SDK (as we are now).

(1) involves quite a bit of refactoring, so probably best to be done by a core contributor. If you would like to help with (2), let me know and we can add you to the Slack. Basically for (2) you could actually start on the deployment logic (setting up Lambda, uploading to S3, API Gateway, CloudFront for assets etc.) assuming that the build outputs look something similar to the existing .serverless_nextjs folder (with default-lambda, api-lambda, assets directories, though of course the handler will remove CloudFront specific logic).

As for Fastly, I don’t believe they support JavaScript yet, unless something changed? See: https://www.fastly.com/blog/why-edge-compute-does-not-yet-support-javascript. They also don’t use Node.js nor V8 isolates (like Cloudflare Workers) so it would even trickier, I imagine. I would say that it would be easier to add Cloudflare Workers support - as FAB project has already done so to some extent.

2reactions
dphangcommented, Jun 22, 2021

I will close this for now since I think the future plans are quite clear: Currently work is being done to support Lambda/APIGW and help reduce complexity (trying to remove origin response handler, etc.), and after we can start looking at other platforms.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Serverless Next.js Component - Serverless Framework: Plugins
Any commands to run post-build and pre-deploy. For example, you can run any custom code on the .serverless_nextjs directory e.g you can copy...
Read more >
Deploying Next.js to AWS using Serverless Next.js
Learn how to deploy a Next.js application to AWS Lambda in Serverless Mode using the Serverless Next.js Component.
Read more >
Blog - Next.js 9
js by contributing RFCs and pull-requests. The goal of this collaboration is large-scale performance improvements, focused on bundle sizes, ...
Read more >
Inputs - Serverless Nextjs
Name Type Default Value domain Array null bucketName string null bucketRegion string us‑east‑1
Read more >
The Complete Guide to Next.js Authentication
Next.js Authentication Concepts · Client authentication · Accessing the user session on the client · Protected client routes · Client-side redirects ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found