Introduction π
There's a common misconception that Node.js is outdated. In fact, itβs constantly evolving, with recent updates introducing a plethora of features that modernize its functionality. Letβs dive into these exciting new features and see how they can transform your development experience.
TypeScript Support π οΈ
Node.js now has built-in support for TypeScript, a massive win for developers who prefer static typing. Traditionally, running a TypeScript file in Node.js resulted in parsing errors, but with the latest experimental features, you can run .ts
files using the --experimental-strip-types
flag.
node --experimental-strip-types index.ts
This flag removes TypeScript types, allowing the code to run as standard JavaScript.
(node:5600) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:5600) [MODULE_TYPELESS_PACKAGE_JSON] Warning: /NodeJS/amazing-features/index.ts parsed as an ES module because module syntax was detected; to avoid the performance penalty of syntax detection, add "type": "module" to your package.json.
Although the feature is experimental, it works well in most cases. You can further enhance performance by adding "type": "module"
in your package.json
:
{
"name": "amazing-features-of-nodejs",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"typescript": "^5.6.2"
}
}
After adding "type": "module"
, the warning about module syntax will be resolved.
Built-In Test Runner π§ͺ
One of the most exciting new features is the built-in test runner in Node.js. You can now run tests natively without needing external libraries like Jest. The built-in test runner allows you to create test files using describe
and it
functions directly from Node.js.
Hereβs an example of a index.test.js
file for a TypeScript module:
import assert from "node:assert";
import { describe, it } from "node:test";
import { IsAdult } from "./index.ts";
describe("#isAdult", () => {
it("Checks if a user is an adult", () => {
assert(IsAdult(29));
});
});
Make sure to import the TypeScript file with the .ts
extension. Run the test using the following command:
node --experimental-strip-types --test
The output will look like this:
βΆ #isAdult
β Check if user is an adult (5ms)
βΉ tests 1
βΉ suites 1
βΉ pass 1
βΉ duration 449ms
You can also add test coverage with the --experimental-test-coverage
flag:
node --experimental-strip-types --experimental-test-coverage --test
For even more control, you can modify the test output format by using the --test-reporter
flag.
node --experimental-strip-types --experimental-test-coverage --test-reporter tap --test
Watch Flag β³
node --watch --experimental-strip-types --experimental-test-coverage --test-reporter tap --test
The --watch
flag automatically reruns your code whenever files change, eliminating the need for tools like Nodemon. Simply run your tests with the --watch
flag, and Node.js will monitor file changes, re-running tests automatically.
Environment File Support π
Node.js now supports loading environment variables directly from a .env
file using the --env-file
flag, making environment management simpler.
Create a .env
file with your variables:
SECRET_VALUE="your-secret-value"
Access your variables in Node.js like this:
console.log(process.env.SECRET_VALUE); // your-secret-value
Run your app with:
node --experimental-strip-types --env-file=.env index.ts
Promises in Standard Libraries π
Node.js is moving towards a promise-based approach across its standard libraries. For example, the fs.readFile
method now supports promises:
import { readFile } from "fs/promises";
const file = await readFile("./index.ts");
console.log(file); // <Buffer 69...>
This change makes asynchronous code cleaner and more manageable by using await
instead of callbacks.
Top-Level Await β©
Node.js now supports top-level await, allowing you to use the await
keyword outside of async
functions:
const file = await readFile("./index.ts");
console.log(file);
This feature improves code readability and removes the need for wrapping code in async
functions.
Glob File Search π
You can now search for files using glob patterns directly in Node.js:
import { glob } from "fs/promises";
const testFile = await glob("**/*.test.js").next();
console.log(testFile); // { value: 'index.test.js', done: false }
Built-In Debugger π
Node.js includes a built-in debugger that works seamlessly with Chrome DevTools. To start debugging:
node --experimental-strip-types --env-file=.env --inspect-brk index.ts
WebSocket Support π
Node.js has added built-in support for WebSockets, allowing you to connect to WebSocket servers directly:
new WebSocket("wss://your-websocket-url");
SQLite Support ποΈ
Node.js now offers built-in support for SQLite databases. Here's how to create an in-memory SQLite database and interact with it:
import { DatabaseSync } from "node:sqlite";
const database = new DatabaseSync(":memory:");
database.exec(`CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT) STRICT`);
const insert = database.prepare("INSERT INTO data (key, value) VALUES (?, ?)");
insert.run(1, "hello");
insert.run(2, "world!");
const query = database.prepare("SELECT * FROM data ORDER BY key");
console.log(query.all()); // [{ key: 1, value: 'hello' }, { key: 2, value: 'world!' }]
To run the code, use:
node --experimental-strip-types --experimental-sqlite index.ts
Conclusion π
Node.js continues to evolve, incorporating features that enhance the developer experience. From built-in TypeScript support to native testing and database integration, these updates make Node.js a modern, powerful tool for web development. Start using these features today to take your projects to the next level!
Top comments (2)
this is refreshing for the node community. thanks for putting this together.
I am glad you find this helpful π