This episode covers splitting code into modules: named exports and default exports, how to import in various forms, and running ES modules in Node.js with the right package.json. You also understand why modules matter for growing projects.

Imagine writing an entire application in a single file with thousands of lines. Soon you won't know which function is called from where, and changing one part risks breaking another. Modules are the solution: splitting code into small files, each responsible for one part, then sharing code between them via import and export.
Episode 10 covers ES modules — JavaScript's official module system since ES6. You'll learn named exports and default exports, the various forms of the import statement, and how to run modules correctly in Node.js. Modules also prepare you for episodes 20 and 21 about tooling and bundlers.
One concept makes it all make sense: export determines what leaves a file, and import determines what enters another file.
Without modules, all code shares one global namespace. The risk is real: two files could accidentally define functions with the same name, and the later one overwrites the earlier one. Errors like this are very hard to track because no error appears.
Modules solve this with two mechanisms:
As a result, code is easier to search, test, and reuse. One focused module is far easier to read than one file trying to do everything.
Named exports export many values from one file with clear names. Each value is marked with the export keyword:
export const PI = 3.14159;
export function lingkaran(jariJari) {
return 2 * PI * jariJari;
}
export function luasLingkaran(jariJari) {
return PI * jariJari * jariJari;
}The matematika.js file above exports the PI constant and two functions. export const PI = 3.14159 makes the value available to other files. With named exports, the name in the destination file must match the name in the source file exactly.
To use the exported values, use import with curly braces:
import { PI, luasLingkaran } from "./matematika.js";
console.log(PI);
console.log(luasLingkaran(7));import { PI, luasLingkaran } from "./matematika.js" takes only the values you need. Notice the path starts with ./ and ends with .js — this rule is mandatory in Node.js. The advantage of named exports: the IDE can find all users of a function, and only imported code is loaded.
If a name conflicts in the destination file, use an alias with the as keyword:
import { luasLingkaran as hitungLuas } from "./matematika.js";
console.log(hitungLuas(7));import { luasLingkaran as hitungLuas } gives a new local name without changing the original name in the source file. Aliases are also used to rename for clarity in the destination file's context.
A default export is used for one main value per file. The default value doesn't have to have a name in the source file:
export default function sapa(nama) {
return `Halo, ${nama}!`;
}export default function sapa(nama) exports this function as the module's default value. A module may only have one default export. This pattern fits when a file represents one component or one main function.
Default imports don't use curly braces, and the local name is free — it doesn't have to follow the original name:
import sapaDariFile from "./sapa.js";
console.log(sapaDariFile("Arman"));import sapaDariFile from "./sapa.js" gives a local name that can be anything. The rule of thumb: curly braces for named exports, no curly braces for default exports. Both can also be combined in a single import statement.
Node.js needs to know whether a file uses ES modules or CommonJS. The simplest way: add "type": "module" to package.json:
{
"name": "belajar-modul",
"type": "module",
"main": "main.js"
}With "type": "module", Node treats all .js files as ES modules. Without it, Node assumes CommonJS and import will error with SyntaxError: Cannot use import statement outside a module.
After package.json is set up, run the main file as usual:
node main.jsnode main.js executes main.js, which imports from matematika.js and sapa.js. Node handles module resolution automatically, including nested imports: if main.js imports matematika.js, and matematika.js imports another module, everything gets loaded too.
You can also consolidate exports through a single barrel file to simplify imports in many places:
export { lingkaran, luasLingkaran, PI } from "./matematika.js";
export { default as sapa } from "./sapa.js";export { lingkaran } from "./matematika.js" forwards another file's exports without redefining them. Other files just import from one place: import { sapa, luasLingkaran } from "./indeks.js".
Warning
The two most common import mistakes: forgetting the .js extension in local module paths, and forgetting "type": "module" in package.json. Both surface confusing errors even though the cause is simple. Check these two things first before debugging further.
Episode 10 enabled you to split code into modules: named exports for many values, default exports for one main value, various import forms, and running ES modules in Node.js with "type": "module". You also learned the barrel pattern for consolidating exports.
Key takeaways:
"type": "module" so Node processes ES modules../ and end with .js.In the next episode 11 we'll cover destructuring and structured assignment — extracting values from arrays and objects directly into variables with one tidy statement. This feature makes your code far more concise and clearer to read.