You have your environment set up and a nomada-tasks folder with its index.html, its CSS and a js/app.js that prints a message. It is time to turn that into your first real program. In this lesson you will learn to display information with console.log, to include JavaScript in a web page in the various ways available (and to understand what defer and async mean), to run a file with Node.js, to document your code with comments and —very importantly— to read an error message without panicking. By the end you will have written a program that prints the summary of a Taller Nómada task.

Contents

  1. console.log: your window into the program
  2. Writing code straight into the console
  3. Including JavaScript in a page: inline versus external file
  4. Where to put the <script>: defer and async
  5. Running JavaScript with Node.js
  6. Your first program: a task summary
  7. Comments in your code
  8. How to read an error message
  9. Common Mistakes and Tips
  10. Exercises
  11. Conclusion

  1. console.log: your window into the program

A program does things internally that you cannot see. console.log is the tool that lets you take a peek at what is going on: you pass it a value and it writes it to the browser console (or to the terminal, if you are using Node.js).

console.log('Hello, Taller Nómada');

Let's take the line apart piece by piece, because every symbol counts:

Part What it is
console An object the environment makes available to you
.log A function belonging to that object
( ... ) The parentheses indicate that you are calling the function
'Hello, Taller Nómada' The argument: the value you pass in
; End of the statement

If you write console.log without parentheses, you are not calling anything: you are only mentioning the function. It is like pointing at a light switch instead of flipping it.

1.1 Printing several values at once

You can pass several arguments separated by commas. console.log prints them all, separated by a space:

console.log('Assignee:', 'Iván', '| Estimated hours:', 12);
// Assignee: Iván | Estimated hours: 12

This is far more convenient than concatenating strings, and it has an extra advantage: each value is shown with its type. In the browser console, the text '12' appears in a different color from the number 12. That visual clue will save you from more than one mistake.

1.2 Other console methods

console has more useful functions, and it is worth knowing them from the start:

Method What it is for How it looks in the console
console.log() General information Plain text
console.info() Highlighted information Similar to log
console.warn() Warnings Yellow background, with an icon
console.error() Errors Red background, with an icon
console.table() Tabular data An actual table
console.warn('Marta\'s task is due in 2 days');
console.error('Could not save Lucía\'s task');

Using them properly keeps the console readable when there are lots of messages. A yellow warning among fifty gray lines stands out; one more console.log does not.

  1. Writing code straight into the console

The console does not just display: it also executes. Open the DevTools (F12), go to Console, type something and press Enter:

8 * 3

It answers 24. It is a JavaScript calculator always within reach, ideal for trying out one-off ideas.

Two practical details:

  • To write several lines without running them, press Shift + Enter instead of Enter.
  • The up/down arrows bring back previous commands, just like in a terminal.

The console is perfect for experimenting, but whatever you type there is lost when you reload the page. Real programs live in files.

  1. Including JavaScript in a page: inline versus external file

There are two ways to put JavaScript into an HTML page.

3.1 Inline script

The code is written inside the tag itself:

<script>
  console.log('This code is written inside the HTML');
</script>

It works, but it is only acceptable for very quick tests.

3.2 External script

The code lives in its own .js file and the HTML links to it with the src attribute:

<script src="js/app.js"></script>
// js/app.js
console.log('This code is in a separate file');

Let's compare them:

Aspect Inline External (src)
Reuse across several pages No Yes
Browser cache Not cached Cached: later loads are faster
Separation of concerns Mixes structure and behavior Everything in its place
Tooling (linters, tests) Cannot analyze it properly Works without issues
Recommended Only for tests Always

Golden rule: always use an external file. That is what we will do in Nómada Tasks.

3.3 Two warnings about <script>

First: if you use src, the content inside the tag is ignored entirely. This prints nothing:

<!-- Wrong! The console.log never runs -->
<script src="js/app.js">
  console.log('This will never run');
</script>

Second: the tag must be closed. <script src="js/app.js" /> is not valid HTML; you have to write </script>.

  1. Where to put the <script>: defer and async

The browser reads the HTML from top to bottom. When it hits a <script> with no extra attributes, it stops building the page, downloads the file, runs it and only then continues. That has a critical consequence.

4.1 The problem with a script in the <head>

<head>
  <!-- Problem! At this point the <h1> does not exist yet -->
  <script src="js/app.js"></script>
</head>
<body>
  <h1>Nómada Tasks</h1>
</body>

If app.js tries to access the <h1>, it will not find it: by the time the script runs, that part of the HTML has not been read yet. This is the number-one cause of the mysterious "I'm getting null" that beginners run into.

4.2 The three solutions

Option A — at the end of the <body> (what the Nómada Tasks skeleton uses):

<body>
  <h1>Nómada Tasks</h1>
  <script src="js/app.js"></script>
</body>

By the time the browser reaches the script, all the HTML above it already exists. Simple, and it always works.

Option B — defer in the <head> (the recommended approach today):

<head>
  <script src="js/app.js" defer></script>
</head>

defer means: download the file in parallel while you keep building the page, and run it once the HTML is complete. You gain download speed without losing the guarantee.

Option C — async (for specific cases):

<head>
  <script src="js/analytics.js" async></script>
</head>

async downloads in parallel and runs as soon as the download finishes, interrupting the construction of the page. It does not guarantee that the HTML is ready, nor does it respect the order between several scripts. It is only suitable for completely independent code, such as an analytics tag.

4.3 Side-by-side comparison

Attribute Does it block the HTML load? When does it run? Does it respect the order between scripts? Recommended use
(none) in the <head> Yes Immediately after downloading Yes Avoid
(none) at the end of the <body> Yes, but it no longer matters When the tag is reached Yes Correct and simple
defer No Once the HTML is complete Yes The best general option
async No As soon as it is downloaded No Independent scripts
flowchart TD
    A["The browser starts<br/>reading the HTML"] --> B{"Does it find<br/>a script?"}
    B -->|"no attributes"| C["Halts the HTML<br/>Downloads and runs it"]
    B -->|"defer"| D["Downloads in parallel<br/>Runs at the end of the HTML"]
    B -->|"async"| E["Downloads in parallel<br/>Runs when the download finishes"]
    C --> F["The HTML continues"]
    D --> F
    E --> F

This is an introductory overview. The relationship between scripts, page loading and performance is studied in depth in Module 9, and accessing the elements of the page in Module 6.

  1. Running JavaScript with Node.js

When you want to try out code without setting up a page, Node.js is the fastest route. Create a test.js file in any folder:

// test.js
console.log('Running JavaScript with Node.js');
console.log('2 + 2 =', 2 + 2);

And run it from the terminal, standing in the folder where it lives:

node test.js

Output:

Running JavaScript with Node.js
2 + 2 = 4

Keep an important difference between the two environments in mind:

Browser Node.js
How it runs By loading the page node file.js
Where you see console.log The Console tab The terminal
Access to the web page Yes No
Access to files on disk No Yes
Good for The real application Trying out standalone logic

The language is the same. A calculation or a comparison behaves identically in both places. What changes is what surrounds it.

  1. Your first program: a task summary

Now for the real thing. Open js/app.js in nomada-tasks and replace its contents with this:

// js/app.js
// Nómada Tasks — First program.
// Prints the summary of a Taller Nómada task to the console.

// 1. We store the task data in variables with descriptive names
const title = 'Redesign the multipurpose room';
const assignee = 'Iván';
const priority = 'high';
const estimatedHours = 12;
const dueDate = '2026-09-30';

// 2. We print a header to visually separate the output
console.log('=== Nómada Tasks · Task summary ===');

// 3. We print each piece of data with its label
console.log('Title:   ', title);
console.log('Assignee:', assignee);
console.log('Priority:', priority);
console.log('Hours:   ', estimatedHours);
console.log('Due date:', dueDate);

// 4. A warning if the priority is high
console.warn('Warning: this task has priority', priority);

Save the file and look at the browser console. You should see:

=== Nómada Tasks · Task summary ===
Title:    Redesign the multipurpose room
Assignee: Iván
Priority: high
Hours:    12
Due date: 2026-09-30
⚠ Warning: this task has priority high

Here is what is happening:

  • const name = value; creates a named container and stores a value inside it. const means that container will not be reassigned. The details come in the next lesson.
  • The names are descriptive. estimatedHours tells you what it holds; h or x does not. Writing clear names is not cosmetics: it is the difference between being able to read your own code a month from now and not.
  • Text goes in quotes, numbers do not. 'high' is text; 12 is a number. If you wrote '12' with quotes, JavaScript would treat it as text and you would not be able to add it up properly. This nuance is explained in Variables and Data Types.
  • The program runs from top to bottom, line by line, in the order it is written.

Try running the same file with Node.js: node js/app.js from the project folder. You will see exactly the same output in the terminal. It is the same language.

  1. Comments in your code

A comment is text that JavaScript ignores completely. It exists to explain the reasons behind things to whoever reads the code later (very likely you).

7.1 Single-line comment: //

// This whole line is a comment
const assignee = 'Lucía'; // It can also go at the end of a line of code

7.2 Multi-line comment: /* */

/*
  Nómada Tasks
  Module 1 · First program
  Author: the Taller Nómada team
*/

7.3 Commenting out to disable code

A very practical use: temporarily disabling a line without deleting it while you hunt for a bug.

console.log('This one does run');
// console.log('This one is disabled');

In VS Code, Ctrl + / comments or uncomments the line (or the selection) instantly.

7.4 What to comment and what not to

Comment Assessment
// Adds 1 to i above i = i + 1 Useless: it repeats what the code already says
// Iván only works half days on Fridays Useful: it explains a business rule that is invisible in the code
// TODO: validate that the date is not in the past Useful: it records outstanding work
// fixed on 3/12, do not touch Bad: it explains nothing; that is Git's job

The practical rule: the code says the "what", the comment says the "why". If you need a comment to explain what a line does, what you probably need is a better name.

  1. How to read an error message

Errors are not punishments: they are information. Learning to read them is one of the skills that will speed you up the most.

Cause one on purpose in app.js:

console.log(taskAssignee);

Something like this will appear in the console:

Uncaught ReferenceError: taskAssignee is not defined
    at app.js:3:13

Let's take the message apart:

Part Meaning
Uncaught The error was not caught, so it stopped execution
ReferenceError The type of error: a name that does not exist was used
taskAssignee is not defined The description: which name is failing
at app.js:3:13 The location: file app.js, line 3, column 13

That last part is gold. Go straight to that line. In the browser console, the app.js:3:13 link is clickable and takes you to the Sources tab with the cursor already in place.

The error types you will see in your first few weeks:

Type What it means Typical cause
SyntaxError The code does not follow the rules of the language A missing quote, parenthesis or brace
ReferenceError A name that does not exist is used A typo in a variable name
TypeError Something impossible is done with a value Calling something as a function when it is not one
RangeError A value is outside the allowed range A negative number where none is accepted

There is an important difference between the first one and the rest: a SyntaxError prevents the entire file from running, because the engine has to understand all the code before it can start. The others happen during execution and stop the program at that point, leaving everything before it already executed.

8.1 Day-one errors

Symptom Likely cause How to confirm it
Absolutely nothing happens The .js file was not loaded Network tab: does it show up with a 404?
"I can't see my messages" The console is not open or a filter is active Open Console and check the log-level selector
Accented characters look odd <meta charset="UTF-8"> is missing Check the <head>
The message appears and disappears The page is reloading (for example, when a form is submitted) Tick Preserve log in the console
Uncaught SyntaxError A quote, parenthesis or brace was left unclosed Go to the line the error points to, and check the previous one too

A methodological tip: when something fails, look at the console before doing anything else. And fix the first error in the list, not the last one: cascading errors are usually a consequence of the first.

Common Mistakes and Tips

Common mistakes

  • Writing console.log without parentheses. It prints nothing; it merely mentions the function.
  • Wrong capitalization. Console.log() gives ReferenceError: Console is not defined. JavaScript is case-sensitive.
  • Mixing quote characters. 'Nómada" is a SyntaxError. Start and end with the same kind of quote.
  • Putting code inside a <script src="...">. It is ignored entirely.
  • Putting the script in the <head> without defer. When the script runs, the HTML does not exist yet.
  • Confusing the console with the editor. What you type in the console is lost on reload; the program lives in the files.
  • Getting scared by a red error. The message tells you the type, the cause and the exact line. It is the best help you are going to get.

Tips

  • Print often while you are learning. A well-placed console.log answers "does the program even get here?" and "what is this worth right now?".
  • Label your messages: console.log('hours:', hours) instead of console.log(hours). With ten messages on screen you will be grateful.
  • Use defer in new projects. It is the correct default behavior.
  • Save and reload frequently. Small changes and frequent checks pinpoint the bug straight away.
  • Keep a test.js handy to experiment with node test.js without touching the project.

Exercises

Exercise 1: A task card in the console

Create a file js/exercise-01.js that prints the card for this Taller Nómada task:

  • Title: Set up the screen-printing workshop
  • Assignee: Marta
  • Priority: medium
  • Estimated hours: 6
  • Due date: 2026-10-15

Requirements:

  1. Use one variable per piece of data, with a descriptive name.
  2. Print a header line with the name of the project.
  3. Print each piece of data with a label.
  4. Finish with a console.info that says: Card generated successfully.
  5. Include a block comment at the top of the file with the name of the exercise.
  6. Run it both ways: linked from the HTML and with node js/exercise-01.js.

Exercise 2: Error diagnosis

For each snippet, state what type of error occurs, what message you will see roughly, and how you would fix it:

// A
console.log('Task for Lucía);
// B
Console.log('Task for Marta');
// C
const assignee = 'Iván';
console.log(assinee);
// D
console.log 'Task for Iván';

Exercise 3: Decide how the script loads

For each situation, say which option you would use (<script> at the end of the <body>, defer or async) and why:

  1. The Nómada Tasks js/app.js needs to read and modify the task list in the HTML.
  2. A visitor-statistics script that does not touch the page and can run whenever.
  3. Two files, js/data.js and js/app.js, where the second depends on the first having run already.

Solutions

Exercise 1

/*
  Nómada Tasks — Module 1, Exercise 1
  A Taller Nómada task card printed to the console.
*/

// Task data
const title = 'Set up the screen-printing workshop';
const assignee = 'Marta';
const priority = 'medium';
const estimatedHours = 6;
const dueDate = '2026-10-15';

// Header
console.log('=== Nómada Tasks · Task card ===');

// Labeled data
console.log('Title:   ', title);
console.log('Assignee:', assignee);
console.log('Priority:', priority);
console.log('Hours:   ', estimatedHours);
console.log('Due date:', dueDate);

// Confirmation
console.info('Card generated successfully.');

Linked from the HTML you see it in the Console tab; with node js/exercise-01.js, in the terminal. The output is identical, because the language is the same in both environments.

Exercise 2

Case Error type Approximate message Fix
A SyntaxError Invalid or unexpected token Close the quote: console.log('Task for Lucía');
B ReferenceError Console is not defined Write console in lowercase
C ReferenceError assinee is not defined Fix the typo: assignee
D SyntaxError Unexpected string Add the parentheses: console.log('Task for Iván');

Notice the pattern: cases A and D are syntax errors (the engine does not understand the code and runs nothing at all from the file); B and C are reference errors (the code is valid, but when it runs it asks for something that does not exist).

Exercise 3

  1. defer, or a script at the end of the <body>. It needs the HTML to be complete before it runs. defer is preferable: it downloads in parallel and runs once the page is ready.
  2. async. It does not depend on the page or on other scripts, and the sooner it runs the better. This is exactly its use case.
  3. defer on both, in that order (data.js before app.js), or both at the end of the <body> in that order. What has to be avoided is async: it does not guarantee execution order, so app.js could run before data.js and fail intermittently in a way that is impossible to reproduce.

Conclusion

You have written and run your first JavaScript program. You know how to use console.log and its variants (warn, error, info, table) to see what is going on inside the program; you can tell an inline script from an external one and you know why you should always use external files; you understand why the position of the <script> matters and exactly what defer and async do; you can run any file with node file.js; you document with comments that explain the why, not the what; and —perhaps most valuable of all— you know how to read an error message: its type, its description and the exact line where it happens.

And in js/app.js you already have a real program that prints the summary of a Taller Nómada task, with its title, assignee, priority, hours and due date.

So far you have been copying syntax without fully knowing its rules. In the next lesson, JavaScript Syntax and Basic Concepts, you will put names to what you have been doing: what exactly a statement is, when the semicolon is needed, how {} blocks work, what names you can give your variables and what strict mode is. It is the lesson that turns "I copy it and it works" into "I understand why it works".

JavaScript Course: From Beginner to Advanced

Module 1: Introduction to JavaScript

Module 2: Control Structures

Module 3: Functions

Module 4: Objects and Arrays

Module 5: Advanced Objects and Functions

Module 6: The Document Object Model (DOM)

Module 7: Browser APIs and Advanced Topics

Module 8: Testing and Debugging

Module 9: Performance and Optimization

Module 10: JavaScript Frameworks and Libraries

Module 11: Final Project

© Copyright 2026. All rights reserved