Writing Node.js in 2025? These New Features & Practices Are Non-Negotiable

If youâre still writing Node.js apps the âold wayâ (CommonJS modules, dotenv, external test libs, etc), itâs time to upgrade. Modern versions of Node.js offer several built-in capabilities that reduce dependencies, simplify workflow, and improve performance. In this blog Iâll walk you through 8 key built-in features you should adopt right now with short code samples, clear guidance and caveats so you can migrate confidently.
1. Embrace the latest import syntax (ESM)
Stop using the old require()/CommonJS style if you can. Node.js fully supports ECMAScript modules (ESM) and itâs time to use them. Node.js+2W3Schools+2
Old (outdated):
const express = require('express');
module.exports = someFunction;
Recommended (ESM):
import express from 'express';
export default someFunction;
Set "type": "module" in your package.json, or use .mjs extensions, and youâre good. Going ESM from day one is cleaner, more aligned with modern JS, and avoids interoperability headaches.
2. Use process.env via run command instead of dotenv (in many cases)
I know many of us used dotenv.config() at the top of our apps. That still works, but recent Node.js updates allow you to pass environment files at runtime without requiring dotenv. Thatâs one less dependency to manage.
Old pattern:
import dotenv from 'dotenv';
dotenv.config();
console.log(process.env.MY_SECRET);
Recommended runtime command:
node --env-file=.env app.js
This way you can skip or minimise dotenv usage (especially in production) and rely more on the runtimeâs built-in env file support. It keeps things simple and reduces third-party reliance.
3. Built-in test runner in Node.js
Remember when you had to install and configure Jest, Mocha or Vite for testing? Thatâs changing. Node.js now ships with a built-in test runner. Node.js+2LogRocket Blog+2
Sample code:
// math.test.mjs
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { add } from './math.js';
test('adds two numbers', () => {
assert.strictEqual(add(2, 3), 5);
});
Then simply run:
node --test
Benefits: zero additional dependency, minimal config, and smoother dev experience. Of course, if you need advanced features, you may still pick Jest/Mocha, but for many use-cases this built-in runner suffices.
4. Native SQLite support (yes, really)
One of the big surprises: Node.js v22.5.0 introduced a built-in experimental module for SQLite: node:sqlite. Better Stack+2LogRocket Blog+2
Note (call-out): Use the special prefix node:packageName when importing built-in modules. This ensures youâre referencing a built-in library, not a third-party with the same name (security + clarity win).
Example usage:
import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync('example.db');
db.run('CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT)');
db.run('INSERT INTO users(name) VALUES (?)', 'Alice');
const row = db.get('SELECT * FROM users WHERE name = ?', 'Alice');
console.log(row);
â ď¸ Keep in mind: still marked experimental, fewer features than popular third-party libs (like concurrency, async API). Use with caution for production. LogRocket Blog
5. âType-skipperâ support for TypeScript files
If youâre doing TypeScript, thereâs good news: recent Node.js versions let you run .ts files directly (for the parts that just use types). Node.js+1
Example:
// app.ts
const greet = (name: string): string => {
return `Hello, ${name}`;
};
console.log(greet('World'));
You can run:
node app.ts
Important call-out: This only supports type stripping (erasable TypeScript syntax). Full TS features (enums, namespaces, fancy transforms) still need compile/transpile. Use this feature vigilantly, understand its limitations, and stay tuned for future updates.
6. Replace nodemon with Nodeâs built-in --watch flag
You probably used nodemon for auto-restarting on file changes. Now, Node.js offers a built-in flag --watch. Make your life simpler.
Example:
node --watch server.js
On changes, Node will auto-reload. Fewer dependencies and tools to maintain.
7. Built-in fetch (no more axios or node-fetch)
Modern Node.js versions include the Fetch API nativelyâjust like in browsers. That means you donât always have to import axios or node-fetch.
Example:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
Saves you package installations, simplifies your stack.
8. Super-fast dev script with node --run dev (yes, no npm needed)
This is one of the cleanest improvements in modern Node.js.
You donât need slow npm run dev anymore because npm adds extra overhead (pre-scripts, post-scripts, lifecycle steps, etc).
Now Node.js gives you a native script runner using:
node --run dev
So you define your scripts in package.json like this:
{
"scripts": {
"dev": "node --watch server.js"
}
}
And instead of:
npm run dev
You can directly run:
node --run dev
This is lightning fast, no npm layer, no extra processing.
Just pure Node executing your script instantly , perfect for local development.
Final Thoughts
If youâre working with Node.js right now (especially v22+), start shifting to these built-in features. They genuinely cut down your dependency list, reduce config headaches, and make your whole dev workflow faster and cleaner. This is the direction Node.js is moving toward, so adopting early gives you an edge.
But remember not everything is 100% production-ready. Features like native SQLite and TypeScript type-skipping are still evolving. Use them smartly, test properly, and make sure your project actually benefits from the switch.
Node.js is changing fast, and these built-in upgrades are going to become the new âdefault wayâ of writing backend apps. So stay updated, experiment, and keep your stack modern.
More improvements are coming , stay tuned.
About the author
Full-Stack Developer | MERN + Next.js | DevOps & Cloud Enthusiast
I specialize in building dynamic web applications using the MERN stack and Next.js. Currently exploring DevOps and cloud technologies to streamline workflows, automate deployments, and optimize cloud infrastructure for scalable, efficient solutions.
Comments
Join the discussionNo comments yet. Be the first to comment.
Backend
A deep dive into backend development where servers, systems, and scalability meet creativity. I simplify complex topics like Kafka, databases, APIs, and microservices into real-world insightsâno fluff, just pure backend engineering. âď¸





