Digging into explicit resource management

#​663 — November 16, 2023

Read on the Web

JavaScript Weekly

Prettier 3.1 Released — The popular opinionated code formatter has a new release including support for the new control flow syntax in Angular 17 plus a new, experimental formatting option for ternary expressions (as in x ? y : z) explained in more depth in “A curious case of the ternaries.”

Alex Rattray

🤔 With an aim to making code formatting even faster, Prettier’s co-creator has put up a $10k bounty for any Rust project that passes >95% of Prettier’s tests.

Exploring Explicit Resource Management in JS — A practical look at the idea of explicit resource management, an idea both currently at stage 3 in TC39 (and partly supported in TypeScript 5.2) that makes it easier to ‘clean up’ resources once they are no longer used or needed.

Ilia Pozdnyakov

Build Interactive, Live Video Applications with Amazon IVS — Amazon Interactive Video Service (Amazon IVS) allows developers to create dynamic video experiences, such as collaborative real-time livestreams. Check out the new ivs.rocks to find code samples, demos, and other resources. Click here to get started.

Amazon Web Services (AWS) sponsor

On HTML Web Components — “With web components, you might even say React’s component model is being ported to the browser. But it’s being done in a way that works to enhance how the web already works, not replace it”.

Jim Nielsen

A Review of Lightweight JavaScript Frameworks — This overview is targeted at Django (i.e. Python) developers but if you, too, want to avoid larger frameworks like React or Angular, you might appreciate this look at numerous alternatives from Stimulus and htmx to more oblique options like Laravel Livewire.

Michael Yin

🥳 AWS is celebrating a huge release with v6 of the AWS Amplify JavaScript library which includes full support for Next.js App Router and Server Actions.

🌎 Node.js TSC member Yagiz Nizipli is suggesting using Biome for code formatting in Node, since ESLint has deprecated its core formatting rules.

👾 The winners of React Jam, a recent React-based game development contest, have been revealed. An entry I enjoyed was useChess, a set of chess-based puzzles.

▶️ If you’ve wondered what the big deal is about Astro, James Q Quick went on the Software Engineering Daily podcast and explained Astro pretty well.

🎵 Someone’s recorded ▶️ a rap music video about TypeScript..

RELEASES:

Node.js v21.2.0 (Current)

visx 3.5 – D3-based visualization primitives for React.

fx 31.0 – Powerful terminal JSON viewer.

Astro 3.5, Ember 5.4, and Prisma 5.6.

📄 Articles & Tutorials

67 Browser-Based Debugging Tricks — A list of useful, ‘not-obvious’ hacks to get the most out of the browser’s DevTools. Assumes a reasonable existing understanding of said tools.

Alan Norbauer

Exploring V8’s Strings: Implementation and OptimizationsNote: This is very technical and most JavaScript developers do not need to go this deep. That aside, this is a fantastic look under the covers of how the V8 engine handles strings, including the optimizations used that allow it to go toe to toe with languages like C++.

Ilia Pozdnyakov

JavaScript Scratchpad for VS Code — Quokka.js is the #1 tool for exploring/testing JavaScript with edit-continue experience to see realtime execution and runtime values.

Wallaby Team sponsor

▶  An Overview of Angular 17’s New Built-In Control FlowAngular 17 was released last week and a significant enhancement was support for a new syntax in templates that looks and feels more JavaScript-y.

Dmytro Mezhenskyi

Moving Back to React (from Preact) — Preact felt like a logical, lightweight choice to this team at one time, but they’ve switched to React for better compatibility with Next.js, among other things. Their page weight is up slightly, but they feel the tradeoff is worth it.

Ante Barić (Daily․Dev)

My Journey to 3x Faster Builds: Trimming Barrel File Imports“I maintain a small frontend application (4K LOC) which uses Vite as the compiler. The production build, using npm run build, was taking 26 secs on Github Actions. It seemed awfully slow for such a small application. I decided to investigate why.”

Ramana Venkata

Can Bun Eat Node’s ‘Lunch’? — An experiment in migrating a codebase (a restaurant voting app called Lunch) from Node over to Bun and seeing how it fares.

Jeffrey Carl Faden

Feel the Power of More Than 420,000 Teammates and Work #LikeABosch

Bosch sponsor

How to Use NPM Packages Outside of Node — Learn how to run NPM packages in ‘other places’ like serverless platforms, the browser, and beyond.

George MacKerron (Neon)

What I Learned Building an Audio Plugins System for the Web

Ben Wiley

Rust for JavaScript Developers: An Overview of Testing

Joshua Mo

🛠 Code & Tools

gsplat.js: A Gaussian Splatting Library — Gaussian splatting is an increasingly popular graphics rendering techniques where rather than render millions of tiny, textured triangles in a scene, you get a more wild paintball-like splatter fest, where each paintball creates a smooth, colorful blob instead of a rigid shape. This demo is both simple and striking.

Dylan Ebert

Reveal.js 5.0: The HTML Presentation Framework — A way to build presentations using standard Web technologies. The project’s homepage is, itself, such a presentation. v5.0 adds support for ‘scroll mode’ which essentially turns presentations into more typically scrolling Web experiences – demo.

Hakim El Hattab

🖍️ Marker.io: Collect Bug Reports With Annotations & Session Replay — Collect feedback on live websites. Get dev-friendly bug reports with screenshots, URLs, console logs & session replay.

Marker.io sponsor

Datasheet Grid: An Airtable-like React Component — If you’ve got an array of objects and you want a way for users to manipulate them, this is for you. It’s not going to replace a spreadsheet or an extensive data grid framework, but it’s a mature solution featuring smooth animations, virtualized rows/columns, keyboard navigation, and more.

Nicolas Keller

Perfect Freehand: A Library for Creating Better ‘Freehand’ Lines — You can try it out here. Makes your e-signature not look like chicken scratch! Might be useful for drawing apps.

Steve Ruiz

Wild Wild Path v5: Object Property Paths with Wildcards and Regexps — A ‘wild’ way to access properties in objects (which can be deeply nested) by way of string based queries that support wildcards and regexes. The examples help communicate the idea.

ehmicky

@storybook-test: More Streamlined and Powerful Storybook Testing — @storybook/test consolidates the API of @storybook/jest and @storybook/testing-library into a new, single package, powered by Vitest.

Kasper Peulen

Marked 10.0 – Markdown parser and compiler. There’s also marked-terminal 6.1 which lets you render Marked-processed Markdown on the terminal.

HumanizeDuration.js 3.31.0 – Turn milliseconds into textual durations in numerous natural languages.

actions/github-script 7.0 – Script the GitHub API in GitHub Actions.

Plasmo v0.84.0“Like Next.js for browser extensions.”

PDFKit 0.14.0 – PDF generation for Node and browser.

React Joyride 2.7 – Create guided tours in your apps.

Job Listing

Full Stack TypeScript Software Engineer – [Remote Europe]Marker.io is a visual bug-reporting tool for the web. Join our dev team and work remotely (Stack: Node.js, Vue.js & MongoDB).

NOTABLE QUOTABLE

“When you choose a language, you’re choosing more than a set of technical trade-offs – you’re choosing a community.”

___
Joshua Bloch

Playwright now offers a UI mode

#​631 — March 24, 2023

Read on the Web

JavaScript Weekly

Speeding Up the JavaScript Ecosystem: npm Scripts — The latest in what has been a fascinating series on finding ‘low hanging fruit’ when it comes to performance in the JavaScript world. The author explains it best himself:

“‘npm scripts’ are executed by JavaScript developers … all the time. Despite their high usage they are not particularly well optimized and add about 400ms of overhead. In this article we were able to bring that down to ~22ms.”
What Marvin does here is a valuable skill for all developers to pick up, and you can enjoy more by going back to the start.

Marvin Hagemeister

Playwright v1.32 – Now with UI Mode — The popular Web testing and automation framework is taking more steps toward the ground currently served by tools like Cypress by offering a ‘UI mode’ that lets you explore, run and debug tests in a UI environment, complete with watch mode. ▶️ This video provides a good introduction.

Microsoft

A Grid Component with All the Features & Great Performance — Try our powerful JS data grid component which lets you edit, sort, group and filter datasets with fantastic performance. Includes a TreeGrid, API docs and plenty of demos. Seamless integration with React, Angular & Vue apps.

Bryntum sponsor

Why We Added package.json Support to Deno — Deno shares some provenance with Node.js but till recently it hadn’t focused on supporting Node features like npm modules. But with Node and npm compatibility beginning to improve, the team has faced questions about the runtime’s priorities. Ryan Dahl explains more about their thinking here.

Ryan Dahl

???? In other Deno news, Deno 1.32 has been released with… improved package.json support, and more.

How to Start a React Project in 2023 — There are lots of ways, but this well-regarded author explains the pros and cons of a few approaches, and gives you a few options targeting specific use cases you might have.

Robin Wieruch

IN BRIEF:

GitHub had to update its RSA SSH host key today so you may see security related warnings when pushing and cloning. It’s easy to fix, but check the new fingerprint matches – it’s for your own security.

The New Stack caught up with Svelte’s Rich Harris on SvelteKit and what’s coming for Svelte 4.

The React team shared some cutting edge updates on what they’re working on including React Server Components and an optimizing compiler.

If you were experiencing errors on the official Node site last week, here’s the (detailed) post mortem of why. Config errors and inappropriate caching, mostly.

✨ Did you know there’s a market in fake GitHub stars? Some developers analyzed some repos to learn more about it.

???? Congratulations to Lea Verou on her TC39 appointment9. Her efforts to push the Web forward are legendary. Prism is one project you may be aware of.

Make your opinions known on what should be in the next version of Vite.

RELEASES:

Docusaurus 2.4
↳ Easy to maintain documentation site generator.

Puppeteer 19.8
↳ Headless Chrome Node.js API.

Neutralinojs 4.11
↳ Lightweight cross-platform desktop app framework.

Qwik 0.23

???? Articles & Tutorials

Buying a Hard-to-Get Bicycle using Playwright — An unusual use case for JavaScript, Playwright, and GitHub Actions, but Maciek managed to buy his bike.

Maciek Palmowski

Snyk Top 10: JavaScript OSS Vulnerabilities — Dive into the most prevalent critical and high open source vulnerabilities found by Snyk scans of JavaScript apps in 2022.

Snyk sponsor

The ‘End’ of Front-End Development? — A recent narrative doing the rounds suggests that large language models like GPT-4 (or even tools like Copilot X) could soon put some developers out of a job — however, Josh is “optimistic about what these AI advancements mean for the future of software development”.

Josh W. Comeau

In related news, Eric Elliott put ChatGPT through its paces to see if it would make for a good JavaScript tutor. It did well, though with mixed results.

Migrating from ts-node to Bun — A look at adopting performance-oriented Bun when you’re used to using TypeScript with Node.js. John runs us through porting a console app from the ts-node approach over to Bun — “a pretty easy process,” he says.

John Reilly

▶  A Pinia Crash Course for BeginnersPinia is a store / state management solution for Vue that does believe in pineapple on pizza.

Alexander Gekov

A Practical Guide to Getting Started with Astro — An extensive walkthrough of Astro that covers all the topics you’ll need to get you started.

Mojtaba Seyedi

???? Test Website Speed Continuously and Rank Higher In Google — You need a fast website to make users happy and meet Google’s Core Web Vitals metrics. Test and optimize with DebugBear.

DebugBear sponsor

Automatic npm Publishing with GitHub Actions and Granular Tokens

Tim Perry

Make Sure You Do This Before Switching to Signals in Angular

Jordan Powell

Six CSS Snippets Every Developer Should Know

Adam Argyle (Google)

???? Code & Tools

trace.cafe: Easy Webperf Trace Sharing — A quick way to share a performance profile saved from your DevTools, available for up to 90 days with the DevTools perf panel embedded (see example).

paul irish

VueUse: A Collection of Vue Composition Utilities — With over 200 functions targeting both Vue 2 and 3, there’ll be something in this suite of Composition API-based utility functions for you, whether it’s working with state, browser capabilities, animations, Electron, Firebase, and more.

Anthony Fu

Don’t Let Your Issue Tracker Be a Four-Letter Word. Use Shortcut

Shortcut (formerly Clubhouse.io) sponsor

OTPAuth: One Time Password (HOTP/TOTP) Library — When you log in to a site that uses 2FA and you’re asked for some digits from an authentication app, that’s probably a Time-based One-Time Password (or TOTP). This library for Node, Deno, Bun and the browser lets you work with TOTPs and HOTPs from JS.

Héctor Molinero Fernández

Recharts 2.5: Chart Library Built with React and D3 — Easy to deploy with declarative components, native SVG support, and lightweight dependency on D3. Line, bar, scatter, composed, pie, and radar charts are offered. There are lots of examples, complete with code.

recharts

DOCX 8.0: Generate Word .docx Files from JavaScript — The code to lay out documents is verbose but there’s a lot of functionality. Here’s a CodePen example and release notesGitHub repo.

Dolan Miu

SvHighlight: Code Syntax Highlighter for Svelte — Powered by Highlight.js, it includes a blurring feature to focus attention on specific areas of code and you an customize it with Tailwind. Try the interactive examples to see the effect.

SvHighlight

eslint-formatter-pretty 5.0: Pretty ESLint Formatter — Nicer output than the default. Sort results by severity. Get stylized inline code blocks, and more.

Sindre Sorhus

AWS JWT Verify: Verify JWTs Signed by Amazon Cognito — In both Node.js and the browser.

Amazon Web Services

???? Jobs

Software Engineer (Backend) — Join our “kick ass” team. Our software team operates from 17 countries and we’re always looking for more exceptional engineers.

Sticker Mule

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

????‍???? Got a job listing to share? Here’s how.

melonJS 15.0
↳ Mature HTML5 game engine.

Marked 4.3
↳ Markdown parser and compiler. (Demo.)

v8go 0.9
↳ Execute JavaScript from Go(lang).

Million 2.1
↳ Fast Virtual DOM to make React faster.

Partytown 0.7.6
↳ Take third-party scripts off the main thread.

???? Bonus Item

Make Bookmarklets — Create and test bookmarklets directly in the browser. Makes an irritating task slightly easier if you need to do it.

Cullan Luther

Introducing nsuv

Introducing nsuv

nsuv is a C++ wrapper around libuv with the main goal of supporting compile-time type safety when propagating data.

You can find the open source package here: https://github.com/nodesource/nsuv

Here at NodeSource we are focused on fixing issues for the enterprise. This includes adding functionality and features to Node.js that are useful for enterprise-level deployments but would be difficult to upstream. One is the ability to execute commands remotely on Worker threads without the addition of running the inspector, such as capturing CPU profiles or heap snapshots. Another feature necessary to make Node.js more reliable in production is the ability to record and send metrics without being at the mercy of a busy event loop.

To achieve these, we run a separate thread that receives commands and gathers metrics from each Node.js thread. The locks and data queues in the separate thread are managed by libuv. As the codebase grew, usability issues began to come up, such as remembering the correct type of each void pointer and keeping track of the lifetime of the many shared locks and resources. Our solution was to write a wrapper for libuv to alleviate these problems.

We had a lot of existing libuv code and didn’t want to rewrite everything from scratch. So we wrote a template class library that inherits from each libuv handle or request type and uses the curiously recurring template pattern (CRTP) for inheritance. Doing so made it possible to write a wrapper that serves as a drop-in replacement, allowing for incremental improvements while supplementing the wrapper’s API with what was needed.

N|Solid has a zero-failure tolerance, so none of our code can accidentally terminate your process. One way we do this is to try our best not to perform additional allocations. If an allocation is necessary, it always does with a strong exception guarantee, which is then caught and returned as a libuv error code.

We have also enabled compile time warnings when returned error codes aren’t handled. While developing nsuv, we analyzed many existing C++ projects that use libuv and discovered that most of them assume the state of the application and lack sufficient error handling in case something unexpected occurs. This can be especially painful when working with asynchronous code, but we understand that not everyone requires the same level of caution. It can be disabled by defining NSUV_DISABLE_WUR in your flags.

Getting Started

The following code example shows the execution of a simple libuv timer, and the only change was to turn the uv_timer_t to a nsuv::ns_timer instance while still being able to use the original libuv APIs:

static void timer_cb(uv_timer_t* handle) {
Foo* foo = static_cast<Foo*>(handle->data);
delete foo;
uv_close(reinterpret_cast<uv_handle_t*>(handle), nullptr);
}

static void call_timer() {
ns_timer timer;
Foo* foo = new Foo();

timer.data = foo;
uv_timer_init(uv_default_loop(), &timer);
uv_timer_start(&timer, timer_cb, 1000, 0);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

As you can see, there’s no need to cast timer before being passed to libuv’s timer function since ns_timer is a derived class of uv_timer_t and upcasting is implicit. It offers the first step in converting code to be more type-safe and improve overall usability. Improvements can be made incrementally from here. Below we take advantage of the CRTP and use it to downcast the uv_timer_t to the nsuv counterpart after using libuv’s timer API:

static void timer_cb(uv_timer_t* handle) {
// Downcast the libuv handle to its nsuv counterpart.
ns_timer* timer = ns_timer::cast(handle);
// Convenience method to retrieve and cast data.
Foo* foo = timer->get_data<Foo>();

delete foo;
timer->close();
}

While this is a good first step, it still requires we know what the data value should be cast to. The call to get_data() only serves as a convenience method for easier casting.

Passing Data

One of the most painful parts of working with libuv was ensuring we didn’t accidentally cast a void pointer to the wrong type from a specific queue. While this could be verified by hand, having the compiler tell us if we did it wrong would have been more reassuring.

To accomplish this, we wrapped libuv in a way that allows any function that takes a callback to be passed an arbitrary pointer. That pointer is then passed along as an argument in the callback’s parameters. Preventing us from needing to use the uv_handle_t::data property and ensuring the callback always has the correct pointer type.

Below we have fully converted the previous code to use nsuv. As you can see, the pointer that would have been stored in the data parameter can now be passed to the method, making it available as an argument in the callback.

static void call_timer() {
ns_timer timer;
Foo* foo = new Foo();
int r;

r = timer.init(uv_default_loop());
//check r
r = timer.start(+[](ns_timer* handle, Foo* foo) {
delete foo;
handle->close();
}, 1000, 0, foo);
// check r

uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

For the sake of the example, a C++ lambda function was used. Remember that when passing a lambda function, it needs to be converted to a plain old function pointer using the + operator.

Also notice that we are assigning and handling all return values from each call. As mentioned above, the compiler will warn us if we do not check each call’s return codes. For simplicity of future examples, the return value will be assigned but not include a comment that it needs to be checked.

Locks

Because of all the communication between threads, mutexes were heavily used. To make things simpler, we added a couple of APIs for convenience. The first API of note is that init() accepts an optional boolean value. If true is passed in, the mutex is automatically destroyed when the destructor is called. The other was to add an API for scoped locking.

static void try_mutex() {
ns_mutex mutex;
// The optional boolean argument sets if the mutex should be
// automatically destroyed in the destructor.
int r = mutex.init(true);
// Convenience class to create scoped locks. Accepts either a
// pointer or reference.
{
ns_mutex::scoped_lock lock(mutex);
}
}

Having a mutex call destroy() in the destructor was kept false by default to maintain parity with the libuv API and prevent surprises while migrating to nsuv.

Example Usage

At first, we only implemented the libuv APIs that were necessary for us to use internally, but since deciding to open source the library we have begun to add as much of the remaining libuv APIs as possible. But despite not having yet ported the entire libuv API, it’s still possible to take advantage of what has been done. The following is an example from a test that includes the checks to demonstrate how class instances are being passed around.

#include “nsuv-inl.h”

using namespace nsuv;

ns_tcp client;
ns_tcp incoming;
ns_tcp server;
ns_connect<ns_tcp> connect_req;
ns_write<ns_tcp> write_req;

static void alloc_cb(ns_tcp* handle, size_t, uv_buf_t* buf) {
static char slab[1024];
assert(handle == &incoming);

buf->base = slab;
buf->len = sizeof(slab);
}

static void read_cb(ns_tcp* handle, ssize_t, const uv_buf_t*) {
assert(handle == &incoming);

handle->close();
client.close();
server.close();
}

static void write_cb(ns_write<ns_tcp>* req, int) {
assert(req == &write_req);
// Retrieve a reference to the uv_buf_t array as a std::vector.
assert(req->bufs().size() == 2);
}

static void connection_cb(ns_tcp* server, int) {
int r;
r = incoming.init(server->get_loop());
r = server->accept(&incoming);
r = incoming.read_start(alloc_cb, read_cb);
}

static void connect_cb(ns_connect<ns_tcp>* req, int, char* data) {
static char bye_ctr[] = “BYE”;
uv_buf_t buf1 = uv_buf_init(data, strlen(data));
uv_buf_t buf2 = uv_buf_init(bye_ctr, strlen(bye_ctr));
// Write to the handle attached to this request and pass along data
// by constructing a std::vector.
int r = req->handle()->write(&write_req, { buf1, buf2 }, write_cb);
}

static void do_listen() {
static char hello_cstr[] = “HELLO”;
struct sockaddr_in addr_in;
struct sockaddr* addr;
int r;

r = uv_ip4_addr(“127.0.0.1”, 9999, &addr_in);
addr = reinterpret_cast<struct sockaddr*>(&addr_in);

// Server setup.
r = server.init(uv_default_loop());
r = server.bind(addr, 0);
r = server.listen(1, connection_cb);

// Client connection.
r = client.init(uv_default_loop());
r = client.connect(&connect_req, addr, connect_cb, hello_cstr);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

The request types ns_write and ns_connect are also used in the above example. They inherit from uv_write_t and uv_connect_t respectively, and can be upcast and downcast the same way as handles. Each request type API is templated to identify which handle is being used and can return the correct handle type.

While the write() method does accept a uv_buf_t[] array, we’ve also added the ability to pass in a std::vector of buffers for ease of use. Once the request is complete, the list of written buffers can be retrieved via the ns_write::buf() API as a reference to the std::vector that’s stored internally.

Conclusion

One goal when creating nsuv was to reduce cognitive load by mimicking the libuv API naming and structure while adding safety features offered by C++. We’ve made it easy to transition existing projects to nsuv. By open-sourcing nsuv, we hope to give developers more confidence that their code will behave as expected when expected.

There is near zero runtime overhead using nsuv. The template function proxy pattern used can be completely optimized out by modern compilers. Combining that with the ability to enforce type checks at compile time, I won’t be using libuv in C++ without nsuv going forward.

Using nsuv is as simple as including the two header files from the project repository. We are still working on getting complete coverage of the libuv API and hope the community can help us decide what to work on next. We are also working on porting all applicable tests from libuv to nsuv, which can serve as usage examples. We hope that you’ll find nsuv as useful as we have.

NodeSource has delivered Node.js fresh to your Linux system via your package manager within hours, minutes, days, or weeks. For NodeSource, sustaining the community is essential because we want to support more people using Linux to have Node.js in production.

Also, we are looking for more community involvement in the project. Help will be appreciated! So if you have ideas or solutions or want to help us continue supporting open source, you can contribute to this GitHub Repo.

Continue the conversation with NodeSource here:
Twitter
LinkedIn
Github
As always, the best place to contact us is via our website or [email protected]

Ready for more?

If you are looking for NodeSource’s Enterprise-grade Node.js platform, N|Solid, please visit https://downloads.nodesource.com/. For detailed information on installing and using N|Solid, please refer to the N|Solid User Guide.

N|Solid v4.8.4 is now available

IMPORTANT: This release of N|Solid v4.8.4 contains a Node.js security release!

NodeSource is excited to announce N|Solid v4.8.4 which contains the following changes:

Node.js v14.21.1 (LTS): Includes a Node.js security release captured in Node.js v14.21.1 (LTS).
Node.js v16.18.1 (LTS): Includes a Node.js security release captured in – Node.js v16.18.1 (LTS).
Node.js v18.12.1 (LTS): Includes a Node.js security release captured in Node.js v18.12.1 (LTS).

For detailed information on installing and using N|Solid, please refer to the N|Solid User Guide..

Changes

NodeSource is excited to announce N|Solid v4.8.4 which contains the following changes:

This release includes patches for these vulnerabilities:

CVE-2022-3602: X.509 Email Address 4-byte Buffer Overflow (High)
CVE-2022-3786: X.509 Email Address Variable Length Buffer Overflow (High)
CVE-2022-43548: DNS rebinding in –inspect via invalid octal IP address (Medium)

There are three available LTS Node.js versions for you to use with N|Solid, Node.js 16 Gallium, Node.js 14 Fermium and Node.js 18 Hydrogen.

N|Solid v4.8.4 Fermium ships with Node.js v14.21.1.

N|Solid v4.8.4 Gallium ships with Node.js v16.18.1.

N|Solid v4.8.4 Hydrogen ships with Node.js v18.12.1.

The Node.js 14 Fermium LTS release line will continue to be supported until April 30, 2023.

The Node.js 16 Gallium LTS release line will continue to be supported until September 11, 2023.

The Node.js 18 Hydrogen LTS release line will continue to be supported until April 30, 2025.

Supported Operating Systems for N|Solid Runtime and N|Solid Console

Please note that The N|Solid Runtime is supported on the following operating systems:

Windows:

Windows 10
Microsoft Windows Server 1909 Core
Microsoft Windows Server 2012
Microsoft Windows Server 2008

macOS:
macOS 10.11 and newer

RPM based 64-bit Linux distributions (x86_64):

Amazon Linux AMI release 2015.09 and newer
RHEL7 / CentOS 7 and newer
Fedora 32 and newer

DEB based 64-bit Linux distributions (x86_64, arm64 and armhf):

Ubuntu 16.04 and newer
Debian 9 (stretch) and newer

Alpine
Alpine 3.3 and newer

Download the latest version of N|Solid

You can download the latest version of N|Solid via http://accounts.nodesource.com or visit https://downloads.nodesource.com/directly.

New to N|Solid?

If you’ve never tried N|Solid, this is a great time to do so. N|Solid is a fully compatible Node.js runtime that has been enhanced to address the needs of the Enterprise. N|Solid provides meaningful insights into the runtime process and the underlying systems. Click here to start!

As always, we’re happy to hear your thoughts – feel free to get in touch with our team or reach out to us on Twitter at @nodesource.