Logto's Next.js SDK is now supporting Edge Runtime. In this article, we're going to share our adventure, looking at the hurdles we faced, how we overcame them, and the cool stuff we learned along the way.
SijieDeveloper
Stop wasting weeks on user auth
Launch secure apps faster with Logto. Integrate user auth in minutes, and focus on your core product.
Edge Runtime has become a buzzword in the technology landscape, driving dynamic, low-latency functions in platforms from AWS Lambda@Edge and Cloudflare Workers to Vercel Edge. Emphasizing its importance, Vercel recently changed "experimental-edge" to "edge", signaling official support in their popular Next.js framework.
With our Next.js SDK gaining serious traction, we at Logto thought, "Why not add Edge Runtime support?" So, we rolled up our sleeves and jumped right in. In this article, we're going to share our adventure, looking at the hurdles we faced, how we overcame them, and the cool stuff we learned along the way.
Transitioning modules and dependencies for Edge Runtime support#
Working with Edge Runtime poses some unique challenges, primarily because it doesn't support all modules and dependencies commonly used in Node.js. We ran into this issue with the crypto, lodash, and iron-session modules, necessitating some innovative workarounds.
In a Node.js environment, the crypto module serves as a wrapper for OpenSSL cryptographic functions. Unfortunately, Edge Runtime doesn't support it. But don't fret - most Edge Runtimes come to the rescue with support for the Web Crypto API. Despite some minor differences, it's a solid stand-in for the crypto module. For instance, to generate random bytes:
Lodash is a favorite among many developers for its utility, but Edge Runtime isn't a fan. Our workaround? We swapped out Lodash functions with native JavaScript methods, keeping our code both efficient and readable.
While replacing most Lodash functions wasn't a Herculean task, it did require some finesse. Let's take a peek at how we recreated the utility of "once" in our own way:
The iron-session module's latest version is Edge Runtime-friendly, so all we had to do was update our version. Simple as that!
Navigating the Intricacies of "Response" in Edge Runtime#
Another challenge that we faced when adapting our SDK for Edge Runtime was handling the differences in the "Response" object. Here's how we overcame these differences:
Unlike in Node.js, a request in Edge Runtime doesn't come with a comming response. This means that we have to create it by calling new Response(), here is an example of returning data:
In the Edge Runtime, the Response.body is a read-only affair. This means that we couldn't initialize a response before the data was prepared. As a result, our trusty "withIronSessionApiRoute" (along with other middleware) had to be benched.
To understand what we replaced, let's first unpack what withIronSessionApiRoute actually does:
It takes a peek at the cookie, constructs a session object, and ties it to res.
It automatically appends the "set-cookie" header to res if there's a change in the session.
So, how did we emulate this functionality in our new Edge Runtime setting?
Read: We utilized the existing getIronSession function. By giving it an empty and fake response, retrieves the session as needed. This replaced the "get" method from req.session.
Writing: We prepared a response with data upfront, then used getIronSession on this response instance to obtain the session object. Once we had this object in our hands, we could modify the session as required.
We thought about creating a separate package for Edge, but quickly realized it was unnecessary. Most of our code was shared between the two runtimes, with only a handful of lines needing tweaks. Plus, using the SDK remains pretty much the same across both runtimes, so maintaining a unified package made the most sense.
Instead of duplicating efforts, we decided to expand the existing package. We added an "edge" folder right in the package's root, cozying up next to the old "src" folder. Then, we updated the package.json file, adding a new path to the "exports". This way, both Edge and Node.js runtimes could live harmoniously within the same package, with minimal fuss.
By sharing our journey of embrace Edge Runtime, we hope to inspire and guide others exploring similar paths. Stay tuned for more updates with our Next.js SDK.