javascript

Inline JavaScript in HTML

Learn how to write JavaScript directly inside your HTML file using the script tag, inline event handlers, and where to place your scripts for best results.

7 min read 10 sections Tutorial
Share

What is Inline JavaScript?

There are two main ways to write inline JavaScript:

Script Tag

Write JS inside a script tag anywhere in your HTML file.

Event Attributes

Write JS directly on an HTML element like onclick to run code on click.

When to Use Inline JS

Inline JS is great for small projects, quick tests, and learning. For real projects, always use external JS files instead.

The Script Tag

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>My Page</title>
5 </head>
6 <body>
7 <h1>Hello World</h1>
8
9 <script>
10 console.log("JavaScript is running!");
11 alert("Welcome to my page!");
12 </script>
13 </body>
14</html>

No Extra Files Needed

With the script tag, you just open one HTML file in your browser and it works. Perfect for learning and testing.

Where to Put the Script Tag

Inside the Head Tag

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <script>
5 // This runs BEFORE the page loads
6 // So document.getElementById won't find anything yet!
7 let btn = document.getElementById("myBtn");
8 console.log(btn); // null — element doesn't exist yet
9 </script>
10 </head>
11 <body>
12 <button id="myBtn">Click Me</button>
13 </body>
14</html>

Script in Head Runs Too Early

When a script runs in the head, the page body has not loaded yet. So you cannot access HTML elements. This is a very common beginner mistake.

At the Bottom of Body Tag

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>My Page</title>
5 </head>
6 <body>
7 <button id="myBtn">Click Me</button>
8
9 <!-- Script goes LAST, before closing body tag -->
10 <script>
11 // Page is fully loaded, so this works perfectly
12 let btn = document.getElementById("myBtn");
13 btn.addEventListener("click", function() {
14 alert("Button clicked!");
15 });
16 </script>
17 </body>
18</html>

Put Scripts at the Bottom

Placing script tags just before the closing body tag means all HTML is already loaded. Your JavaScript can safely find and work with any element on the page.

LocationWhen It RunsCan Access HTML?Recommended?
head tagBefore page loadsNoNo (unless using defer)
End of bodyAfter page loadsYesYes — safest option
head with deferAfter page loadsYesYes — modern approach

The defer and async Attributes

The defer Attribute

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <!-- defer = download script now, run it AFTER page loads -->
5 <script defer>
6 let btn = document.getElementById("myBtn");
7 btn.addEventListener("click", function() {
8 alert("Deferred script works!");
9 });
10 </script>
11 </head>
12 <body>
13 <button id="myBtn">Click Me</button>
14 </body>
15</html>

The async Attribute

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <!-- async = download AND run as soon as possible, don't wait -->
5 <script async>
6 console.log("This runs as soon as it downloads!");
7 // Warning: page might not be fully loaded yet
8 </script>
9 </head>
10 <body>
11 <p>Page content here...</p>
12 </body>
13</html>

async is Unpredictable

With async, the script runs the moment it downloads — even if the page has not finished loading. Avoid async for scripts that need to access HTML elements.

AttributeDownloadsRuns WhenBest For
None (in body)When browser reaches the tagImmediatelyMost inline scripts
deferIn parallel with HTMLAfter HTML is parsedScripts that need the DOM
asyncIn parallel with HTMLAs soon as downloadedIndependent scripts like analytics

Inline Event Handlers

html
1<!-- onclick runs JS when button is clicked -->
2<button onclick="alert('Hello!')">Click Me</button>
3
4<!-- onmouseover runs JS when mouse hovers -->
5<p onmouseover="this.style.color = 'red'">Hover over me!</p>
6
7<!-- onchange runs JS when input value changes -->
8<input type="text" onchange="console.log(this.value)" />
9
10<!-- You can call a function too -->
11<button onclick="sayHello()">Say Hello</button>
12
13<script>
14 function sayHello() {
15 alert("Hello from a function!");
16 }
17</script>

Inline Event Handlers Are Not Recommended

Inline event attributes mix HTML and JavaScript together. This makes your code hard to read and maintain. Use addEventListener in a script tag or external file instead.

Better Alternative to Inline Events

Bad — Inline Event
<button onclick="alert('Hello')">Click Me</button>
VS
Good — addEventListener
<button id="greetBtn">Click Me</button>
<script>
document.getElementById("greetBtn")
.addEventListener("click", function() {
alert("Hello!");
});
</script>

Multiple Script Tags

html
1<!DOCTYPE html>
2<html>
3 <body>
4 <h1>My Page</h1>
5
6 <script>
7 // First script runs first
8 let name = "Alice";
9 console.log("First script: name is " + name);
10 </script>
11
12 <p>Some content in between...</p>
13
14 <script>
15 // Second script runs second
16 // It can use variables from the first script!
17 console.log("Second script: still " + name);
18 name = "Bob";
19 </script>
20
21 <script>
22 // Third script runs third
23 console.log("Third script: now it is " + name);
24 </script>
25 </body>
26</html>

Scripts Share the Same Scope

All script tags on the same page share the same global scope. A variable declared in one script tag is available in all later script tags.

Real Example: Interactive Counter

Here is a full working example of inline JavaScript making a page interactive. It uses a counter with increment and reset buttons.

html
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>Counter</title>
5 <style>
6 body { font-family: sans-serif; text-align: center; padding: 40px; }
7 #count { font-size: 72px; font-weight: bold; color: #333; }
8 button { font-size: 18px; padding: 10px 24px; margin: 8px; cursor: pointer; }
9 </style>
10 </head>
11 <body>
12 <h1>Counter</h1>
13 <div id="count">0</div>
14 <br />
15 <button id="addBtn">+ Add</button>
16 <button id="resetBtn">Reset</button>
17
18 <script>
19 let count = 0;
20 let countDisplay = document.getElementById("count");
21
22 document.getElementById("addBtn").addEventListener("click", function() {
23 count++;
24 countDisplay.textContent = count;
25 });
26
27 document.getElementById("resetBtn").addEventListener("click", function() {
28 count = 0;
29 countDisplay.textContent = count;
30 });
31 </script>
32 </body>
33</html>

Pros and Cons of Inline JavaScript

Inline JavaScript is useful for small projects but has real downsides when projects grow. Here is an honest look at both sides.

ProsCons
No extra files neededHarder to reuse code across pages
Easy to get startedMixes structure (HTML) and logic (JS)
Works in any browserGets messy as projects grow
Great for learningHard to maintain long term
Quick to test ideasNo caching — redownloads every page visit

Use Inline JS for Learning

When you are learning JavaScript, inline scripts are perfect. When you start building real apps, move your code to external .js files.

Quick Quiz

Quick Check

Where is the safest place to put a script tag without using defer?

Quick Check

What does the defer attribute do?

Quick Check

What is wrong with inline event attributes like onclick?

Quick Check

If you declare a variable in one script tag, can you use it in a later script tag on the same page?

Quick Check

Which attribute should you use when a script needs to access HTML elements and is placed in the head?

Key Takeaways

Pro Tips
  • 1Put script tags just before the closing body tag to safely access all HTML elements.
  • 2Use the defer attribute if you must place your script in the head.
  • 3Avoid async unless the script is completely independent of the page content.
  • 4Avoid inline event attributes like onclick — use addEventListener instead.
  • 5All script tags on the same page share global scope — variables from one are visible in another.
  • 6Inline JavaScript is perfect for learning and small projects, but switch to external files for real apps.

Try it in the Javascript Compiler

Run and experiment with Javascript code right in your browser — no setup needed.

Continue Learning