COMPUTER PROGRAMMING 1 (JAVASCRIPT) • FUNCTIONS, SCOPE & ORGANIZATION

Organizing into Modules — I can organize a small project into multiple files using import/export in supported tasks.

Learn to split your JavaScript code into reusable, maintainable modules connected by import and export statements.

Historical Context & Motivation

In the early days of the web, JavaScript was used for tiny scripts — a form validation here, an animated button there. Developers would dump all their code into a single <script> tag, and that was fine when files were only fifty lines long. But as websites became full-blown applications with thousands of lines of logic, that single-file approach became a nightmare. Imagine writing an entire essay in one enormous paragraph with no headings, no chapters, and no sections — that's what early JavaScript projects felt like.

The core problem was code organization. Without a way to split code across files and share specific pieces between them, developers faced naming collisions (two variables with the same name clobbering each other), tangled dependencies, and bugs that were incredibly hard to track down. The JavaScript community spent years inventing solutions, eventually arriving at the ES Modules system we use today.

1995
JavaScript Is Born
Brendan Eich creates JavaScript at Netscape in just ten days. All code lives inside <script> tags in HTML files with no module system at all.
2009
CommonJS & Node.js
Node.js launches using the CommonJS module pattern with require() and module.exports, proving that modular JavaScript is practical.
2015
ES6 Modules Standardized
ECMAScript 2015 (ES6) officially adds import and export keywords to the language specification, giving JavaScript a native module system.
2018–Now
Broad Browser & Runtime Support
All major browsers and modern runtimes support ES Modules natively. Build tools like Vite and bundlers like Webpack make modules the default approach for every project.

The central question this lesson addresses is straightforward: How do you break a growing JavaScript project into separate files, and how do those files share code with each other? The answer lies in understanding the export and import keywords.

Core Principles of Modules

A module is simply a JavaScript file that explicitly declares what it shares with the outside world and what it keeps private. Think of each module as a room in a house: the room has its own furniture and decorations (private variables and helper functions), but it has a door that lets specific items pass through to other rooms. The export keyword is that door going out, and import is how another room reaches through the door to grab what it needs.

1

Encapsulation

Each module has its own scope. Variables and functions defined inside a module are private by default — other files cannot see them unless you explicitly export them.
2

Named Exports

You can export multiple values from a module by placing the export keyword before each declaration, or by listing them in an export statement at the bottom. The importing file picks them by name using curly braces.
3

Default Export

Each module may have one export default. This is the 'main thing' the module provides. The importing file can give it any name it likes — no curly braces needed.
4

Dependency Graph

When module A imports from module B, a dependency is created. The collection of all import relationships forms a tree-like graph that the runtime or bundler follows to load code in the correct order.
✦ KEY TAKEAWAY
Think of modules like a team project at school. Each person works on their own section of the presentation (encapsulation), and they share their finished slides with the group through a shared folder (export). When someone needs to reference another person's slide, they pull it from the folder (import). Nobody accidentally overwrites anyone else's work because each person's files stay separate.

Visual Explanation — How Files Connect

The diagram below shows a small project with three files. The math.js module exports two functions. The greet.js module exports one default function. Finally, app.js imports from both modules and uses them together. Notice how each module keeps its internal helpers private.

Three-file module architecture. Cyan arrows show named imports from math.js; the amber arrow shows the default import from greet.js. Private helpers like validate and PREFIX stay hidden inside their modules.

The key insight from this diagram is that each file controls exactly what leaves its boundary. The validate function in math.js is a private helper — it does work internally but is never exported, so app.js cannot access it. This is encapsulation in action, and it protects your code from accidental interference.

How Import and Export Actually Work

Let's look at the exact syntax for both types of exports and imports. Understanding these patterns is essential because mixing them up is one of the most common beginner mistakes.

Named Exports

A named export attaches a specific name to the value you're sharing. You can export inline — right where the function or variable is declared — or you can gather all exports at the bottom of the file. Here is the inline approach:

INLINE NAMED EXPORT
export function add(a, b) { return a + b; }
The export keyword goes directly before the declaration. The function is both created and exported in one statement.

And here is the gathered-at-the-bottom approach, which some developers prefer because it creates a clear manifest of everything a module shares:

GROUPED NAMED EXPORT
export { add, multiply };
The curly braces list every name to export. The functions add and multiply must already be declared somewhere above this line.

Default Exports

A default export signals that the module has one primary value to share. A module can have only one default export, though it can also have additional named exports alongside it.

DEFAULT EXPORT
export default function greet(name) { return `Hello, ${name}!`; }
The default keyword means this function is the module's 'main attraction.' When importing, you don't need curly braces and you can choose any name.

Import Syntax

IMPORTING NAMED EXPORTS
import { add, multiply } from './math.js';
Curly braces are required, and the names inside must match exactly what was exported. The path './math.js' is a relative file path.
IMPORTING A DEFAULT EXPORT
import greet from './greet.js';
No curly braces. The name greet could be anything you like — e.g., import sayHello from './greet.js' would work just as well.
⚠️ Common Mistake
Forgetting the curly braces when importing named exports — or adding them when importing a default — is the number-one syntax error with modules. Remember: named → braces, default → no braces.

Organizing a Project's File Structure

Knowing the syntax is half the battle; the other half is deciding how to split your code into files in the first place. A good rule of thumb is one responsibility per file. If a file handles math utilities, it shouldn't also handle greeting messages. Keeping each file focused makes your code easier to read, test, and reuse.

A clean folder structure for a small JavaScript project. Each .js file has a single responsibility. The HTML file loads only app.js as a module; the browser follows the import chain to load the rest.

Notice the type="module" attribute on the script tag in index.html. This is what tells the browser to treat your JavaScript as an ES Module rather than a traditional script. Without it, import and export will throw a syntax error. When the browser loads app.js as a module, it reads the import statements at the top, fetches those files, reads their imports, and so on until every dependency is resolved.

💡 Tip: Live Server
ES Modules require a web server — you can't just double-click index.html and open it as a local file. Use the "Live Server" extension in VS Code, or run npx serve . in your terminal.

Worked Example — Building a Mini Calculator

Let's walk through creating a tiny project from scratch. We'll build a calculator that adds and multiplies, with a greeting message, spread across three files.

Mini Calculator with Modules
1
Step 1 — Create math.js with named exportsCreate a file called math.js. Inside, define and export two functions: export function add(a, b) { return a + b; } export function multiply(a, b) { return a * b; }
Two named exports: add and multiply
2
Step 2 — Create greet.js with a default exportCreate greet.js with a single default export: export default function greet(name) { return `Welcome, ${name}! Ready to calculate?`; }
One default export: greet
3
Step 3 — Create app.js as the entry pointCreate app.js and import from both modules: import { add, multiply } from './math.js'; import greet from './greet.js'; console.log(greet('Alex')); console.log('3 + 5 =', add(3, 5)); console.log('4 × 7 =', multiply(4, 7));
Named imports use { }; the default import has no braces.
4
Step 4 — Link in HTML with type="module"In index.html, add the script tag: <script type="module" src="./app.js"></script>
The type="module" attribute is essential for browser-based ES Modules.
5
Step 5 — Run and verify in the consoleOpen the page in a browser via a local server and check the developer console. You should see: Welcome, Alex! Ready to calculate? 3 + 5 = 8 4 × 7 = 28
All three outputs appear — the modules are properly connected.

Named vs. Default Exports — When to Use Each

One of the most frequent questions beginners ask is: "Should I use a named export or a default export?" Both are valid, and many real projects use a mix of both. The table below compares them side by side to help you decide.

Comparison of named and default exports in ES Modules
FeatureNamed ExportDefault Export
How many per file?Unlimited — export as many as you likeExactly one per file
Import syntaximport { name } from '...'import anyName from '...'
Renaming on importUse as keyword: import { add as sum }Automatic — just pick any name
Best for…Utility libraries with many functions (e.g., math helpers)Files with one main purpose (e.g., a component or class)
Auto-import supportEditors auto-complete the exact nameEditors may not auto-suggest the correct name
🎯 PRACTICAL GUIDELINE
When in doubt, prefer named exports. They make it obvious what's being imported and give you better autocomplete in code editors. Use a default export when a file has one clear 'star player' — like a single class or a single component — and everything else in that file exists only to support it.

Connection to Advanced Concepts

The import/export system you're learning now is the foundation for virtually every advanced JavaScript tool. As you progress, you'll encounter bundlers (like Webpack and Vite) that combine your many modules into optimized files for production, frameworks (like React and Vue) that rely on modules for component architecture, and package managers (like npm) that let you import code written by other developers from a global registry.

How today's skills connect to advanced JavaScript development
What You Know NowWhere It Leads
import { x } from './file.js'import React from 'react' — importing from installed packages
Splitting code into 3–5 filesReal apps have hundreds of modules, organized into folders by feature
Static import at the top of a fileDynamic import() that loads modules on demand for performance
Using type="module" in HTMLBundlers handle this automatically; you just write import/export and they do the rest

Don't worry about mastering all of these tools right now. The important takeaway is that the import/export pattern is universal in modern JavaScript. Whether you're building a simple calculator or a full web application, you'll always be organizing your code into modules. Getting comfortable with the syntax now will pay dividends in every future project.

Practice Problems

PROBLEM 1 — CONCEPTUAL
What is the main difference between a named export and a default export? Why does the import syntax differ between the two?
PROBLEM 2 — BASIC CALCULATION
Given the following utils.js file, write the correct import statement in app.js to use both functions: // utils.js export function double(n) { return n * 2; } export function triple(n) { return n * 3; }
PROBLEM 3 — INTERMEDIATE
A student writes the following code and gets an error. Identify the bug and fix it. // logger.js export default function log(msg) { console.log(`[LOG]: ${msg}`); } // app.js import { log } from './logger.js'; log('Starting app');
PROBLEM 4 — APPLIED
You're building a simple quiz app. You need a questions.js file that exports an array of question objects and a score.js file that exports a function calculateScore which takes an array of answers and returns a number. Write the export statements for each file and the import statements you'd put in app.js.
PROBLEM 5 — CRITICAL THINKING
A classmate argues that modules are unnecessary for small projects — they'd rather keep everything in one file to avoid dealing with import paths. Write a response explaining at least three concrete benefits of modules, even for a project that's only 200 lines of code.

Lesson Summary

JavaScript modules let you organize a project into multiple files, each with its own scope. You share values between files using export (to send values out) and import (to pull values in). Named exports allow multiple values per file and require curly braces on import, while a default export represents a file's main value and is imported without braces.

To use modules in the browser, your <script> tag must include type="module". A well-organized project follows the principle of one responsibility per file, keeping math helpers separate from greeting logic and DOM manipulation. This pattern of modular organization is the foundation for every modern JavaScript framework, bundler, and large-scale application you'll encounter in the future.

Varsity Tutors • Computer Programming 1 (JavaScript) • Organizing into Modules