Internal & External JavaScript: Learn with Example

⚡ Smart Summary

Internal and External JavaScript describe the two supported placements for script code inside a web project. This article compares both approaches, shows working examples, explains correct linking with async and defer, and states when each placement delivers better maintainability and performance.

  • 📄 Internal Placement: Code sits between script tags inside the HTML document and loads with the page that owns it.
  • 🗂️ External Placement: Code lives in a separate .js file referenced through the src attribute, so many pages share one source.
  • 🔗 Linking Rule: An external script tag must always be closed, and the src path is resolved relative to the HTML document unless a full path is supplied.
  • ⚙️ Loading Control: The defer attribute runs the file after HTML parsing completes, while async runs it as soon as the download finishes.
  • 🚀 Caching Benefit: External files are cached by the browser once and reused across every page that references them.
  • 🧭 Selection Criterion: Keep short page-specific logic internal, and move shared or lengthy logic into an external file for easier debugging.
  • 🚫 Inline Handlers: Attribute-based handlers such as onclick mix markup with behaviour and should be replaced by addEventListener.

Internal and External JavaScript

What are Internal and External JavaScript?

You can use JavaScript code in two ways.

  1. You can either include the JavaScript code internally within your HTML document itself.
  2. You can keep the JavaScript code in a separate external file and then point to that file from your HTML document.

Both placements execute exactly the same language and produce the same result in the browser. The difference lies in where the source is stored, how the browser downloads it, and how easily the code can be reused and maintained across a website.

What is Internal JavaScript?

Internal JavaScript is code written directly inside a pair of script tags in the HTML file. The browser reads the markup from top to bottom, and when it reaches the script tag it executes the statements immediately, with no extra network request.

We have been using Internal JS so far. Here is a sample –

<html>
<head>
  <title>My First JavaScript code!!!</title>
  <script type="text/javascript">
    // Create a Date Object
    var day = new Date();
    // Use getDay function to obtain todays Day.
    // getDay() method returns the day of the week as a number like 0 for Sunday, 1 for Monday,….., 5
    // This value is stored in today variable
    var today = day.getDay();
    // To get the name of the day as Sunday, Monday or Saturday, we have created an array named weekday and stored the values
    var weekday = new Array(7);
    weekday[0]="Sunday";
    weekday[1]="Monday";
    weekday[2]="Tuesday";
    weekday[3]="Wednesday";
    weekday[4]="Thursday";
    weekday[5]="Friday";
    weekday[6]="Saturday";
    // weekday[today] will return the day of the week as we want
    document.write("Today is " + weekday[today] + ".");
  </script>
</head>
<body>
</body>
</html>

Output:

Today is Wednesday.

The printed day changes with the visitor’s system clock, because getDay returns a number from 0 for Sunday through 6 for Saturday, and that number is used as an index into the weekday array.

What is External JavaScript?

You plan to display the current date and time in all your web pages. Suppose you wrote the code and copied it into all your web pages (say 100). But later, you want to change the format in which the date or time is displayed. In this case, you will have to make changes in all the 100 web pages. This will be a very time consuming and difficult task.

So, save the JavaScript code in a new file with the extension .js. Then, add a line of code in all your web pages to point to your .js file like this:

<script type="text/javascript" src="currentdetails.js"></script>

Note: It is assumed that the .js file and all your web pages are in the same folder. If the external.js file is in a different folder, you need to specify the full path to your file in the src attribute. The closing </script> tag is mandatory even though the element has no content, because a self-closing script tag is not valid HTML and the rest of the page would be swallowed by the unterminated element.

This is the code you place inside currentdetails.js:

var currentDate = new Date();
var day = currentDate.getDate();
var month = currentDate.getMonth() + 1;
var monthName;

var hours = currentDate.getHours();
var mins = currentDate.getMinutes();
var secs = currentDate.getSeconds();
var strToAppend;
if (hours >12 )
{
	hours1 = "0" + (hours - 12);
strToAppend = "PM";
}
else if (hours <12)
{
	hours1 = "0" + hours;
	strToAppend = "AM";
}
else
{
	hours1 = hours;
	strToAppend = "PM";
}

if(mins<10)
mins = "0" + mins;
if (secs<10)
	secs = "0" + secs;

switch (month)
{
	case 1:
		monthName = "January";
		break;
	case 2:
		monthName = "February";
		break;
	case 3:
		monthName = "March";
		break;
	case 4:
		monthName = "April";
		break;
	case 5:
		monthName = "May";
		break;
	case 6:
		monthName = "June";
		break;
	case 7:
		monthName = "July";
		break;
	case 8:
		monthName = "August";
		break;
	case 9:
		monthName = "September";
		break;
	case 10:
		monthName = "October";
		break;
	case 11:
		monthName = "November";
		break;
	case 12:
		monthName = "December";
		break;
}

var year = currentDate.getFullYear();
var myString;
myString = "Today is " + day +  " - " + monthName + " - " + year + ".<br />Current time is " + hours1 + ":" + mins + ":" + secs + " " + strToAppend + ".";
document.write(myString);

This is your currentdetails.js file. Do not worry seeing long lines of code. You will learn to code soon. Make changes to your HTML document like this:

<html>
	<head>
	   <title>My External JavaScript Code!!!</title>
	   <script type="text/javascript" src="currentdetails.js">
	   </script>
	</head>
	<body>
	</body>
</html>

⚠️ Warning: The legacy script above prefixes every hour with a zero, so 11 in the morning is displayed as 011. It also assigns hours1 without declaring it, which creates an implicit global variable and throws an error under strict mode. The corrected version below fixes both defects.

A modern rewrite of the same file is shorter, declares every variable, and pads the values correctly:

// currentdetails.js - corrected modern version
const now = new Date();

const months = ["January", "February", "March", "April", "May", "June",
                "July", "August", "September", "October", "November", "December"];

const hours24 = now.getHours();
const suffix  = hours24 >= 12 ? "PM" : "AM";
const hours12 = String(hours24 % 12 || 12).padStart(2, "0");
const mins    = String(now.getMinutes()).padStart(2, "0");
const secs    = String(now.getSeconds()).padStart(2, "0");

const message = "Today is " + now.getDate() + " - " + months[now.getMonth()] +
                " - " + now.getFullYear() + ". Current time is " +
                hours12 + ":" + mins + ":" + secs + " " + suffix + ".";

document.getElementById("stamp").textContent = message;

Sample Output:

Today is 29 - July - 2026. Current time is 09:05:07 AM.

How to Link an External JavaScript File Correctly

Three details decide whether an external file loads at all: the path written in the src attribute, the position of the script tag in the document, and the loading attribute applied to it.

Paths are resolved relative to the HTML document unless a leading slash or a full address is supplied.

src Value Meaning Resolves To
currentdetails.js Same folder as the HTML page /pages/currentdetails.js
js/currentdetails.js Subfolder of the current folder /pages/js/currentdetails.js
../currentdetails.js One folder above the current one /currentdetails.js
/assets/js/currentdetails.js Absolute path from the site root /assets/js/currentdetails.js

The loading attribute controls when the browser stops parsing HTML to run the file. The table below summarises the three available behaviours.

Attribute Download Execution Moment Order Preserved
None Blocks HTML parsing Immediately after download Yes
defer Parallel with parsing After the document is parsed Yes
async Parallel with parsing As soon as the download ends No
<!-- Recommended for scripts that read the DOM -->
<script src="js/currentdetails.js" defer></script>

<!-- Recommended for independent third party scripts -->
<script src="js/analytics.js" async></script>

<!-- Modern module syntax, deferred by default -->
<script type="module" src="js/app.js"></script>

💡 Tip: The type="text/javascript" attribute is optional in HTML5 and can be omitted. Keep it only when supporting very old browsers, or replace it with type="module" when using import and export statements.

Internal vs External JavaScript: Key Differences

The comparison below sets both placements side by side across the factors that usually decide the choice.

Factor Internal JavaScript External JavaScript
Storage location Inside the HTML file Separate file with .js extension
Reuse across pages Requires copying into every page One file referenced by every page
Browser caching Re-downloaded with each page Cached once and reused
Maintenance effort High when the code is shared Low, one file to edit
Extra HTTP request No Yes, one per file
Debugging Harder in a long HTML file Easier with clear file names and line numbers
Best suited for Short page-specific logic Shared libraries and long scripts

When to Use Internal and External JavaScript Code?

If you have only a few lines of code that is specific to a particular webpage, then it is better to keep your JavaScript code internally within your HTML document.

On the other hand, if your JavaScript code is used in many web pages, then you should consider keeping your code in a separate file. In that case, if you wish to make some changes to your code, you just have to change only one file, which makes code maintenance easy. If your code is too long, then it is also better to keep it in a separate file. This helps in easy debugging.

A practical rule for beginners is a threshold of roughly ten lines. Anything shorter and page-specific can stay internal, while anything longer or shared belongs in an external file.

Inline JavaScript and Why It Should Be Avoided

A third placement exists in older pages, where the code is written directly inside an HTML attribute. Although it still runs, it mixes structure with behaviour and cannot be cached, reused, or covered by a strict content security policy.

<!-- Inline handler: works, but avoid it -->
<button onclick="alert('Clicked')">Click me</button>

<!-- Preferred: behaviour attached from a script -->
<button id="greet">Click me</button>

<script>
  document.getElementById("greet").addEventListener("click", () => {
      alert("Clicked");
  });
</script>

Once you are comfortable placing scripts, continue with JavaScript array methods, study loops in JavaScript, and work through the practical JavaScript code examples. External files also make it far easier to manage browser storage logic such as cookies in JavaScript.

FAQs

Place it just before the closing body tag, or in the head with the defer attribute. Both options let the HTML render first, so elements exist by the time the code runs.

Yes. Add one script tag per file. Without async, the browser executes them in the order they appear, so place files that define shared functions before the files that call them.

The usual causes are a wrong src path, a missing closing script tag, or a file name with different capitalisation. Open the browser network panel and look for a 404 response.

Only on the first visit, when one extra request is made. After that the file is served from the browser cache, which is usually faster than repeating the same code inside every page.

Most assistants return a single HTML file with internal script tags, because that runs without setup. Ask explicitly for a separate .js file when you need production-ready structure.

External files with the async attribute suit third party AI widgets such as chatbots, because they load independently and never block the surrounding page from rendering.

Summarize this post with: