Adding JavaScript to a Page
JavaScript reaches a web page through the <script> element. You can write code directly inside it or, more commonly, point it at a separate .js file. Where you put the tag, and which attributes you give it, decides when the code runs.
Inline scripts
Code can go straight between <script> tags:
<!DOCTYPE html> <html> <body> <h1 id="title">Welcome</h1> <script> document.querySelector("#title").textContent = "Welcome back!"; </script> </body> </html>
This is handy for tiny snippets, but it mixes behaviour into your HTML and can't be cached or reused across pages.
External script files
For anything real, put the code in its own file and link to it with src:
<script src="app.js"></script>
document.querySelector("#title").textContent = "Welcome back!";
External files keep HTML and JavaScript separate, can be shared between pages, and are cached by the browser so returning visitors don't download them again. The path in src works like any other link: relative (js/app.js), root-relative (/js/app.js) or a full URL.
<script> with a src attribute ignores any code written between its tags. Use two separate tags if you need both.When does the script run?
By default, the browser reads HTML from top to bottom. When it reaches a <script>, it stops building the page, downloads and runs the script, and only then continues. That causes two problems for scripts in the <head>:
- The page appears more slowly, because rendering is blocked.
- The script can't find elements that come later in the HTML — they don't exist yet.
There are three common solutions:
| Approach | How | Runs |
|---|---|---|
Script at the end of <body> | <script src="app.js"></script> just before </body> | After the HTML above it is built |
defer | <script src="app.js" defer> in the <head> | After the whole page is parsed, in order |
type="module" | <script type="module" src="app.js"> | Like defer, and enables import/export |
The modern recommendation is defer (or type="module") in the <head>: the browser downloads the file while it keeps building the page, then runs it once the HTML is ready.
<head> <meta charset="UTF-8"> <title>My page</title> <script src="app.js" defer></script> </head>
async scripts
async also downloads without blocking, but runs the script the moment it arrives — possibly before the page is finished, and in no particular order relative to other scripts. It suits independent scripts such as analytics, but not code that touches the page or depends on another script.
Waiting for the page in code
If you can't control the script tag, you can wait for the page inside your code with the DOMContentLoaded event:
document.addEventListener("DOMContentLoaded", () => { document.querySelector("#title").textContent = "Ready!"; });
Running JavaScript outside a page
You don't always need an HTML file. Two quick alternatives:
- The browser console — open developer tools (F12), choose the Console tab and type code directly. Great for experiments.
- Node.js — install it from nodejs.org, save code in
hello.jsand runnode hello.jsin a terminal.
node hello.js
The examples on this site that don't touch the page run the same way in either environment.